mirror of
https://github.com/konvajs/konva.git
synced 2025-04-05 20:48:28 +08:00
perf optimizations
This commit is contained in:
parent
e22a98d656
commit
0fe8e7fb7f
71
konva.js
71
konva.js
@ -2644,6 +2644,7 @@
|
||||
this.index = 0;
|
||||
this.parent = null;
|
||||
this._cache = new Map();
|
||||
this._attachedDepsListeners = new Map();
|
||||
this._lastPos = null;
|
||||
this._batchingTransformChange = false;
|
||||
this._needClearTransformCache = false;
|
||||
@ -2706,6 +2707,20 @@
|
||||
}
|
||||
return cache;
|
||||
};
|
||||
Node.prototype._calculate = function (name, deps, getter) {
|
||||
var _this = this;
|
||||
// if we are trying to calculate function for the first time
|
||||
// we need to attach listeners for change events
|
||||
if (!this._attachedDepsListeners.get(name)) {
|
||||
var depsString = deps.map(function (dep) { return dep + 'Change.konva'; }).join(SPACE);
|
||||
this.on(depsString, function () {
|
||||
_this._clearCache(name);
|
||||
});
|
||||
this._attachedDepsListeners.set(name, true);
|
||||
}
|
||||
// just use cache function
|
||||
return this._getCache(name, getter);
|
||||
};
|
||||
Node.prototype._getCanvasCache = function () {
|
||||
return this._cache.get(CANVAS);
|
||||
};
|
||||
@ -4044,6 +4059,9 @@
|
||||
Node.prototype._getTransform = function () {
|
||||
var m = this._cache.get(TRANSFORM) || new Transform();
|
||||
m.reset();
|
||||
// I was trying to use attributes directly here
|
||||
// but it doesn't work for Transformer well
|
||||
// because it overwrite x,y getters
|
||||
var x = this.x(), y = this.y(), rotation = Konva.getAngle(this.rotation()), scaleX = this.scaleX(), scaleY = this.scaleY(), skewX = this.skewX(), skewY = this.skewY(), offsetX = this.offsetX(), offsetY = this.offsetY();
|
||||
if (x !== 0 || y !== 0) {
|
||||
m.translate(x, y);
|
||||
@ -6964,11 +6982,20 @@
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
Shape.prototype.hasFill = function () {
|
||||
return (this.fillEnabled() &&
|
||||
!!(this.fill() ||
|
||||
this.fillPatternImage() ||
|
||||
this.fillLinearGradientColorStops() ||
|
||||
this.fillRadialGradientColorStops()));
|
||||
var _this = this;
|
||||
return this._calculate('hasFill', [
|
||||
'fillEnabled',
|
||||
'fill',
|
||||
'fillPatternImage',
|
||||
'fillLinearGradientColorStops',
|
||||
'fillRadialGradientColorStops',
|
||||
], function () {
|
||||
return (_this.fillEnabled() &&
|
||||
!!(_this.fill() ||
|
||||
_this.fillPatternImage() ||
|
||||
_this.fillLinearGradientColorStops() ||
|
||||
_this.fillRadialGradientColorStops()));
|
||||
});
|
||||
};
|
||||
/**
|
||||
* returns whether or not the shape will be stroked
|
||||
@ -6977,11 +7004,25 @@
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
Shape.prototype.hasStroke = function () {
|
||||
return (this.strokeEnabled() &&
|
||||
this.strokeWidth() &&
|
||||
!!(this.stroke() || this.strokeLinearGradientColorStops())
|
||||
// this.getStrokeRadialGradientColorStops()
|
||||
);
|
||||
var _this = this;
|
||||
return this._calculate('hasStroke', [
|
||||
'strokeEnabled',
|
||||
'strokeWidth',
|
||||
'stroke',
|
||||
'strokeLinearGradientColorStops',
|
||||
], function () {
|
||||
return (_this.strokeEnabled() &&
|
||||
_this.strokeWidth() &&
|
||||
!!(_this.stroke() || _this.strokeLinearGradientColorStops())
|
||||
// this.getStrokeRadialGradientColorStops()
|
||||
);
|
||||
});
|
||||
// return (
|
||||
// this.strokeEnabled() &&
|
||||
// this.strokeWidth() &&
|
||||
// !!(this.stroke() || this.strokeLinearGradientColorStops())
|
||||
// // this.getStrokeRadialGradientColorStops()
|
||||
// );
|
||||
};
|
||||
Shape.prototype.hasHitStroke = function () {
|
||||
var width = this.hitStrokeWidth();
|
||||
@ -14806,7 +14847,7 @@
|
||||
var lastPos;
|
||||
node.on("dragstart." + EVENTS_NAME, function (e) {
|
||||
lastPos = node.getAbsolutePosition();
|
||||
_this.fire('dragstart', e);
|
||||
// this.fire('dragstart', e);
|
||||
});
|
||||
node.on("dragmove." + EVENTS_NAME, function (e) {
|
||||
if (!lastPos) {
|
||||
@ -14828,12 +14869,10 @@
|
||||
y: otherAbs.y + dy,
|
||||
});
|
||||
otherNode.startDrag();
|
||||
// TODO: how to trigger event after all nodes are dragged?
|
||||
_this.fire('dragmove', e);
|
||||
});
|
||||
node.on("dragend." + EVENTS_NAME, function (e) {
|
||||
_this.fire('dragend', e);
|
||||
});
|
||||
// node.on(`dragend.${EVENTS_NAME}`, (e) => {
|
||||
// this.fire('dragend', e);
|
||||
// });
|
||||
lastPos = null;
|
||||
});
|
||||
};
|
||||
|
2
konva.min.js
vendored
2
konva.min.js
vendored
File diff suppressed because one or more lines are too long
19
src/Node.ts
19
src/Node.ts
@ -197,6 +197,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
index = 0;
|
||||
parent: Container<Node> | null = null;
|
||||
_cache: Map<string, any> = new Map<string, any>();
|
||||
_attachedDepsListeners: Map<string, boolean> = new Map<string, boolean>();
|
||||
_lastPos: Vector2d = null;
|
||||
_attrsAffectingSize!: string[];
|
||||
_batchingTransformChange = false;
|
||||
@ -273,6 +274,21 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
_calculate(name, deps, getter) {
|
||||
// if we are trying to calculate function for the first time
|
||||
// we need to attach listeners for change events
|
||||
if (!this._attachedDepsListeners.get(name)) {
|
||||
const depsString = deps.map((dep) => dep + 'Change.konva').join(SPACE);
|
||||
this.on(depsString, () => {
|
||||
this._clearCache(name);
|
||||
});
|
||||
this._attachedDepsListeners.set(name, true);
|
||||
}
|
||||
// just use cache function
|
||||
return this._getCache(name, getter);
|
||||
}
|
||||
|
||||
_getCanvasCache() {
|
||||
return this._cache.get(CANVAS);
|
||||
}
|
||||
@ -1786,6 +1802,9 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
var m: Transform = this._cache.get(TRANSFORM) || new Transform();
|
||||
m.reset();
|
||||
|
||||
// I was trying to use attributes directly here
|
||||
// but it doesn't work for Transformer well
|
||||
// because it overwrite x,y getters
|
||||
var x = this.x(),
|
||||
y = this.y(),
|
||||
rotation = Konva.getAngle(this.rotation()),
|
||||
|
55
src/Shape.ts
55
src/Shape.ts
@ -351,14 +351,26 @@ export class Shape<Config extends ShapeConfig = ShapeConfig> extends Node<
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
hasFill() {
|
||||
return (
|
||||
this.fillEnabled() &&
|
||||
!!(
|
||||
this.fill() ||
|
||||
this.fillPatternImage() ||
|
||||
this.fillLinearGradientColorStops() ||
|
||||
this.fillRadialGradientColorStops()
|
||||
)
|
||||
return this._calculate(
|
||||
'hasFill',
|
||||
[
|
||||
'fillEnabled',
|
||||
'fill',
|
||||
'fillPatternImage',
|
||||
'fillLinearGradientColorStops',
|
||||
'fillRadialGradientColorStops',
|
||||
],
|
||||
() => {
|
||||
return (
|
||||
this.fillEnabled() &&
|
||||
!!(
|
||||
this.fill() ||
|
||||
this.fillPatternImage() ||
|
||||
this.fillLinearGradientColorStops() ||
|
||||
this.fillRadialGradientColorStops()
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
/**
|
||||
@ -368,12 +380,29 @@ export class Shape<Config extends ShapeConfig = ShapeConfig> extends Node<
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
hasStroke() {
|
||||
return (
|
||||
this.strokeEnabled() &&
|
||||
this.strokeWidth() &&
|
||||
!!(this.stroke() || this.strokeLinearGradientColorStops())
|
||||
// this.getStrokeRadialGradientColorStops()
|
||||
return this._calculate(
|
||||
'hasStroke',
|
||||
[
|
||||
'strokeEnabled',
|
||||
'strokeWidth',
|
||||
'stroke',
|
||||
'strokeLinearGradientColorStops',
|
||||
],
|
||||
() => {
|
||||
return (
|
||||
this.strokeEnabled() &&
|
||||
this.strokeWidth() &&
|
||||
!!(this.stroke() || this.strokeLinearGradientColorStops())
|
||||
// this.getStrokeRadialGradientColorStops()
|
||||
);
|
||||
}
|
||||
);
|
||||
// return (
|
||||
// this.strokeEnabled() &&
|
||||
// this.strokeWidth() &&
|
||||
// !!(this.stroke() || this.strokeLinearGradientColorStops())
|
||||
// // this.getStrokeRadialGradientColorStops()
|
||||
// );
|
||||
}
|
||||
hasHitStroke() {
|
||||
const width = this.hitStrokeWidth();
|
||||
|
@ -316,7 +316,7 @@ export class Transformer extends Group {
|
||||
let lastPos;
|
||||
node.on(`dragstart.${EVENTS_NAME}`, (e) => {
|
||||
lastPos = node.getAbsolutePosition();
|
||||
this.fire('dragstart', e);
|
||||
// this.fire('dragstart', e);
|
||||
});
|
||||
node.on(`dragmove.${EVENTS_NAME}`, (e) => {
|
||||
if (!lastPos) {
|
||||
@ -338,12 +338,10 @@ export class Transformer extends Group {
|
||||
y: otherAbs.y + dy,
|
||||
});
|
||||
otherNode.startDrag();
|
||||
// TODO: how to trigger event after all nodes are dragged?
|
||||
this.fire('dragmove', e);
|
||||
});
|
||||
node.on(`dragend.${EVENTS_NAME}`, (e) => {
|
||||
this.fire('dragend', e);
|
||||
});
|
||||
// node.on(`dragend.${EVENTS_NAME}`, (e) => {
|
||||
// this.fire('dragend', e);
|
||||
// });
|
||||
lastPos = null;
|
||||
});
|
||||
}
|
||||
|
@ -92,6 +92,7 @@
|
||||
transformsEnabled: 'position',
|
||||
x: 10,
|
||||
y: 10,
|
||||
perfectDrawEnabled: false,
|
||||
});
|
||||
|
||||
bunny.speedX = Math.random() * 10;
|
||||
@ -122,6 +123,7 @@
|
||||
transformsEnabled: 'position',
|
||||
x: 0,
|
||||
y: 0,
|
||||
perfectDrawEnabled: false,
|
||||
});
|
||||
bunny.speedX = Math.random() * 10;
|
||||
bunny.speedY = Math.random() * 10 - 5;
|
||||
|
@ -3861,9 +3861,9 @@ suite('Transformer', function () {
|
||||
// proxy drag to other nodes
|
||||
assert.equal(rect2.x(), 105);
|
||||
assert.equal(rect2.y(), 105);
|
||||
assert.equal(dragstart, 2);
|
||||
assert.equal(dragmove, 2);
|
||||
assert.equal(dragend, 2);
|
||||
assert.equal(dragstart, 1);
|
||||
assert.equal(dragmove, 1);
|
||||
assert.equal(dragend, 1);
|
||||
});
|
||||
|
||||
test('reattach from several and drag one', function () {
|
||||
|
Loading…
Reference in New Issue
Block a user