Merge branch 'master' into fix-unscalable-strokes

This commit is contained in:
MaxGraey 2018-04-11 14:31:43 +03:00
commit 1bcea51047
17 changed files with 419 additions and 132 deletions

View File

@ -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
View File

@ -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
View File

@ -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

File diff suppressed because one or more lines are too long

View File

@ -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

View File

@ -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;

View File

@ -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) {

View File

@ -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);

View File

@ -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;

View File

@ -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;
}
}
};

View File

@ -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);

View File

@ -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);

View File

@ -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);
});
});

View File

@ -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');
});
// ======================================================

View File

@ -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();'
);
});
});

View File

@ -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'
);
});
});

View File

@ -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
});
});
});