mirror of
https://github.com/konvajs/konva.git
synced 2025-06-28 08:48:57 +08:00
Merge branch 'master' into fix-unscalable-strokes
This commit is contained in:
commit
1bcea51047
@ -13,10 +13,14 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
## Changes
|
||||
|
||||
* Fixed flow for `contextmenu` event. Not it will be triggered on shapes too
|
||||
* `find()` method for Containers can use a function as a parameter
|
||||
|
||||
## Fixed
|
||||
|
||||
* some bugs fixes for `group.getClientRect()`
|
||||
* `Konva.Arrow` will not draw dash for pointers
|
||||
* setAttr will trigger change event if new value is the same Object
|
||||
* better behavior of `dblclick` event when you click fast on different shapes
|
||||
|
||||
## [2.0.2][2018-03-15]
|
||||
|
||||
|
2
konva.d.ts
vendored
2
konva.d.ts
vendored
@ -343,7 +343,7 @@ declare namespace Konva {
|
||||
clipFunc(ctx: CanvasRenderingContext2D | undefined | null): void;
|
||||
destroyChildren(): void;
|
||||
find(selector?: string | ((Node) => boolean)): Collection;
|
||||
findOne<T extends Node>(selector: string): T;
|
||||
findOne<T extends Node>(selector: string | ((Node) => boolean)): T;
|
||||
getAllIntersections(pos: Vector2d): Shape[];
|
||||
hasChildren(): boolean;
|
||||
removeChildren(): void;
|
||||
|
143
konva.js
143
konva.js
@ -2,7 +2,7 @@
|
||||
* Konva JavaScript Framework v2.0.2
|
||||
* http://konvajs.github.io/
|
||||
* Licensed under the MIT
|
||||
* Date: Sun Mar 25 2018
|
||||
* Date: Wed Apr 11 2018
|
||||
*
|
||||
* Original work Copyright (C) 2011 - 2013 by Eric Rowell (KineticJS)
|
||||
* Modified work Copyright (C) 2014 - present by Anton Lavrenov (Konva)
|
||||
@ -352,7 +352,10 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Transform constructor
|
||||
* Transform constructor. Transform object is a private class of Konva framework.
|
||||
* In most of the cases you don't need to use it in your app.
|
||||
* But there is a documentation for that class in case you still want
|
||||
* to make some manual calculations.
|
||||
* @constructor
|
||||
* @param {Array} [m] Optional six-element matrix
|
||||
* @memberof Konva
|
||||
@ -732,6 +735,10 @@
|
||||
_isString: function(obj) {
|
||||
return Object.prototype.toString.call(obj) === OBJECT_STRING;
|
||||
},
|
||||
// arrays are objects too
|
||||
isObject: function(val) {
|
||||
return val instanceof Object;
|
||||
},
|
||||
isValidSelector: function(selector) {
|
||||
if (typeof selector !== 'string') {
|
||||
return false;
|
||||
@ -4253,7 +4260,8 @@
|
||||
_setAttr: function(key, val) {
|
||||
var oldVal;
|
||||
oldVal = this.attrs[key];
|
||||
if (oldVal === val) {
|
||||
var same = oldVal === val;
|
||||
if (same && !Konva.Util.isObject(val)) {
|
||||
return;
|
||||
}
|
||||
if (val === undefined || val === null) {
|
||||
@ -7811,31 +7819,42 @@
|
||||
* });
|
||||
*/
|
||||
find: function(selector) {
|
||||
var retArr = [];
|
||||
|
||||
if (typeof selector === 'string') {
|
||||
retArr = this._findByString(selector);
|
||||
} else if (typeof selector === 'function') {
|
||||
retArr = this._findByFunction(selector);
|
||||
}
|
||||
|
||||
return Konva.Collection.toCollection(retArr);
|
||||
// protecting _generalFind to prevent user from accidentally adding
|
||||
// second argument and getting unexpected `findOne` result
|
||||
return this._generalFind(selector, false);
|
||||
},
|
||||
/**
|
||||
* return a first node from `find` method
|
||||
* @method
|
||||
* @memberof Konva.Container.prototype
|
||||
* @param {String} selector
|
||||
* @returns {Konva.Node}
|
||||
* @param {String | Function} selector
|
||||
* @returns {Konva.Node | Undefined}
|
||||
* @example
|
||||
* // select node with id foo
|
||||
* var node = stage.findOne('#foo');
|
||||
*
|
||||
* // select node with name bar inside layer
|
||||
* var nodes = layer.findOne('.bar');
|
||||
*
|
||||
* // select the first node to return true in a function
|
||||
* var node = stage.findOne(node => {
|
||||
* return node.getType() === 'Shape'
|
||||
* })
|
||||
*/
|
||||
findOne: function(selector) {
|
||||
return this.find(selector)[0];
|
||||
var result = this._generalFind(selector, true);
|
||||
return result.length > 0 ? result[0] : undefined;
|
||||
},
|
||||
_generalFind: function(selector, findOne) {
|
||||
var retArr = [];
|
||||
|
||||
if (typeof selector === 'string') {
|
||||
retArr = this._findByString(selector, findOne);
|
||||
} else if (typeof selector === 'function') {
|
||||
retArr = this._findByFunction(selector, findOne);
|
||||
}
|
||||
|
||||
return Konva.Collection.toCollection(retArr);
|
||||
},
|
||||
_findByString: function(selector) {
|
||||
var retArr = [],
|
||||
@ -7884,10 +7903,16 @@
|
||||
|
||||
return retArr;
|
||||
},
|
||||
_findByFunction: function(fn) {
|
||||
// (fn: ((Node) => boolean, findOne?: boolean)
|
||||
_findByFunction: function(fn, findOne) {
|
||||
var retArr = [];
|
||||
|
||||
var addItems = function(el) {
|
||||
// escape function if we've already found one.
|
||||
if (findOne && retArr.length > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var children = el.getChildren();
|
||||
var clen = children.length;
|
||||
|
||||
@ -10631,7 +10656,8 @@
|
||||
|
||||
if (Konva.inDblClickWindow) {
|
||||
fireDblClick = true;
|
||||
Konva.inDblClickWindow = false;
|
||||
clearTimeout(this.dblTimeout);
|
||||
// Konva.inDblClickWindow = false;
|
||||
} else if (!dd || !dd.justDragged) {
|
||||
// don't set inDblClickWindow after dragging
|
||||
Konva.inDblClickWindow = true;
|
||||
@ -10639,7 +10665,7 @@
|
||||
dd.justDragged = false;
|
||||
}
|
||||
|
||||
setTimeout(function() {
|
||||
this.dblTimeout = setTimeout(function() {
|
||||
Konva.inDblClickWindow = false;
|
||||
}, Konva.dblClickWindow);
|
||||
|
||||
@ -10738,12 +10764,13 @@
|
||||
|
||||
if (Konva.inDblClickWindow) {
|
||||
fireDblClick = true;
|
||||
Konva.inDblClickWindow = false;
|
||||
clearTimeout(this.dblTimeout);
|
||||
// Konva.inDblClickWindow = false;
|
||||
} else {
|
||||
Konva.inDblClickWindow = true;
|
||||
}
|
||||
|
||||
setTimeout(function() {
|
||||
this.dblTimeout = setTimeout(function() {
|
||||
Konva.inDblClickWindow = false;
|
||||
}, Konva.dblClickWindow);
|
||||
|
||||
@ -14755,14 +14782,6 @@
|
||||
context.closePath();
|
||||
context.fillStrokeShape(this);
|
||||
},
|
||||
// _useBufferCanvas: function(caching) {
|
||||
// var useIt = Konva.Shape.prototype._useBufferCanvas.call(this, caching);
|
||||
// if (useIt) {
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
// // return isFirefox && this.hasFill() && this.hasShadow();
|
||||
// },
|
||||
setText: function(text) {
|
||||
var str = Konva.Util._isString(text) ? text : (text || '').toString();
|
||||
this._setAttr(TEXT, str);
|
||||
@ -14896,14 +14915,14 @@
|
||||
var lineWidth = this._getTextWidth(line);
|
||||
if (fixedWidth && lineWidth > maxWidth) {
|
||||
/*
|
||||
* if width is fixed and line does not fit entirely
|
||||
* break the line into multiple fitting lines
|
||||
*/
|
||||
* if width is fixed and line does not fit entirely
|
||||
* break the line into multiple fitting lines
|
||||
*/
|
||||
while (line.length > 0) {
|
||||
/*
|
||||
* use binary search to find the longest substring that
|
||||
* that would fit in the specified width
|
||||
*/
|
||||
* use binary search to find the longest substring that
|
||||
* that would fit in the specified width
|
||||
*/
|
||||
var low = 0,
|
||||
high = line.length,
|
||||
match = '',
|
||||
@ -14947,9 +14966,9 @@
|
||||
(fixedHeight && currentHeightPx + lineHeightPx > maxHeightPx)
|
||||
) {
|
||||
/*
|
||||
* stop wrapping if wrapping is disabled or if adding
|
||||
* one more line would overflow the fixed height
|
||||
*/
|
||||
* stop wrapping if wrapping is disabled or if adding
|
||||
* one more line would overflow the fixed height
|
||||
*/
|
||||
break;
|
||||
}
|
||||
line = line.slice(low);
|
||||
@ -18521,7 +18540,24 @@
|
||||
ctx.closePath();
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
// here is a tricky part
|
||||
// we need to disable dash for arrow pointers
|
||||
var isDashEnabled = this.dashEnabled();
|
||||
if (isDashEnabled) {
|
||||
// manually disable dash for head
|
||||
// it is better not to use setter here,
|
||||
// because it will trigger attr change event
|
||||
this.attrs.dashEnabled = false;
|
||||
ctx.setLineDash([]);
|
||||
}
|
||||
|
||||
ctx.fillStrokeShape(this);
|
||||
|
||||
// restore old value
|
||||
if (isDashEnabled) {
|
||||
this.attrs.dashEnabled = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -19159,31 +19195,32 @@
|
||||
}
|
||||
},
|
||||
|
||||
_fitNodeInto: function(attrs) {
|
||||
_fitNodeInto: function(newAttrs) {
|
||||
// waring! in this attrs padding may be included
|
||||
var boundBoxFunc = this.getBoundBoxFunc();
|
||||
if (boundBoxFunc) {
|
||||
var oldAttrs = this._getNodeRect();
|
||||
newAttrs = boundBoxFunc.call(this, oldAttrs, newAttrs);
|
||||
}
|
||||
this._settings = true;
|
||||
var node = this.getNode();
|
||||
if (attrs.rotation !== undefined) {
|
||||
this.getNode().rotation(attrs.rotation);
|
||||
if (newAttrs.rotation !== undefined) {
|
||||
this.getNode().rotation(newAttrs.rotation);
|
||||
}
|
||||
var pure = node.getClientRect({ skipTransform: true });
|
||||
var padding = this.getPadding();
|
||||
var scaleX = (attrs.width - padding * 2) / pure.width;
|
||||
var scaleY = (attrs.height - padding * 2) / pure.height;
|
||||
var scaleX = (newAttrs.width - padding * 2) / pure.width;
|
||||
var scaleY = (newAttrs.height - padding * 2) / pure.height;
|
||||
|
||||
var rotation = Konva.getAngle(node.getRotation());
|
||||
// debugger;
|
||||
var dx = pure.x * scaleX - padding;
|
||||
var dy = pure.y * scaleY - padding;
|
||||
|
||||
// var dxo = node.offsetX() * scaleX;
|
||||
// var dyo = node.offsetY() * scaleY;
|
||||
|
||||
this.getNode().setAttrs({
|
||||
scaleX: scaleX,
|
||||
scaleY: scaleY,
|
||||
x: attrs.x - (dx * Math.cos(rotation) + dy * Math.sin(-rotation)),
|
||||
y: attrs.y - (dy * Math.cos(rotation) + dx * Math.sin(rotation))
|
||||
x: newAttrs.x - (dx * Math.cos(rotation) + dy * Math.sin(-rotation)),
|
||||
y: newAttrs.y - (dy * Math.cos(rotation) + dx * Math.sin(rotation))
|
||||
});
|
||||
this._settings = false;
|
||||
|
||||
@ -19276,6 +19313,14 @@
|
||||
visible: this.lineEnabled()
|
||||
});
|
||||
},
|
||||
isTransforming: function() {
|
||||
return this._transforming;
|
||||
},
|
||||
stopTransform: function() {
|
||||
if (this._transforming) {
|
||||
this._removeEvents();
|
||||
}
|
||||
},
|
||||
destroy: function() {
|
||||
Konva.Group.prototype.destroy.call(this);
|
||||
this.detach();
|
||||
@ -19443,5 +19488,7 @@
|
||||
|
||||
Konva.Factory.addOverloadedGetterSetter(Konva.Transformer, 'node');
|
||||
|
||||
Konva.Factory.addGetterSetter(Konva.Transformer, 'boundBoxFunc');
|
||||
|
||||
Konva.Collection.mapMethods(Konva.Transformer);
|
||||
})(Konva);
|
||||
|
6
konva.min.js
vendored
6
konva.min.js
vendored
File diff suppressed because one or more lines are too long
21
package.json
21
package.json
@ -2,13 +2,7 @@
|
||||
"name": "konva",
|
||||
"version": "2.0.2",
|
||||
"author": "Anton Lavrenov",
|
||||
"files": [
|
||||
"README.md",
|
||||
"konva.js",
|
||||
"konva.min.js",
|
||||
"src",
|
||||
"konva.d.ts"
|
||||
],
|
||||
"files": ["README.md", "konva.js", "konva.min.js", "src", "konva.d.ts"],
|
||||
"main": "konva.js",
|
||||
"typings": "./konva.d.ts",
|
||||
"scripts": {
|
||||
@ -17,7 +11,8 @@
|
||||
"build": "gulp build",
|
||||
"full-build": "gulp lint test build",
|
||||
"test": "gulp test",
|
||||
"prettier": "prettier --write \"src/**/*.js\" \"test/**/*.js\" --single-quote"
|
||||
"prettier":
|
||||
"prettier --write \"src/**/*.js\" \"test/**/*.js\" --single-quote"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chai": "4.1.2",
|
||||
@ -35,12 +30,10 @@
|
||||
"mocha": "4.0.1",
|
||||
"prettier": "^1.9.2"
|
||||
},
|
||||
"keywords": [
|
||||
"canvas",
|
||||
"animations",
|
||||
"graphic",
|
||||
"html5"
|
||||
],
|
||||
"keywords": ["canvas", "animations", "graphic", "html5"],
|
||||
"prettier": {
|
||||
"singleQuote": true
|
||||
},
|
||||
"browser": {
|
||||
"canvas": false,
|
||||
"jsdom": false
|
||||
|
@ -181,31 +181,42 @@
|
||||
* });
|
||||
*/
|
||||
find: function(selector) {
|
||||
var retArr = [];
|
||||
|
||||
if (typeof selector === 'string') {
|
||||
retArr = this._findByString(selector);
|
||||
} else if (typeof selector === 'function') {
|
||||
retArr = this._findByFunction(selector);
|
||||
}
|
||||
|
||||
return Konva.Collection.toCollection(retArr);
|
||||
// protecting _generalFind to prevent user from accidentally adding
|
||||
// second argument and getting unexpected `findOne` result
|
||||
return this._generalFind(selector, false);
|
||||
},
|
||||
/**
|
||||
* return a first node from `find` method
|
||||
* @method
|
||||
* @memberof Konva.Container.prototype
|
||||
* @param {String} selector
|
||||
* @returns {Konva.Node}
|
||||
* @param {String | Function} selector
|
||||
* @returns {Konva.Node | Undefined}
|
||||
* @example
|
||||
* // select node with id foo
|
||||
* var node = stage.findOne('#foo');
|
||||
*
|
||||
* // select node with name bar inside layer
|
||||
* var nodes = layer.findOne('.bar');
|
||||
*
|
||||
* // select the first node to return true in a function
|
||||
* var node = stage.findOne(node => {
|
||||
* return node.getType() === 'Shape'
|
||||
* })
|
||||
*/
|
||||
findOne: function(selector) {
|
||||
return this.find(selector)[0];
|
||||
var result = this._generalFind(selector, true);
|
||||
return result.length > 0 ? result[0] : undefined;
|
||||
},
|
||||
_generalFind: function(selector, findOne) {
|
||||
var retArr = [];
|
||||
|
||||
if (typeof selector === 'string') {
|
||||
retArr = this._findByString(selector, findOne);
|
||||
} else if (typeof selector === 'function') {
|
||||
retArr = this._findByFunction(selector, findOne);
|
||||
}
|
||||
|
||||
return Konva.Collection.toCollection(retArr);
|
||||
},
|
||||
_findByString: function(selector) {
|
||||
var retArr = [],
|
||||
@ -254,10 +265,16 @@
|
||||
|
||||
return retArr;
|
||||
},
|
||||
_findByFunction: function(fn) {
|
||||
// (fn: ((Node) => boolean, findOne?: boolean)
|
||||
_findByFunction: function(fn, findOne) {
|
||||
var retArr = [];
|
||||
|
||||
var addItems = function(el) {
|
||||
// escape function if we've already found one.
|
||||
if (findOne && retArr.length > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var children = el.getChildren();
|
||||
var clen = children.length;
|
||||
|
||||
|
@ -1879,7 +1879,8 @@
|
||||
_setAttr: function(key, val) {
|
||||
var oldVal;
|
||||
oldVal = this.attrs[key];
|
||||
if (oldVal === val) {
|
||||
var same = oldVal === val;
|
||||
if (same && !Konva.Util.isObject(val)) {
|
||||
return;
|
||||
}
|
||||
if (val === undefined || val === null) {
|
||||
|
10
src/Stage.js
10
src/Stage.js
@ -550,7 +550,8 @@
|
||||
|
||||
if (Konva.inDblClickWindow) {
|
||||
fireDblClick = true;
|
||||
Konva.inDblClickWindow = false;
|
||||
clearTimeout(this.dblTimeout);
|
||||
// Konva.inDblClickWindow = false;
|
||||
} else if (!dd || !dd.justDragged) {
|
||||
// don't set inDblClickWindow after dragging
|
||||
Konva.inDblClickWindow = true;
|
||||
@ -558,7 +559,7 @@
|
||||
dd.justDragged = false;
|
||||
}
|
||||
|
||||
setTimeout(function() {
|
||||
this.dblTimeout = setTimeout(function() {
|
||||
Konva.inDblClickWindow = false;
|
||||
}, Konva.dblClickWindow);
|
||||
|
||||
@ -657,12 +658,13 @@
|
||||
|
||||
if (Konva.inDblClickWindow) {
|
||||
fireDblClick = true;
|
||||
Konva.inDblClickWindow = false;
|
||||
clearTimeout(this.dblTimeout);
|
||||
// Konva.inDblClickWindow = false;
|
||||
} else {
|
||||
Konva.inDblClickWindow = true;
|
||||
}
|
||||
|
||||
setTimeout(function() {
|
||||
this.dblTimeout = setTimeout(function() {
|
||||
Konva.inDblClickWindow = false;
|
||||
}, Konva.dblClickWindow);
|
||||
|
||||
|
@ -107,7 +107,10 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Transform constructor
|
||||
* Transform constructor. Transform object is a private class of Konva framework.
|
||||
* In most of the cases you don't need to use it in your app.
|
||||
* But there is a documentation for that class in case you still want
|
||||
* to make some manual calculations.
|
||||
* @constructor
|
||||
* @param {Array} [m] Optional six-element matrix
|
||||
* @memberof Konva
|
||||
@ -487,6 +490,10 @@
|
||||
_isString: function(obj) {
|
||||
return Object.prototype.toString.call(obj) === OBJECT_STRING;
|
||||
},
|
||||
// arrays are objects too
|
||||
isObject: function(val) {
|
||||
return val instanceof Object;
|
||||
},
|
||||
isValidSelector: function(selector) {
|
||||
if (typeof selector !== 'string') {
|
||||
return false;
|
||||
|
@ -66,7 +66,24 @@
|
||||
ctx.closePath();
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
// here is a tricky part
|
||||
// we need to disable dash for arrow pointers
|
||||
var isDashEnabled = this.dashEnabled();
|
||||
if (isDashEnabled) {
|
||||
// manually disable dash for head
|
||||
// it is better not to use setter here,
|
||||
// because it will trigger attr change event
|
||||
this.attrs.dashEnabled = false;
|
||||
ctx.setLineDash([]);
|
||||
}
|
||||
|
||||
ctx.fillStrokeShape(this);
|
||||
|
||||
// restore old value
|
||||
if (isDashEnabled) {
|
||||
this.attrs.dashEnabled = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -222,14 +222,6 @@
|
||||
context.closePath();
|
||||
context.fillStrokeShape(this);
|
||||
},
|
||||
// _useBufferCanvas: function(caching) {
|
||||
// var useIt = Konva.Shape.prototype._useBufferCanvas.call(this, caching);
|
||||
// if (useIt) {
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
// // return isFirefox && this.hasFill() && this.hasShadow();
|
||||
// },
|
||||
setText: function(text) {
|
||||
var str = Konva.Util._isString(text) ? text : (text || '').toString();
|
||||
this._setAttr(TEXT, str);
|
||||
@ -363,14 +355,14 @@
|
||||
var lineWidth = this._getTextWidth(line);
|
||||
if (fixedWidth && lineWidth > maxWidth) {
|
||||
/*
|
||||
* if width is fixed and line does not fit entirely
|
||||
* break the line into multiple fitting lines
|
||||
*/
|
||||
* if width is fixed and line does not fit entirely
|
||||
* break the line into multiple fitting lines
|
||||
*/
|
||||
while (line.length > 0) {
|
||||
/*
|
||||
* use binary search to find the longest substring that
|
||||
* that would fit in the specified width
|
||||
*/
|
||||
* use binary search to find the longest substring that
|
||||
* that would fit in the specified width
|
||||
*/
|
||||
var low = 0,
|
||||
high = line.length,
|
||||
match = '',
|
||||
@ -414,9 +406,9 @@
|
||||
(fixedHeight && currentHeightPx + lineHeightPx > maxHeightPx)
|
||||
) {
|
||||
/*
|
||||
* stop wrapping if wrapping is disabled or if adding
|
||||
* one more line would overflow the fixed height
|
||||
*/
|
||||
* stop wrapping if wrapping is disabled or if adding
|
||||
* one more line would overflow the fixed height
|
||||
*/
|
||||
break;
|
||||
}
|
||||
line = line.slice(low);
|
||||
|
@ -552,31 +552,32 @@
|
||||
}
|
||||
},
|
||||
|
||||
_fitNodeInto: function(attrs) {
|
||||
_fitNodeInto: function(newAttrs) {
|
||||
// waring! in this attrs padding may be included
|
||||
var boundBoxFunc = this.getBoundBoxFunc();
|
||||
if (boundBoxFunc) {
|
||||
var oldAttrs = this._getNodeRect();
|
||||
newAttrs = boundBoxFunc.call(this, oldAttrs, newAttrs);
|
||||
}
|
||||
this._settings = true;
|
||||
var node = this.getNode();
|
||||
if (attrs.rotation !== undefined) {
|
||||
this.getNode().rotation(attrs.rotation);
|
||||
if (newAttrs.rotation !== undefined) {
|
||||
this.getNode().rotation(newAttrs.rotation);
|
||||
}
|
||||
var pure = node.getClientRect({ skipTransform: true });
|
||||
var padding = this.getPadding();
|
||||
var scaleX = (attrs.width - padding * 2) / pure.width;
|
||||
var scaleY = (attrs.height - padding * 2) / pure.height;
|
||||
var scaleX = (newAttrs.width - padding * 2) / pure.width;
|
||||
var scaleY = (newAttrs.height - padding * 2) / pure.height;
|
||||
|
||||
var rotation = Konva.getAngle(node.getRotation());
|
||||
// debugger;
|
||||
var dx = pure.x * scaleX - padding;
|
||||
var dy = pure.y * scaleY - padding;
|
||||
|
||||
// var dxo = node.offsetX() * scaleX;
|
||||
// var dyo = node.offsetY() * scaleY;
|
||||
|
||||
this.getNode().setAttrs({
|
||||
scaleX: scaleX,
|
||||
scaleY: scaleY,
|
||||
x: attrs.x - (dx * Math.cos(rotation) + dy * Math.sin(-rotation)),
|
||||
y: attrs.y - (dy * Math.cos(rotation) + dx * Math.sin(rotation))
|
||||
x: newAttrs.x - (dx * Math.cos(rotation) + dy * Math.sin(-rotation)),
|
||||
y: newAttrs.y - (dy * Math.cos(rotation) + dx * Math.sin(rotation))
|
||||
});
|
||||
this._settings = false;
|
||||
|
||||
@ -669,6 +670,14 @@
|
||||
visible: this.lineEnabled()
|
||||
});
|
||||
},
|
||||
isTransforming: function() {
|
||||
return this._transforming;
|
||||
},
|
||||
stopTransform: function() {
|
||||
if (this._transforming) {
|
||||
this._removeEvents();
|
||||
}
|
||||
},
|
||||
destroy: function() {
|
||||
Konva.Group.prototype.destroy.call(this);
|
||||
this.detach();
|
||||
@ -836,5 +845,7 @@
|
||||
|
||||
Konva.Factory.addOverloadedGetterSetter(Konva.Transformer, 'node');
|
||||
|
||||
Konva.Factory.addGetterSetter(Konva.Transformer, 'boundBoxFunc');
|
||||
|
||||
Konva.Collection.mapMethods(Konva.Transformer);
|
||||
})(Konva);
|
||||
|
@ -392,9 +392,7 @@ suite('MouseEvents', function() {
|
||||
});
|
||||
|
||||
// ======================================================
|
||||
test('modify fill stroke and stroke width on hover with circle', function(
|
||||
done
|
||||
) {
|
||||
test('modify fill stroke and stroke width on hover with circle', function(done) {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer({
|
||||
throttle: 999
|
||||
@ -464,9 +462,7 @@ suite('MouseEvents', function() {
|
||||
});
|
||||
|
||||
// ======================================================
|
||||
test('mousedown mouseup mouseover mouseout mousemove click dblclick', function(
|
||||
done
|
||||
) {
|
||||
test('mousedown mouseup mouseover mouseout mousemove click dblclick', function(done) {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer();
|
||||
var circle = new Konva.Circle({
|
||||
@ -1191,14 +1187,14 @@ suite('MouseEvents', function() {
|
||||
var group22 = new Konva.Group({ name: 'group22' });
|
||||
group21.add(group22);
|
||||
|
||||
var smallRect = new Konva.Rect({
|
||||
var smallShape = new Konva.Rect({
|
||||
x: 50,
|
||||
y: 50,
|
||||
width: 100,
|
||||
height: 100,
|
||||
fill: 'red'
|
||||
});
|
||||
group22.add(smallRect);
|
||||
group22.add(smallShape);
|
||||
stage.draw();
|
||||
|
||||
var group1Mouseenter = 0;
|
||||
@ -1311,7 +1307,7 @@ suite('MouseEvents', function() {
|
||||
});
|
||||
|
||||
// ======================================================
|
||||
test('test dblclick to a wrong target', function () {
|
||||
test('test dblclick to a wrong target', function() {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer();
|
||||
stage.add(layer);
|
||||
@ -1340,13 +1336,13 @@ suite('MouseEvents', function() {
|
||||
var rightRectSingleClick = 0;
|
||||
var rightRectDblClick = 0;
|
||||
|
||||
leftRect.on('click', function () {
|
||||
leftRect.on('click', function() {
|
||||
leftRectSingleClick++;
|
||||
});
|
||||
rightRect.on('click', function () {
|
||||
rightRect.on('click', function() {
|
||||
rightRectSingleClick++;
|
||||
});
|
||||
rightRect.on('dblclick', function () {
|
||||
rightRect.on('dblclick', function() {
|
||||
rightRectDblClick++;
|
||||
});
|
||||
|
||||
@ -1369,11 +1365,7 @@ suite('MouseEvents', function() {
|
||||
y: 50
|
||||
});
|
||||
assert.equal(rightRectSingleClick, 1, 'rightRect trigger a click');
|
||||
assert.equal(
|
||||
rightRectDblClick,
|
||||
0,
|
||||
'rightRect dblClick should not trigger'
|
||||
);
|
||||
assert.equal(rightRectDblClick, 0, 'rightRect dblClick should not trigger');
|
||||
});
|
||||
|
||||
// ======================================================
|
||||
@ -1701,7 +1693,10 @@ suite('MouseEvents', function() {
|
||||
context.fillStrokeShape(this);
|
||||
});
|
||||
|
||||
layer.getHitCanvas().getContext().clear();
|
||||
layer
|
||||
.getHitCanvas()
|
||||
.getContext()
|
||||
.clear();
|
||||
layer.drawHit();
|
||||
|
||||
setTimeout(function() {
|
||||
@ -1787,4 +1782,89 @@ suite('MouseEvents', function() {
|
||||
});
|
||||
assert.equal(shape, circle);
|
||||
});
|
||||
|
||||
it('double click after click should trigger event', function(done) {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer();
|
||||
stage.add(layer);
|
||||
|
||||
var bigRect = new Konva.Rect({
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 200,
|
||||
height: 200,
|
||||
fill: 'yellow'
|
||||
});
|
||||
layer.add(bigRect);
|
||||
|
||||
var smallShape = new Konva.Circle({
|
||||
x: 100,
|
||||
y: 100,
|
||||
width: 100,
|
||||
fill: 'red'
|
||||
});
|
||||
layer.add(smallShape);
|
||||
layer.draw();
|
||||
|
||||
var bigClicks = 0;
|
||||
var smallClicks = 0;
|
||||
var smallDblClicks = 0;
|
||||
|
||||
bigRect.on('click', function() {
|
||||
bigClicks += 1;
|
||||
});
|
||||
|
||||
smallShape.on('click', function() {
|
||||
smallClicks += 1;
|
||||
});
|
||||
|
||||
smallShape.on('dblclick', function() {
|
||||
smallDblClicks += 1;
|
||||
});
|
||||
|
||||
stage.simulateMouseDown({
|
||||
x: 10,
|
||||
y: 10
|
||||
});
|
||||
stage.simulateMouseUp({
|
||||
x: 10,
|
||||
y: 10
|
||||
});
|
||||
|
||||
assert.equal(bigClicks, 1, 'single click on big rect');
|
||||
assert.equal(smallClicks, 0, 'no click on small rect');
|
||||
assert.equal(smallDblClicks, 0, 'no dblclick on small rect');
|
||||
|
||||
setTimeout(function() {
|
||||
stage.simulateMouseDown({
|
||||
x: 100,
|
||||
y: 100
|
||||
});
|
||||
stage.simulateMouseUp({
|
||||
x: 100,
|
||||
y: 100
|
||||
});
|
||||
|
||||
assert.equal(bigClicks, 1, 'single click on big rect');
|
||||
assert.equal(smallClicks, 1, 'single click on small rect');
|
||||
assert.equal(smallDblClicks, 0, 'no dblclick on small rect');
|
||||
|
||||
setTimeout(function() {
|
||||
stage.simulateMouseDown({
|
||||
x: 100,
|
||||
y: 100
|
||||
});
|
||||
stage.simulateMouseUp({
|
||||
x: 100,
|
||||
y: 100
|
||||
});
|
||||
|
||||
assert.equal(bigClicks, 1, 'single click on big rect');
|
||||
assert.equal(smallClicks, 2, 'second click on small rect');
|
||||
assert.equal(smallDblClicks, 1, 'single dblclick on small rect');
|
||||
|
||||
done();
|
||||
}, 200);
|
||||
}, 200);
|
||||
});
|
||||
});
|
||||
|
@ -291,7 +291,7 @@ suite('Container', function() {
|
||||
});
|
||||
|
||||
// ======================================================
|
||||
test('select shape by id and name with findOne', function() {
|
||||
test('select shape with findOne', function() {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer({
|
||||
id: 'myLayer'
|
||||
@ -330,6 +330,10 @@ suite('Container', function() {
|
||||
assert.equal(node, undefined, 'node should be undefined');
|
||||
node = stage.findOne('#myLayer');
|
||||
assert.equal(node, layer, 'node type should be Layer');
|
||||
node = stage.findOne(function(node) {
|
||||
return node.getType() === 'Shape';
|
||||
});
|
||||
assert.equal(node, circle, 'findOne should work with functions');
|
||||
});
|
||||
|
||||
// ======================================================
|
||||
|
@ -35,4 +35,31 @@ suite('Arrow', function() {
|
||||
layer.draw();
|
||||
showHit(layer);
|
||||
});
|
||||
|
||||
test('do not draw dash for head', function() {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer();
|
||||
|
||||
var arrow = new Konva.Arrow({
|
||||
points: [50, 50, 100, 100],
|
||||
stroke: 'red',
|
||||
fill: 'blue',
|
||||
strokeWidth: 5,
|
||||
pointerWidth: 20,
|
||||
pointerLength: 20,
|
||||
dash: [5, 5]
|
||||
});
|
||||
|
||||
layer.add(arrow);
|
||||
stage.add(layer);
|
||||
|
||||
var trace = layer.getContext().getTrace();
|
||||
|
||||
// console.log(trace);
|
||||
|
||||
assert.equal(
|
||||
trace,
|
||||
'clearRect(0,0,578,200);save();transform(1,0,0,1,0,0);beginPath();moveTo(50,50);lineTo(100,100);setLineDash(5,5);lineDashOffset=0;lineWidth=5;strokeStyle=red;stroke();save();beginPath();translate(100,100);rotate(0.785);moveTo(0,0);lineTo(-20,10);lineTo(-20,-10);closePath();restore();setLineDash();fillStyle=blue;fill();lineWidth=5;strokeStyle=red;stroke();restore();'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -309,4 +309,34 @@ suite('Line', function() {
|
||||
layer2.hide();
|
||||
compareLayers(layer, layer2);
|
||||
});
|
||||
|
||||
test('updating points with old mutable array should trigger recalculations', function() {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer();
|
||||
|
||||
var points = [-25, 50, 250, -30, 150, 50];
|
||||
var blob = new Konva.Line({
|
||||
x: 50,
|
||||
y: 50,
|
||||
points: points,
|
||||
stroke: 'blue',
|
||||
strokeWidth: 10,
|
||||
draggable: true,
|
||||
closed: true,
|
||||
tension: 1
|
||||
});
|
||||
|
||||
var tensionPoints = blob.getTensionPoints();
|
||||
points.push(250, 100);
|
||||
blob.setPoints(points);
|
||||
|
||||
layer.add(blob);
|
||||
stage.add(layer);
|
||||
|
||||
assert.equal(
|
||||
tensionPoints === blob.getTensionPoints(),
|
||||
false,
|
||||
'calculated points should change'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -991,4 +991,59 @@ suite('Transformer', function() {
|
||||
});
|
||||
assert.equal(stage.content.style.cursor, 'nwse-resize');
|
||||
});
|
||||
|
||||
test('stopTransform method', function() {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer();
|
||||
stage.add(layer);
|
||||
|
||||
var rect = new Konva.Rect({
|
||||
x: 50,
|
||||
y: 50,
|
||||
draggable: true,
|
||||
width: 100,
|
||||
height: 100,
|
||||
fill: 'yellow'
|
||||
});
|
||||
layer.add(rect);
|
||||
|
||||
var tr = new Konva.Transformer({
|
||||
node: rect
|
||||
});
|
||||
layer.add(tr);
|
||||
layer.draw();
|
||||
|
||||
stage.simulateMouseDown({
|
||||
x: 50,
|
||||
y: 50
|
||||
});
|
||||
|
||||
var top = stage.content.getBoundingClientRect().top;
|
||||
tr._handleMouseMove({
|
||||
target: tr.findOne('.top-left'),
|
||||
clientX: 60,
|
||||
clientY: 60 + top
|
||||
});
|
||||
|
||||
assert.equal(tr.isTransforming(), true);
|
||||
assert.equal(rect.x(), 60);
|
||||
|
||||
var transformend = 0;
|
||||
rect.on('transformend', function() {
|
||||
transformend += 1;
|
||||
});
|
||||
|
||||
tr.stopTransform();
|
||||
|
||||
assert.equal(transformend, 1);
|
||||
|
||||
assert.equal(tr.isTransforming(), false);
|
||||
assert.equal(rect.x(), 60);
|
||||
|
||||
// here is duplicate, because transformer is listening window events
|
||||
stage.simulateMouseUp({
|
||||
x: 100,
|
||||
y: 100
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user