several fixes

This commit is contained in:
Anton Lavrenov
2019-01-21 17:42:02 -05:00
parent 199bbbbff1
commit 7aa3c3238d
13 changed files with 229 additions and 145 deletions

View File

@@ -9,12 +9,13 @@ This project adheres to [Semantic Versioning](http://semver.org/).
* Fixes inconsistent `layer.setSize()` method. Now it has same arguments as any container.
* Full rewrite to Typescript with tons of refactoring and small optimizations. The public API should be 100% the same
* Fixed `patternImage` and `radialGradient` for `Konva.Text`
* `Konva.Util._isObject` is renamed to `Konva.Util._isPlainObject`.
* TODO: changed behavior of `removeId`.
### Removed
* `Konva.Util.addMethods`
* `Konva.Util._removeLastLetter`
### Fixed
* Better mouse support on mobile devices (yes, that is possible to connect mouse to mobile)

143
konva.js
View File

@@ -67,8 +67,8 @@
return;
}
// do we need this warning?
// if (this.ids[id]) {
// Util.warn(
// if (ids[id]) {
// console.warn(
// 'Duplicate id "' +
// id +
// '". Please don not use same id several times. It may break find() method look up.'
@@ -76,11 +76,16 @@
// }
ids[id] = node;
};
// TODO: check node on remove
var _removeId = function (id) {
if (id !== undefined) {
delete ids[id];
var _removeId = function (id, node) {
// node has no id
if (!id) {
return;
}
// another node is registered (possible for duplicate ids)
if (ids[id] !== node) {
return;
}
delete ids[id];
};
var _addName = function (node, name) {
if (name) {
@@ -607,7 +612,7 @@
_isFunction: function (obj) {
return !!(obj && obj.constructor && obj.call && obj.apply);
},
_isObject: function (obj) {
_isPlainObject: function (obj) {
return !!obj && obj.constructor === Object;
},
_isArray: function (obj) {
@@ -878,7 +883,7 @@
_merge: function (o1, o2) {
var retObj = this._clone(o2);
for (var key in o1) {
if (this._isObject(o1[key])) {
if (this._isPlainObject(o1[key])) {
retObj[key] = this._merge(o1[key], retObj[key]);
}
else {
@@ -905,7 +910,7 @@
cloneObject: function (obj) {
var retObj = {};
for (var key in obj) {
if (this._isObject(obj[key])) {
if (this._isPlainObject(obj[key])) {
retObj[key] = this.cloneObject(obj[key]);
}
else if (this._isArray(obj[key])) {
@@ -2651,7 +2656,7 @@
*/
Node.prototype.destroy = function () {
// remove from ids and names hashes
_removeId(this.id());
_removeId(this.id(), this);
// remove all names
var names$$1 = (this.name() || '').split(/\s/g);
for (var i = 0; i < names$$1.length; i++) {
@@ -3164,10 +3169,16 @@
* @returns {Object}
*/
Node.prototype.toObject = function () {
var obj = {}, attrs = this.getAttrs(), key, val, getter, defaultValue;
var obj = {}, attrs = this.getAttrs(), key, val, getter, defaultValue, nonPlainObject;
obj.attrs = {};
for (key in attrs) {
val = attrs[key];
// if value is object and object is not plain
// like class instance, we should skip it and to not inclide
nonPlainObject = Util.isObject(val) && !Util._isPlainObject(val);
if (nonPlainObject) {
continue;
}
getter = typeof this[key] === 'function' && this[key];
// remove attr value so that we can extract the default value from the getter
delete attrs[key];
@@ -3662,7 +3673,7 @@
};
Node.prototype.setId = function (id) {
var oldId = this.id();
_removeId(oldId);
_removeId(oldId, this);
_addId(this, id);
this._setAttr('id', id);
return this;
@@ -7175,8 +7186,8 @@
Factory.addGetterSetter(Shape, 'shadowForStrokeEnabled', true, Validators.getBooleanValidator());
/**
* get/set shadowForStrokeEnabled. Useful for performance optimization.
* You may set `shape.shadowForStrokeEnabled(false)`. In this case stroke will be no draw shadow for stroke.
* Remember if you set `shadowForStrokeEnabled = false` for non closed line - that line with have no shadow!.
* You may set `shape.shadowForStrokeEnabled(false)`. In this case stroke will no effect shadow.
* Remember if you set `shadowForStrokeEnabled = false` for non closed line - that line will have no shadow!.
* Default value is true
* @name Konva.Shape#shadowForStrokeEnabled
* @method
@@ -15581,6 +15592,51 @@
* @returns {Number}
*/
var enableTrace = false;
var traceArrMax = 100;
var listenClickTap = false;
var inDblClickWindow = false;
/**
* Global pixel ratio configuration. KonvaJS automatically detect pixel ratio of current device.
* But you may override such property, if you want to use your value.
* @property pixelRatio
* @default undefined
* @name pixelRatio
* @memberof Konva
* @example
* Konva.pixelRatio = 1;
*/
var pixelRatio = undefined;
/**
* Drag distance property. If you start to drag a node you may want to wait until pointer is moved to some distance from start point,
* only then start dragging. Default is 3px.
* @property dragDistance
* @default 0
* @memberof Konva
* @example
* Konva.dragDistance = 10;
*/
var dragDistance = 3;
/**
* Use degree values for angle properties. You may set this property to false if you want to use radiant values.
* @property angleDeg
* @default true
* @memberof Konva
* @example
* node.rotation(45); // 45 degrees
* Konva.angleDeg = false;
* node.rotation(Math.PI / 2); // PI/2 radian
*/
var angleDeg = true;
/**
* Show different warnings about errors or wrong API usage
* @property showWarnings
* @default true
* @memberof Konva
* @example
* Konva.showWarnings = false;
*/
var showWarnings = true;
/**
* @namespace Filters
* @memberof Konva
@@ -15607,7 +15663,15 @@
Threshold: Threshold
};
var KonvaInternals = ({
var Konva = ({
enableTrace: enableTrace,
traceArrMax: traceArrMax,
listenClickTap: listenClickTap,
inDblClickWindow: inDblClickWindow,
pixelRatio: pixelRatio,
dragDistance: dragDistance,
angleDeg: angleDeg,
showWarnings: showWarnings,
Filters: Filters,
Collection: Collection,
Util: Util,
@@ -15663,53 +15727,6 @@
getGlobalKonva: getGlobalKonva
});
var Konva = KonvaInternals;
Konva.enableTrace = false;
Konva.traceArrMax = 100;
Konva.listenClickTap = false;
Konva.inDblClickWindow = false;
/**
* Global pixel ratio configuration. KonvaJS automatically detect pixel ratio of current device.
* But you may override such property, if you want to use your value.
* @property pixelRatio
* @default undefined
* @name pixelRatio
* @memberof Konva
* @example
* Konva.pixelRatio = 1;
*/
Konva.pixelRatio = undefined;
/**
* Drag distance property. If you start to drag a node you may want to wait until pointer is moved to some distance from start point,
* only then start dragging. Default is 3px.
* @property dragDistance
* @default 0
* @memberof Konva
* @example
* Konva.dragDistance = 10;
*/
Konva.dragDistance = 3;
/**
* Use degree values for angle properties. You may set this property to false if you want to use radiant values.
* @property angleDeg
* @default true
* @memberof Konva
* @example
* node.rotation(45); // 45 degrees
* Konva.angleDeg = false;
* node.rotation(Math.PI / 2); // PI/2 radian
*/
Konva.angleDeg = true;
/**
* Show different warnings about errors or wrong API usage
* @property showWarnings
* @default true
* @memberof Konva
* @example
* Konva.showWarnings = false;
*/
Konva.showWarnings = true;
return KonvaInternals;
return Konva;
}));

4
konva.min.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -19,7 +19,7 @@
"full-build": "npm run build && npm t",
"test": "mocha-headless-chrome -f ./test/runner.html -a disable-web-security",
"prettier": "prettier --write \"src/**/*.js\" \"test/**/*.js\" --single-quote",
"tsc": "tsc || echo \"tsc faild for some file(s).\"",
"tsc": "tsc -d --declarationDir ./types --removeComments --noEmit || echo \"tsc faild for some file(s).\"",
"rollup": "rollup -c",
"compile": "npm run tsc && npm run rollup",
"watch": "rollup -c -w"

View File

@@ -71,8 +71,8 @@ export const _addId = function(node: any, id) {
return;
}
// do we need this warning?
// if (this.ids[id]) {
// Util.warn(
// if (ids[id]) {
// console.warn(
// 'Duplicate id "' +
// id +
// '". Please don not use same id several times. It may break find() method look up.'
@@ -81,11 +81,16 @@ export const _addId = function(node: any, id) {
ids[id] = node;
};
// TODO: check node on remove
export const _removeId = function(id: string) {
if (id !== undefined) {
delete ids[id];
export const _removeId = function(id: string, node: any) {
// node has no id
if (!id) {
return;
}
// another node is registered (possible for duplicate ids)
if (ids[id] !== node) {
return;
}
delete ids[id];
};
export const _addName = function(node: any, name) {

View File

@@ -710,7 +710,7 @@ export abstract class Node {
*/
destroy() {
// remove from ids and names hashes
_removeId(this.id());
_removeId(this.id(), this);
// remove all names
var names = (this.name() || '').split(/\s/g);
@@ -1277,12 +1277,19 @@ export abstract class Node {
key,
val,
getter,
defaultValue;
defaultValue,
nonPlainObject;
obj.attrs = {};
for (key in attrs) {
val = attrs[key];
// if value is object and object is not plain
// like class instance, we should skip it and to not inclide
nonPlainObject = Util.isObject(val) && !Util._isPlainObject(val);
if (nonPlainObject) {
continue;
}
getter = typeof this[key] === 'function' && this[key];
// remove attr value so that we can extract the default value from the getter
delete attrs[key];
@@ -1823,7 +1830,7 @@ export abstract class Node {
setId(id) {
var oldId = this.id();
_removeId(oldId);
_removeId(oldId, this);
_addId(this, id);
this._setAttr('id', id);
return this;

View File

@@ -688,8 +688,8 @@ Factory.addGetterSetter(
/**
* get/set shadowForStrokeEnabled. Useful for performance optimization.
* You may set `shape.shadowForStrokeEnabled(false)`. In this case stroke will be no draw shadow for stroke.
* Remember if you set `shadowForStrokeEnabled = false` for non closed line - that line with have no shadow!.
* You may set `shape.shadowForStrokeEnabled(false)`. In this case stroke will no effect shadow.
* Remember if you set `shadowForStrokeEnabled = false` for non closed line - that line will have no shadow!.
* Default value is true
* @name Konva.Shape#shadowForStrokeEnabled
* @method

View File

@@ -501,7 +501,7 @@ export const Util = {
_isFunction(obj) {
return !!(obj && obj.constructor && obj.call && obj.apply);
},
_isObject(obj) {
_isPlainObject(obj) {
return !!obj && obj.constructor === Object;
},
_isArray(obj) {
@@ -782,7 +782,7 @@ export const Util = {
_merge(o1, o2) {
var retObj = this._clone(o2);
for (var key in o1) {
if (this._isObject(o1[key])) {
if (this._isPlainObject(o1[key])) {
retObj[key] = this._merge(o1[key], retObj[key]);
} else {
retObj[key] = o1[key];
@@ -810,7 +810,7 @@ export const Util = {
cloneObject<Any>(obj: Any): Any {
var retObj: any = {};
for (var key in obj) {
if (this._isObject(obj[key])) {
if (this._isPlainObject(obj[key])) {
retObj[key] = this.cloneObject(obj[key]);
} else if (this._isArray(obj[key])) {
retObj[key] = this.cloneArray(obj[key]);

View File

@@ -1,53 +1,3 @@
import * as KonvaInternals from './internals';
import * as Konva from './internals';
const Konva: any = KonvaInternals;
Konva.enableTrace = false;
Konva.traceArrMax = 100;
Konva.listenClickTap = false;
Konva.inDblClickWindow = false;
/**
* Global pixel ratio configuration. KonvaJS automatically detect pixel ratio of current device.
* But you may override such property, if you want to use your value.
* @property pixelRatio
* @default undefined
* @name pixelRatio
* @memberof Konva
* @example
* Konva.pixelRatio = 1;
*/
Konva.pixelRatio = undefined;
/**
* Drag distance property. If you start to drag a node you may want to wait until pointer is moved to some distance from start point,
* only then start dragging. Default is 3px.
* @property dragDistance
* @default 0
* @memberof Konva
* @example
* Konva.dragDistance = 10;
*/
Konva.dragDistance = 3;
/**
* Use degree values for angle properties. You may set this property to false if you want to use radiant values.
* @property angleDeg
* @default true
* @memberof Konva
* @example
* node.rotation(45); // 45 degrees
* Konva.angleDeg = false;
* node.rotation(Math.PI / 2); // PI/2 radian
*/
Konva.angleDeg = true;
/**
* Show different warnings about errors or wrong API usage
* @property showWarnings
* @default true
* @memberof Konva
* @example
* Konva.showWarnings = false;
*/
Konva.showWarnings = true;
export default KonvaInternals;
export default Konva;

View File

@@ -17,6 +17,56 @@ export { Shape } from './Shape';
export { Animation } from './Animation';
export { Tween, Easings } from './Tween';
export const enableTrace = false;
export const traceArrMax = 100;
export const listenClickTap = false;
export const inDblClickWindow = false;
/**
* Global pixel ratio configuration. KonvaJS automatically detect pixel ratio of current device.
* But you may override such property, if you want to use your value.
* @property pixelRatio
* @default undefined
* @name pixelRatio
* @memberof Konva
* @example
* Konva.pixelRatio = 1;
*/
export const pixelRatio = undefined;
/**
* Drag distance property. If you start to drag a node you may want to wait until pointer is moved to some distance from start point,
* only then start dragging. Default is 3px.
* @property dragDistance
* @default 0
* @memberof Konva
* @example
* Konva.dragDistance = 10;
*/
export const dragDistance = 3;
/**
* Use degree values for angle properties. You may set this property to false if you want to use radiant values.
* @property angleDeg
* @default true
* @memberof Konva
* @example
* node.rotation(45); // 45 degrees
* Konva.angleDeg = false;
* node.rotation(Math.PI / 2); // PI/2 radian
*/
export const angleDeg = true;
/**
* Show different warnings about errors or wrong API usage
* @property showWarnings
* @default true
* @memberof Konva
* @example
* Konva.showWarnings = false;
*/
export const showWarnings = true;
// export default KonvaInternals;
// shapes
export { Arc } from './shapes/Arc';
export { Arrow } from './shapes/Arrow';

View File

@@ -227,11 +227,18 @@ beforeEach(function() {
Konva.UA.mobile = false;
afterEach(function() {
// can we destroy stage?
clearTimeout(Konva.stages[Konva.stages.length - 1].dblTimeout);
// Konva.stages.forEach(function(stage) {
// stage.destroy();
// });
var isFailed = this.currentTest.state == 'failed';
var isManual = this.currentTest.parent.title === 'Manual';
Konva.stages.forEach(function(stage) {
clearTimeout(stage.dblTimeout);
});
if (!isFailed && !isManual) {
Konva.stages.forEach(function(stage) {
stage.destroy();
});
}
});
Konva.Stage.prototype.simulateMouseDown = function(pos) {

View File

@@ -1153,6 +1153,8 @@ suite('Node', function() {
layer.add(circle);
stage.add(layer);
/*
* add custom attr that points to self. The setAttrs method should
* not inifinitely recurse causing a stack overflow
@@ -1166,7 +1168,12 @@ suite('Node', function() {
* methods, such as self, are not serialized, and will therefore avoid
* circular json errors.
*/
// console.log(stage.children);
// return;
var json = stage.toJSON();
// make sure children are ok after json
assert.equal(stage.children[0], layer);
});
// ======================================================
@@ -3047,6 +3054,44 @@ suite('Node', function() {
assert.equal(Konva.shapes[rectColorKey], undefined);
});
// ======================================================
test('destroy should remove only required shape from ids regestry', function() {
var stage = addStage();
var layer = new Konva.Layer();
var circle = new Konva.Circle({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
radius: 70,
fill: 'green',
stroke: 'black',
strokeWidth: 4,
id: 'shape'
});
var rect = new Konva.Rect({
x: 300,
y: 100,
width: 100,
height: 50,
fill: 'purple',
stroke: 'black',
strokeWidth: 4,
id: 'shape'
});
layer.add(circle);
layer.add(rect);
stage.add(layer);
// last shape is registered
assert.equal(Konva.ids.shape, rect);
// destroying circle should not remove rect from regiter
circle.destroy();
assert.equal(Konva.ids.shape, rect);
});
// ======================================================
test('hide stage', function() {
var stage = addStage();

View File

@@ -146,17 +146,17 @@ suite('Line', function() {
context.strokeStyle = 'blue';
context.shadowColor = 'rgba(0,0,0,0.5)';
context.shadowBlur = 20;
context.shadowOffsetX = 10;
context.shadowOffsetY = 10;
context.shadowBlur = 40;
context.shadowOffsetX = 20;
context.shadowOffsetY = 20;
context.moveTo(73, 160);
context.lineTo(340, 23);
context.stroke();
context.fill();
// context.fill();
context.restore();
compareLayerAndCanvas(layer, canvas, 5);
compareLayerAndCanvas(layer, canvas, 50);
var trace = layer.getContext().getTrace();
@@ -309,7 +309,8 @@ suite('Line', function() {
assert.equal(rect.height, 52, 'check height');
});
test('line caching', function() {
test.only('line caching', function() {
// Konva.pixelRatio = 1;
var stage = addStage();
var layer = new Konva.Layer();
var blob = new Konva.Line({
@@ -330,7 +331,8 @@ suite('Line', function() {
stage.add(layer);
stage.add(layer2);
layer2.hide();
compareLayers(layer, layer2);
compareLayers(layer, layer2, 100);
// Konva.pixelRatio = undefined;
});
test('updating points with old mutable array should trigger recalculations', function() {