mirror of
https://github.com/konvajs/konva.git
synced 2025-06-28 05:36:38 +08:00
performance updates
This commit is contained in:
parent
2dbde0fd6f
commit
dd84716715
@ -6,6 +6,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
## Unreleased
|
||||
|
||||
* Add `onUpdate` callbacks to `Konva.Tween` configuration and `node.to()` method.
|
||||
* Up to 6x faster initializations of objects, like `const shape = new Konva.Shape()`.
|
||||
|
||||
## 7.0.3 - 2020-07-09
|
||||
|
||||
|
118
konva.js
118
konva.js
@ -8,7 +8,7 @@
|
||||
* Konva JavaScript Framework v7.0.3
|
||||
* http://konvajs.org/
|
||||
* Licensed under the MIT
|
||||
* Date: Thu Jul 09 2020
|
||||
* Date: Thu Jul 30 2020
|
||||
*
|
||||
* Original work Copyright (C) 2011 - 2013 by Eric Rowell (KineticJS)
|
||||
* Modified work Copyright (C) 2014 - present by Anton Lavrenov (Konva)
|
||||
@ -2641,7 +2641,6 @@
|
||||
*/
|
||||
var Node = /** @class */ (function () {
|
||||
function Node(config) {
|
||||
var _this = this;
|
||||
this._id = idCounter++;
|
||||
this.eventListeners = {};
|
||||
this.attrs = {};
|
||||
@ -2656,25 +2655,12 @@
|
||||
this._isUnderCache = false;
|
||||
this.children = emptyChildren;
|
||||
this._dragEventId = null;
|
||||
this._shouldFireChangeEvents = false;
|
||||
// on initial set attrs wi don't need to fire change events
|
||||
// because nobody is listening to them yet
|
||||
this.setAttrs(config);
|
||||
// event bindings for cache handling
|
||||
this.on(TRANSFORM_CHANGE_STR, function () {
|
||||
if (_this._batchingTransformChange) {
|
||||
_this._needClearTransformCache = true;
|
||||
return;
|
||||
}
|
||||
_this._clearCache(TRANSFORM);
|
||||
_this._clearSelfAndDescendantCache(ABSOLUTE_TRANSFORM);
|
||||
});
|
||||
this.on('visibleChange.konva', function () {
|
||||
_this._clearSelfAndDescendantCache(VISIBLE);
|
||||
});
|
||||
this.on('listeningChange.konva', function () {
|
||||
_this._clearSelfAndDescendantCache(LISTENING);
|
||||
});
|
||||
this.on('opacityChange.konva', function () {
|
||||
_this._clearSelfAndDescendantCache(ABSOLUTE_OPACITY);
|
||||
});
|
||||
this._shouldFireChangeEvents = true;
|
||||
// all change event listeners are attached to the prototype
|
||||
}
|
||||
Node.prototype.hasChildren = function () {
|
||||
return false;
|
||||
@ -4425,7 +4411,7 @@
|
||||
}
|
||||
return this;
|
||||
};
|
||||
Node.prototype._setAttr = function (key, val) {
|
||||
Node.prototype._setAttr = function (key, val, skipFire) {
|
||||
var oldVal = this.attrs[key];
|
||||
if (oldVal === val && !Util.isObject(val)) {
|
||||
return;
|
||||
@ -4436,7 +4422,9 @@
|
||||
else {
|
||||
this.attrs[key] = val;
|
||||
}
|
||||
this._fireChangeEvent(key, oldVal, val);
|
||||
if (this._shouldFireChangeEvents) {
|
||||
this._fireChangeEvent(key, oldVal, val);
|
||||
}
|
||||
};
|
||||
Node.prototype._setComponentAttr = function (key, component, val) {
|
||||
var oldVal;
|
||||
@ -4480,9 +4468,29 @@
|
||||
}
|
||||
}
|
||||
};
|
||||
Node.prototype._getListeners = function (eventType) {
|
||||
var totalEvents = [];
|
||||
var obj;
|
||||
while (true) {
|
||||
obj = obj ? Object.getPrototypeOf(obj) : this;
|
||||
if (!obj) {
|
||||
break;
|
||||
}
|
||||
if (!obj.eventListeners) {
|
||||
continue;
|
||||
}
|
||||
var events = obj.eventListeners[eventType];
|
||||
if (!events) {
|
||||
continue;
|
||||
}
|
||||
totalEvents = events.concat(totalEvents);
|
||||
obj = Object.getPrototypeOf(obj);
|
||||
}
|
||||
return totalEvents;
|
||||
};
|
||||
Node.prototype._fire = function (eventType, evt) {
|
||||
var events = this.eventListeners[eventType], i;
|
||||
if (events) {
|
||||
var events = this._getListeners(eventType), i;
|
||||
if (events.length) {
|
||||
evt = evt || {};
|
||||
evt.currentTarget = this;
|
||||
evt.type = eventType;
|
||||
@ -4699,6 +4707,26 @@
|
||||
}());
|
||||
Node.prototype.nodeType = 'Node';
|
||||
Node.prototype._attrsAffectingSize = [];
|
||||
// attache events listeners once into prototype
|
||||
// that way we don't spend too much time on making an new instance
|
||||
Node.prototype.eventListeners = {};
|
||||
Node.prototype.on.call(Node.prototype, TRANSFORM_CHANGE_STR, function () {
|
||||
if (this._batchingTransformChange) {
|
||||
this._needClearTransformCache = true;
|
||||
return;
|
||||
}
|
||||
this._clearCache(TRANSFORM);
|
||||
this._clearSelfAndDescendantCache(ABSOLUTE_TRANSFORM);
|
||||
});
|
||||
Node.prototype.on.call(Node.prototype, 'visibleChange.konva', function () {
|
||||
this._clearSelfAndDescendantCache(VISIBLE);
|
||||
});
|
||||
Node.prototype.on.call(Node.prototype, 'listeningChange.konva', function () {
|
||||
this._clearSelfAndDescendantCache(LISTENING);
|
||||
});
|
||||
Node.prototype.on.call(Node.prototype, 'opacityChange.konva', function () {
|
||||
this._clearSelfAndDescendantCache(ABSOLUTE_OPACITY);
|
||||
});
|
||||
var addGetterSetter = Factory.addGetterSetter;
|
||||
/**
|
||||
* get/set zIndex relative to the node's siblings who share the same parent.
|
||||
@ -6881,11 +6909,6 @@
|
||||
}
|
||||
_this.colorKey = key;
|
||||
shapes[key] = _this;
|
||||
_this.on('shadowColorChange.konva shadowBlurChange.konva shadowOffsetChange.konva shadowOpacityChange.konva shadowEnabledChange.konva', _clearHasShadowCache);
|
||||
_this.on('shadowColorChange.konva shadowOpacityChange.konva shadowEnabledChange.konva', _clearGetShadowRGBACache);
|
||||
_this.on('fillPriorityChange.konva fillPatternImageChange.konva fillPatternRepeatChange.konva fillPatternScaleXChange.konva fillPatternScaleYChange.konva', _clearFillPatternCache);
|
||||
_this.on('fillPriorityChange.konva fillLinearGradientColorStopsChange.konva fillLinearGradientStartPointXChange.konva fillLinearGradientStartPointYChange.konva fillLinearGradientEndPointXChange.konva fillLinearGradientEndPointYChange.konva', _clearLinearGradientCache);
|
||||
_this.on('fillPriorityChange.konva fillRadialGradientColorStopsChange.konva fillRadialGradientStartPointXChange.konva fillRadialGradientStartPointYChange.konva fillRadialGradientEndPointXChange.konva fillRadialGradientEndPointYChange.konva fillRadialGradientStartRadiusChange.konva fillRadialGradientEndRadiusChange.konva', _clearRadialGradientCache);
|
||||
return _this;
|
||||
}
|
||||
/**
|
||||
@ -7343,6 +7366,12 @@
|
||||
Shape.prototype._centroid = false;
|
||||
Shape.prototype.nodeType = 'Shape';
|
||||
_registerNode(Shape);
|
||||
Shape.prototype.eventListeners = {};
|
||||
Shape.prototype.on.call(Shape.prototype, 'shadowColorChange.konva shadowBlurChange.konva shadowOffsetChange.konva shadowOpacityChange.konva shadowEnabledChange.konva', _clearHasShadowCache);
|
||||
Shape.prototype.on.call(Shape.prototype, 'shadowColorChange.konva shadowOpacityChange.konva shadowEnabledChange.konva', _clearGetShadowRGBACache);
|
||||
Shape.prototype.on.call(Shape.prototype, 'fillPriorityChange.konva fillPatternImageChange.konva fillPatternRepeatChange.konva fillPatternScaleXChange.konva fillPatternScaleYChange.konva', _clearFillPatternCache);
|
||||
Shape.prototype.on.call(Shape.prototype, 'fillPriorityChange.konva fillLinearGradientColorStopsChange.konva fillLinearGradientStartPointXChange.konva fillLinearGradientStartPointYChange.konva fillLinearGradientEndPointXChange.konva fillLinearGradientEndPointYChange.konva', _clearLinearGradientCache);
|
||||
Shape.prototype.on.call(Shape.prototype, 'fillPriorityChange.konva fillRadialGradientColorStopsChange.konva fillRadialGradientStartPointXChange.konva fillRadialGradientStartPointYChange.konva fillRadialGradientEndPointXChange.konva fillRadialGradientEndPointYChange.konva fillRadialGradientStartRadiusChange.konva fillRadialGradientEndRadiusChange.konva', _clearRadialGradientCache);
|
||||
// add getters and setters
|
||||
Factory.addGetterSetter(Shape, 'stroke', undefined, getStringValidator());
|
||||
/**
|
||||
@ -9137,7 +9166,7 @@
|
||||
duration: 1,
|
||||
easing: 1,
|
||||
onFinish: 1,
|
||||
yoyo: 1
|
||||
yoyo: 1,
|
||||
}, PAUSED = 1, PLAYING = 2, REVERSING = 3, idCounter$1 = 0, colorAttrs = ['fill', 'stroke', 'shadowColor'];
|
||||
var TweenEngine = /** @class */ (function () {
|
||||
function TweenEngine(prop, propFunc, func, begin, finish, duration, yoyo) {
|
||||
@ -9234,6 +9263,7 @@
|
||||
};
|
||||
TweenEngine.prototype.update = function () {
|
||||
this.setPosition(this.getPosition(this._time));
|
||||
this.fire('onUpdate');
|
||||
};
|
||||
TweenEngine.prototype.onEnterFrame = function () {
|
||||
var t = this.getTimer() - this._startTime;
|
||||
@ -9262,10 +9292,15 @@
|
||||
* @example
|
||||
* // instantiate new tween which fully rotates a node in 1 second
|
||||
* var tween = new Konva.Tween({
|
||||
* // list of tween specific properties
|
||||
* node: node,
|
||||
* rotationDeg: 360,
|
||||
* duration: 1,
|
||||
* easing: Konva.Easings.EaseInOut
|
||||
* easing: Konva.Easings.EaseInOut,
|
||||
* onUpdate: () => console.log('node attrs updated')
|
||||
* onFinish: () => console.log('finished'),
|
||||
* // set new values for any attributes of a passed node
|
||||
* rotation: 360,
|
||||
* fill: 'red'
|
||||
* });
|
||||
*
|
||||
* // play tween
|
||||
@ -9321,6 +9356,7 @@
|
||||
// callbacks
|
||||
this.onFinish = config.onFinish;
|
||||
this.onReset = config.onReset;
|
||||
this.onUpdate = config.onUpdate;
|
||||
}
|
||||
Tween.prototype._addAttr = function (key, end) {
|
||||
var node = this.node, nodeId = node._id, start, diff, tweenId, n, len, trueEnd, trueStart, endRGBA;
|
||||
@ -9361,7 +9397,7 @@
|
||||
r: endRGBA.r - startRGBA.r,
|
||||
g: endRGBA.g - startRGBA.g,
|
||||
b: endRGBA.b - startRGBA.b,
|
||||
a: endRGBA.a - startRGBA.a
|
||||
a: endRGBA.a - startRGBA.a,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -9379,7 +9415,7 @@
|
||||
r: endRGBA.r - start.r,
|
||||
g: endRGBA.g - start.g,
|
||||
b: endRGBA.b - start.b,
|
||||
a: endRGBA.a - start.a
|
||||
a: endRGBA.a - start.a,
|
||||
};
|
||||
}
|
||||
else {
|
||||
@ -9390,7 +9426,7 @@
|
||||
diff: diff,
|
||||
end: end,
|
||||
trueEnd: trueEnd,
|
||||
trueStart: trueStart
|
||||
trueStart: trueStart,
|
||||
};
|
||||
Tween.tweens[nodeId][key] = this._id;
|
||||
};
|
||||
@ -9481,6 +9517,11 @@
|
||||
_this.onReset();
|
||||
}
|
||||
};
|
||||
this.tween.onUpdate = function () {
|
||||
if (_this.onUpdate) {
|
||||
_this.onUpdate.call(_this);
|
||||
}
|
||||
};
|
||||
};
|
||||
/**
|
||||
* play
|
||||
@ -9570,9 +9611,8 @@
|
||||
* circle.to({
|
||||
* x : 50,
|
||||
* duration : 0.5,
|
||||
* onFinish: () => {
|
||||
* console.log('finished');
|
||||
* }
|
||||
* onUpdate: () => console.log('props updated'),
|
||||
* onFinish: () => console.log('finished'),
|
||||
* });
|
||||
*/
|
||||
Node.prototype.to = function (params) {
|
||||
@ -9821,7 +9861,7 @@
|
||||
*/
|
||||
Linear: function (t, b, c, d) {
|
||||
return (c * t) / d + b;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// what is core parts of Konva?
|
||||
|
4
konva.min.js
vendored
4
konva.min.js
vendored
File diff suppressed because one or more lines are too long
78
src/Node.ts
78
src/Node.ts
@ -208,30 +208,17 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
children = emptyChildren;
|
||||
nodeType!: string;
|
||||
className!: string;
|
||||
|
||||
_dragEventId: number | null = null;
|
||||
_shouldFireChangeEvents = false;
|
||||
|
||||
constructor(config?: Config) {
|
||||
// on initial set attrs wi don't need to fire change events
|
||||
// because nobody is listening to them yet
|
||||
this.setAttrs(config);
|
||||
this._shouldFireChangeEvents = true;
|
||||
|
||||
// event bindings for cache handling
|
||||
this.on(TRANSFORM_CHANGE_STR, () => {
|
||||
if (this._batchingTransformChange) {
|
||||
this._needClearTransformCache = true;
|
||||
return;
|
||||
}
|
||||
this._clearCache(TRANSFORM);
|
||||
this._clearSelfAndDescendantCache(ABSOLUTE_TRANSFORM);
|
||||
});
|
||||
|
||||
this.on('visibleChange.konva', () => {
|
||||
this._clearSelfAndDescendantCache(VISIBLE);
|
||||
});
|
||||
this.on('listeningChange.konva', () => {
|
||||
this._clearSelfAndDescendantCache(LISTENING);
|
||||
});
|
||||
this.on('opacityChange.konva', () => {
|
||||
this._clearSelfAndDescendantCache(ABSOLUTE_OPACITY);
|
||||
});
|
||||
// all change event listeners are attached to the prototype
|
||||
}
|
||||
|
||||
hasChildren() {
|
||||
@ -2218,7 +2205,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
}
|
||||
return this;
|
||||
}
|
||||
_setAttr(key, val) {
|
||||
_setAttr(key, val, skipFire = false) {
|
||||
var oldVal = this.attrs[key];
|
||||
if (oldVal === val && !Util.isObject(val)) {
|
||||
return;
|
||||
@ -2228,7 +2215,9 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
} else {
|
||||
this.attrs[key] = val;
|
||||
}
|
||||
this._fireChangeEvent(key, oldVal, val);
|
||||
if (this._shouldFireChangeEvents) {
|
||||
this._fireChangeEvent(key, oldVal, val);
|
||||
}
|
||||
}
|
||||
_setComponentAttr(key, component, val) {
|
||||
var oldVal;
|
||||
@ -2280,11 +2269,32 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_getListeners(eventType) {
|
||||
let totalEvents = [];
|
||||
let obj;
|
||||
while (true) {
|
||||
obj = obj ? Object.getPrototypeOf(obj) : this;
|
||||
if (!obj) {
|
||||
break;
|
||||
}
|
||||
if (!obj.eventListeners) {
|
||||
continue;
|
||||
}
|
||||
const events = obj.eventListeners[eventType];
|
||||
if (!events) {
|
||||
continue;
|
||||
}
|
||||
totalEvents = events.concat(totalEvents);
|
||||
obj = Object.getPrototypeOf(obj);
|
||||
}
|
||||
return totalEvents;
|
||||
}
|
||||
_fire(eventType, evt) {
|
||||
var events = this.eventListeners[eventType],
|
||||
var events = this._getListeners(eventType),
|
||||
i;
|
||||
|
||||
if (events) {
|
||||
if (events.length) {
|
||||
evt = evt || {};
|
||||
evt.currentTarget = this;
|
||||
evt.type = eventType;
|
||||
@ -2604,6 +2614,28 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
Node.prototype.nodeType = 'Node';
|
||||
Node.prototype._attrsAffectingSize = [];
|
||||
|
||||
// attache events listeners once into prototype
|
||||
// that way we don't spend too much time on making an new instance
|
||||
Node.prototype.eventListeners = {};
|
||||
Node.prototype.on.call(Node.prototype, TRANSFORM_CHANGE_STR, function () {
|
||||
if (this._batchingTransformChange) {
|
||||
this._needClearTransformCache = true;
|
||||
return;
|
||||
}
|
||||
this._clearCache(TRANSFORM);
|
||||
this._clearSelfAndDescendantCache(ABSOLUTE_TRANSFORM);
|
||||
});
|
||||
|
||||
Node.prototype.on.call(Node.prototype, 'visibleChange.konva', function () {
|
||||
this._clearSelfAndDescendantCache(VISIBLE);
|
||||
});
|
||||
Node.prototype.on.call(Node.prototype, 'listeningChange.konva', function () {
|
||||
this._clearSelfAndDescendantCache(LISTENING);
|
||||
});
|
||||
Node.prototype.on.call(Node.prototype, 'opacityChange.konva', function () {
|
||||
this._clearSelfAndDescendantCache(ABSOLUTE_OPACITY);
|
||||
});
|
||||
|
||||
const addGetterSetter = Factory.addGetterSetter;
|
||||
|
||||
/**
|
||||
|
56
src/Shape.ts
56
src/Shape.ts
@ -182,31 +182,6 @@ export class Shape<Config extends ShapeConfig = ShapeConfig> extends Node<
|
||||
|
||||
this.colorKey = key;
|
||||
shapes[key] = this;
|
||||
|
||||
this.on(
|
||||
'shadowColorChange.konva shadowBlurChange.konva shadowOffsetChange.konva shadowOpacityChange.konva shadowEnabledChange.konva',
|
||||
_clearHasShadowCache
|
||||
);
|
||||
|
||||
this.on(
|
||||
'shadowColorChange.konva shadowOpacityChange.konva shadowEnabledChange.konva',
|
||||
_clearGetShadowRGBACache
|
||||
);
|
||||
|
||||
this.on(
|
||||
'fillPriorityChange.konva fillPatternImageChange.konva fillPatternRepeatChange.konva fillPatternScaleXChange.konva fillPatternScaleYChange.konva',
|
||||
_clearFillPatternCache
|
||||
);
|
||||
|
||||
this.on(
|
||||
'fillPriorityChange.konva fillLinearGradientColorStopsChange.konva fillLinearGradientStartPointXChange.konva fillLinearGradientStartPointYChange.konva fillLinearGradientEndPointXChange.konva fillLinearGradientEndPointYChange.konva',
|
||||
_clearLinearGradientCache
|
||||
);
|
||||
|
||||
this.on(
|
||||
'fillPriorityChange.konva fillRadialGradientColorStopsChange.konva fillRadialGradientStartPointXChange.konva fillRadialGradientStartPointYChange.konva fillRadialGradientEndPointXChange.konva fillRadialGradientEndPointYChange.konva fillRadialGradientStartRadiusChange.konva fillRadialGradientEndRadiusChange.konva',
|
||||
_clearRadialGradientCache
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -842,6 +817,37 @@ Shape.prototype._centroid = false;
|
||||
Shape.prototype.nodeType = 'Shape';
|
||||
_registerNode(Shape);
|
||||
|
||||
Shape.prototype.eventListeners = {};
|
||||
Shape.prototype.on.call(
|
||||
Shape.prototype,
|
||||
'shadowColorChange.konva shadowBlurChange.konva shadowOffsetChange.konva shadowOpacityChange.konva shadowEnabledChange.konva',
|
||||
_clearHasShadowCache
|
||||
);
|
||||
|
||||
Shape.prototype.on.call(
|
||||
Shape.prototype,
|
||||
'shadowColorChange.konva shadowOpacityChange.konva shadowEnabledChange.konva',
|
||||
_clearGetShadowRGBACache
|
||||
);
|
||||
|
||||
Shape.prototype.on.call(
|
||||
Shape.prototype,
|
||||
'fillPriorityChange.konva fillPatternImageChange.konva fillPatternRepeatChange.konva fillPatternScaleXChange.konva fillPatternScaleYChange.konva',
|
||||
_clearFillPatternCache
|
||||
);
|
||||
|
||||
Shape.prototype.on.call(
|
||||
Shape.prototype,
|
||||
'fillPriorityChange.konva fillLinearGradientColorStopsChange.konva fillLinearGradientStartPointXChange.konva fillLinearGradientStartPointYChange.konva fillLinearGradientEndPointXChange.konva fillLinearGradientEndPointYChange.konva',
|
||||
_clearLinearGradientCache
|
||||
);
|
||||
|
||||
Shape.prototype.on.call(
|
||||
Shape.prototype,
|
||||
'fillPriorityChange.konva fillRadialGradientColorStopsChange.konva fillRadialGradientStartPointXChange.konva fillRadialGradientStartPointYChange.konva fillRadialGradientEndPointXChange.konva fillRadialGradientEndPointYChange.konva fillRadialGradientStartRadiusChange.konva fillRadialGradientEndRadiusChange.konva',
|
||||
_clearRadialGradientCache
|
||||
);
|
||||
|
||||
// add getters and setters
|
||||
Factory.addGetterSetter(Shape, 'stroke', undefined, getStringValidator());
|
||||
|
||||
|
@ -10,8 +10,8 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id="container"></div>
|
||||
<script src="../../konva.js"></script>
|
||||
<!-- <script src="https://unpkg.com/konva@6.0.0/konva.min.js"></script> -->
|
||||
<!-- <script src="../../konva.js"></script> -->
|
||||
<script src="https://unpkg.com/konva@7.0.3/konva.min.js"></script>
|
||||
<script src="http://www.html5canvastutorials.com/lib/stats/stats.js"></script>
|
||||
<script defer="defer">
|
||||
var lastTime = 0;
|
||||
|
107
test/performance/creating_elements.html
Normal file
107
test/performance/creating_elements.html
Normal file
@ -0,0 +1,107 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container"></div>
|
||||
<script src="../../konva.js"></script>
|
||||
<!-- <script src="https://unpkg.com/konva@7.0.3/konva.min.js"></script> -->
|
||||
<script src="http://www.html5canvastutorials.com/lib/stats/stats.js"></script>
|
||||
<script defer="defer">
|
||||
var lastTime = 0;
|
||||
|
||||
var width = window.innerWidth;
|
||||
var height = window.innerHeight;
|
||||
|
||||
var maxX = width - 10;
|
||||
var minX = 0;
|
||||
var maxY = height - 10;
|
||||
var minY = 0;
|
||||
|
||||
var startObjectsCount = 5000;
|
||||
var isAdding = false;
|
||||
var count = 0;
|
||||
var container;
|
||||
var layer;
|
||||
var stats;
|
||||
var amount = 10;
|
||||
var counter;
|
||||
|
||||
var stage = new Konva.Stage({
|
||||
container: 'container',
|
||||
width: width - 10,
|
||||
height: height - 10,
|
||||
});
|
||||
layer = new Konva.Layer();
|
||||
stage.add(layer);
|
||||
stats = new Stats();
|
||||
|
||||
document.body.appendChild(stats.domElement);
|
||||
stats.domElement.style.position = 'absolute';
|
||||
stats.domElement.style.top = '0px';
|
||||
|
||||
window.requestAnimationFrame(update);
|
||||
|
||||
counter = document.createElement('div');
|
||||
counter.className = 'counter';
|
||||
counter.style.position = 'absolute';
|
||||
counter.style.top = '50px';
|
||||
|
||||
document.body.appendChild(counter);
|
||||
|
||||
count = startObjectsCount;
|
||||
counter.innerHTML = startObjectsCount + ' BUNNIES';
|
||||
|
||||
container = stage;
|
||||
// stage.addChild(container);
|
||||
|
||||
stage.on('mousedown', function () {
|
||||
isAdding = true;
|
||||
});
|
||||
|
||||
stage.on('mouseup', function () {
|
||||
isAdding = false;
|
||||
});
|
||||
|
||||
document.addEventListener('touchstart', onTouchStart, true);
|
||||
document.addEventListener('touchend', onTouchEnd, true);
|
||||
|
||||
function onTouchStart(event) {
|
||||
isAdding = true;
|
||||
}
|
||||
|
||||
function onTouchEnd(event) {
|
||||
isAdding = false;
|
||||
}
|
||||
|
||||
function update() {
|
||||
stats.begin();
|
||||
layer.destroyChildren();
|
||||
if (isAdding) {
|
||||
// add 10 at a time :)
|
||||
count += 10;
|
||||
counter.innerHTML = count + ' BUNNIES';
|
||||
}
|
||||
for (var i = 0; i < count; i++) {
|
||||
var bunny = new Konva.Rect({
|
||||
x: Math.random() * width,
|
||||
y: Math.random() * height,
|
||||
width: 50,
|
||||
height: 50,
|
||||
fill: Konva.Util.getRandomColor(),
|
||||
});
|
||||
layer.add(bunny);
|
||||
}
|
||||
|
||||
requestAnimationFrame(update);
|
||||
stats.end();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user