type fixes, fix fast layer bug

This commit is contained in:
Anton Lavrenov 2019-02-22 12:46:46 -05:00
parent b251fe3f57
commit aaf0185363
9 changed files with 105 additions and 75 deletions

View File

@ -8,7 +8,7 @@
* Konva JavaScript Framework v3.0.0-0 * Konva JavaScript Framework v3.0.0-0
* http://konvajs.github.io/ * http://konvajs.github.io/
* Licensed under the MIT * Licensed under the MIT
* Date: Wed Feb 20 2019 * Date: Fri Feb 22 2019
* *
* Original work Copyright (C) 2011 - 2013 by Eric Rowell (KineticJS) * Original work Copyright (C) 2011 - 2013 by Eric Rowell (KineticJS)
* Modified work Copyright (C) 2014 - present by Anton Lavrenov (Konva) * Modified work Copyright (C) 2014 - present by Anton Lavrenov (Konva)
@ -569,7 +569,7 @@
whitesmoke: [245, 245, 245], whitesmoke: [245, 245, 245],
yellow: [255, 255, 0], yellow: [255, 255, 0],
yellowgreen: [154, 205, 5] yellowgreen: [154, 205, 5]
}, RGB_REGEX = /rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)/; }, RGB_REGEX = /rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)/, animQueue = [];
/** /**
* @namespace Util * @namespace Util
* @memberof Konva * @memberof Konva
@ -625,13 +625,12 @@
return -1; return -1;
} }
}, },
animQueue: [],
requestAnimFrame: function (callback) { requestAnimFrame: function (callback) {
Util.animQueue.push(callback); animQueue.push(callback);
if (Util.animQueue.length === 1) { if (animQueue.length === 1) {
requestAnimationFrame(function () { requestAnimationFrame(function () {
var queue = Util.animQueue; var queue = animQueue;
Util.animQueue = []; animQueue = [];
queue.forEach(function (cb) { queue.forEach(function (cb) {
cb(); cb();
}); });
@ -678,9 +677,8 @@
* arg can be an image object or image data * arg can be an image object or image data
*/ */
_urlToImage: function (url, callback) { _urlToImage: function (url, callback) {
var imageObj;
// if arg is a string, then it's a data url // if arg is a string, then it's a data url
imageObj = new glob.Image(); var imageObj = new glob.Image();
imageObj.onload = function () { imageObj.onload = function () {
callback(imageObj); callback(imageObj);
}; };
@ -1404,16 +1402,13 @@
*/ */
var Context = /** @class */ (function () { var Context = /** @class */ (function () {
function Context(canvas) { function Context(canvas) {
this.init(canvas);
}
Context.prototype.init = function (canvas) {
this.canvas = canvas; this.canvas = canvas;
this._context = canvas._canvas.getContext('2d'); this._context = canvas._canvas.getContext('2d');
if (getGlobalKonva().enableTrace) { if (getGlobalKonva().enableTrace) {
this.traceArr = []; this.traceArr = [];
this._enableTrace(); this._enableTrace();
} }
}; }
/** /**
* fill shape * fill shape
* @method * @method
@ -4950,16 +4945,14 @@
* @name Konva.Container#removeChildren * @name Konva.Container#removeChildren
*/ */
Container.prototype.removeChildren = function () { Container.prototype.removeChildren = function () {
var children = Collection.toCollection(this.children);
var child; var child;
for (var i = 0; i < children.length; i++) { for (var i = 0; i < this.children.length; i++) {
child = children[i]; child = this.children[i];
// reset parent to prevent many _setChildrenIndices calls // reset parent to prevent many _setChildrenIndices calls
child.parent = null; child.parent = null;
child.index = 0; child.index = 0;
child.remove(); child.remove();
} }
children = null;
this.children = new Collection(); this.children = new Collection();
return this; return this;
}; };
@ -4969,16 +4962,14 @@
* @name Konva.Container#destroyChildren * @name Konva.Container#destroyChildren
*/ */
Container.prototype.destroyChildren = function () { Container.prototype.destroyChildren = function () {
var children = Collection.toCollection(this.children);
var child; var child;
for (var i = 0; i < children.length; i++) { for (var i = 0; i < this.children.length; i++) {
child = children[i]; child = this.children[i];
// reset parent to prevent many _setChildrenIndices calls // reset parent to prevent many _setChildrenIndices calls
child.parent = null; child.parent = null;
child.index = 0; child.index = 0;
child.destroy(); child.destroy();
} }
children = null;
this.children = new Collection(); this.children = new Collection();
return this; return this;
}; };
@ -7342,7 +7333,7 @@
return this; return this;
}; };
Shape.prototype.drawHit = function (can, top, caching) { Shape.prototype.drawHit = function (can, top, caching) {
var layer = this.getLayer(), canvas = can || layer.hitCanvas, context = canvas.getContext(), drawFunc = this.hitFunc() || this.sceneFunc(), cachedCanvas = this._getCanvasCache(), cachedHitCanvas = cachedCanvas && cachedCanvas.hit; var layer = this.getLayer(), canvas = can || layer.hitCanvas, context = canvas && canvas.getContext(), drawFunc = this.hitFunc() || this.sceneFunc(), cachedCanvas = this._getCanvasCache(), cachedHitCanvas = cachedCanvas && cachedCanvas.hit;
if (!this.colorKey) { if (!this.colorKey) {
Util.warn('Looks like your canvas has a destroyed shape in it. Do not reuse shape after you destroyed it. See the shape in logs above. If you want to reuse shape you should call remove() instead of destroy()'); Util.warn('Looks like your canvas has a destroyed shape in it. Do not reuse shape after you destroyed it. See the shape in logs above. If you want to reuse shape you should call remove() instead of destroy()');
} }

4
konva.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -61,16 +61,14 @@ export abstract class Container extends Node {
* @name Konva.Container#removeChildren * @name Konva.Container#removeChildren
*/ */
removeChildren() { removeChildren() {
var children = Collection.toCollection(this.children);
var child; var child;
for (var i = 0; i < children.length; i++) { for (var i = 0; i < this.children.length; i++) {
child = children[i]; child = this.children[i];
// reset parent to prevent many _setChildrenIndices calls // reset parent to prevent many _setChildrenIndices calls
child.parent = null; child.parent = null;
child.index = 0; child.index = 0;
child.remove(); child.remove();
} }
children = null;
this.children = new Collection(); this.children = new Collection();
return this; return this;
} }
@ -80,16 +78,14 @@ export abstract class Container extends Node {
* @name Konva.Container#destroyChildren * @name Konva.Container#destroyChildren
*/ */
destroyChildren() { destroyChildren() {
var children = Collection.toCollection(this.children);
var child; var child;
for (var i = 0; i < children.length; i++) { for (var i = 0; i < this.children.length; i++) {
child = children[i]; child = this.children[i];
// reset parent to prevent many _setChildrenIndices calls // reset parent to prevent many _setChildrenIndices calls
child.parent = null; child.parent = null;
child.index = 0; child.index = 0;
child.destroy(); child.destroy();
} }
children = null;
this.children = new Collection(); this.children = new Collection();
return this; return this;
} }

View File

@ -1,4 +1,4 @@
import { Util, Collection } from './Util'; import { Util } from './Util';
import { getAngle, getGlobalKonva } from './Global'; import { getAngle, getGlobalKonva } from './Global';
import { Canvas } from './Canvas'; import { Canvas } from './Canvas';
@ -90,19 +90,16 @@ export class Context {
_context: CanvasRenderingContext2D; _context: CanvasRenderingContext2D;
traceArr: Array<String>; traceArr: Array<String>;
constructor(canvas) { constructor(canvas: Canvas) {
this.init(canvas);
}
init(canvas) {
this.canvas = canvas; this.canvas = canvas;
this._context = canvas._canvas.getContext('2d'); this._context = canvas._canvas.getContext('2d') as CanvasRenderingContext2D;
if (getGlobalKonva().enableTrace) { if (getGlobalKonva().enableTrace) {
this.traceArr = []; this.traceArr = [];
this._enableTrace(); this._enableTrace();
} }
} }
/** /**
* fill shape * fill shape
* @method * @method

View File

@ -531,7 +531,7 @@ export class Shape extends Node {
drawHit(can, top?, caching?) { drawHit(can, top?, caching?) {
var layer = this.getLayer(), var layer = this.getLayer(),
canvas = can || layer.hitCanvas, canvas = can || layer.hitCanvas,
context = canvas.getContext(), context = canvas && canvas.getContext(),
drawFunc = this.hitFunc() || this.sceneFunc(), drawFunc = this.hitFunc() || this.sceneFunc(),
cachedCanvas = this._getCanvasCache(), cachedCanvas = this._getCanvasCache(),
cachedHitCanvas = cachedCanvas && cachedCanvas.hit; cachedHitCanvas = cachedCanvas && cachedCanvas.hit;

View File

@ -29,11 +29,17 @@ export interface RectConf {
export class Collection<Child extends Node> { export class Collection<Child extends Node> {
[index: number]: Child; [index: number]: Child;
// @ts-ignore
length: number; length: number;
// @ts-ignore
each: (f: Function) => void; each: (f: Function) => void;
// @ts-ignore
toArray: () => Array<any>; toArray: () => Array<any>;
// @ts-ignore
push: (item: Child) => void; push: (item: Child) => void;
// @ts-ignore
unshift: (item: Child) => void; unshift: (item: Child) => void;
// @ts-ignore
splice: (start: number, length: number, replace?: any) => void; splice: (start: number, length: number, replace?: any) => void;
/** /**
@ -42,7 +48,7 @@ export class Collection<Child extends Node> {
* @memberof Konva.Collection * @memberof Konva.Collection
* @param {Array} arr * @param {Array} arr
*/ */
static toCollection(arr) { static toCollection(arr: Array<Node>) {
var collection = new Collection(), var collection = new Collection(),
len = arr.length, len = arr.length,
n; n;
@ -53,7 +59,7 @@ export class Collection<Child extends Node> {
return collection; return collection;
} }
static _mapMethod(methodName) { static _mapMethod(methodName: any) {
Collection.prototype[methodName] = function() { Collection.prototype[methodName] = function() {
var len = this.length, var len = this.length,
i; i;
@ -67,7 +73,7 @@ export class Collection<Child extends Node> {
}; };
} }
static mapMethods = function(constructor) { static mapMethods = function(constructor: Function) {
var prot = constructor.prototype; var prot = constructor.prototype;
for (var methodName in prot) { for (var methodName in prot) {
Collection._mapMethod(methodName); Collection._mapMethod(methodName);
@ -156,7 +162,7 @@ export class Transform {
* @param {Object} point 2D point(x, y) * @param {Object} point 2D point(x, y)
* @returns {Object} 2D point(x, y) * @returns {Object} 2D point(x, y)
*/ */
point(point) { point(point: Point) {
var m = this.m; var m = this.m;
return { return {
x: m[0] * point.x + m[2] * point.y + m[4], x: m[0] * point.x + m[2] * point.y + m[4],
@ -171,7 +177,7 @@ export class Transform {
* @param {Number} y * @param {Number} y
* @returns {Konva.Transform} * @returns {Konva.Transform}
*/ */
translate(x, y) { translate(x: number, y: number) {
this.m[4] += this.m[0] * x + this.m[2] * y; this.m[4] += this.m[0] * x + this.m[2] * y;
this.m[5] += this.m[1] * x + this.m[3] * y; this.m[5] += this.m[1] * x + this.m[3] * y;
return this; return this;
@ -184,7 +190,7 @@ export class Transform {
* @param {Number} sy * @param {Number} sy
* @returns {Konva.Transform} * @returns {Konva.Transform}
*/ */
scale(sx, sy) { scale(sx: number, sy: number) {
this.m[0] *= sx; this.m[0] *= sx;
this.m[1] *= sx; this.m[1] *= sx;
this.m[2] *= sy; this.m[2] *= sy;
@ -198,7 +204,7 @@ export class Transform {
* @param {Number} rad Angle in radians * @param {Number} rad Angle in radians
* @returns {Konva.Transform} * @returns {Konva.Transform}
*/ */
rotate(rad) { rotate(rad: number) {
var c = Math.cos(rad); var c = Math.cos(rad);
var s = Math.sin(rad); var s = Math.sin(rad);
var m11 = this.m[0] * c + this.m[2] * s; var m11 = this.m[0] * c + this.m[2] * s;
@ -231,7 +237,7 @@ export class Transform {
* @param {Number} sy * @param {Number} sy
* @returns {Konva.Transform} * @returns {Konva.Transform}
*/ */
skew(sx, sy) { skew(sx: number, sy: number) {
var m11 = this.m[0] + this.m[2] * sy; var m11 = this.m[0] + this.m[2] * sy;
var m12 = this.m[1] + this.m[3] * sy; var m12 = this.m[1] + this.m[3] * sy;
var m21 = this.m[2] + this.m[0] * sx; var m21 = this.m[2] + this.m[0] * sx;
@ -249,7 +255,7 @@ export class Transform {
* @param {Konva.Transform} matrix * @param {Konva.Transform} matrix
* @returns {Konva.Transform} * @returns {Konva.Transform}
*/ */
multiply(matrix) { multiply(matrix: Transform) {
var m11 = this.m[0] * matrix.m[0] + this.m[2] * matrix.m[1]; var m11 = this.m[0] * matrix.m[0] + this.m[2] * matrix.m[1];
var m12 = this.m[1] * matrix.m[0] + this.m[3] * matrix.m[1]; var m12 = this.m[1] * matrix.m[0] + this.m[3] * matrix.m[1];
@ -304,7 +310,7 @@ export class Transform {
* @returns {Konva.Transform} * @returns {Konva.Transform}
* @author ericdrowell * @author ericdrowell
*/ */
setAbsolutePosition(x, y) { setAbsolutePosition(x: number, y: number) {
var m0 = this.m[0], var m0 = this.m[0],
m1 = this.m[1], m1 = this.m[1],
m2 = this.m[2], m2 = this.m[2],
@ -482,7 +488,8 @@ var OBJECT_ARRAY = '[object Array]',
yellow: [255, 255, 0], yellow: [255, 255, 0],
yellowgreen: [154, 205, 5] yellowgreen: [154, 205, 5]
}, },
RGB_REGEX = /rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)/; RGB_REGEX = /rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)/,
animQueue: Array<Function> = [];
/** /**
* @namespace Util * @namespace Util
@ -492,36 +499,36 @@ export const Util = {
/* /*
* cherry-picked utilities from underscore.js * cherry-picked utilities from underscore.js
*/ */
_isElement(obj) { _isElement(obj: any) {
return !!(obj && obj.nodeType == 1); return !!(obj && obj.nodeType == 1);
}, },
_isFunction(obj) { _isFunction(obj: any) {
return !!(obj && obj.constructor && obj.call && obj.apply); return !!(obj && obj.constructor && obj.call && obj.apply);
}, },
_isPlainObject(obj) { _isPlainObject(obj: any) {
return !!obj && obj.constructor === Object; return !!obj && obj.constructor === Object;
}, },
_isArray(obj) { _isArray(obj: any) {
return Object.prototype.toString.call(obj) === OBJECT_ARRAY; return Object.prototype.toString.call(obj) === OBJECT_ARRAY;
}, },
_isNumber(obj) { _isNumber(obj: any) {
return ( return (
Object.prototype.toString.call(obj) === OBJECT_NUMBER && Object.prototype.toString.call(obj) === OBJECT_NUMBER &&
!isNaN(obj) && !isNaN(obj) &&
isFinite(obj) isFinite(obj)
); );
}, },
_isString(obj) { _isString(obj: any) {
return Object.prototype.toString.call(obj) === OBJECT_STRING; return Object.prototype.toString.call(obj) === OBJECT_STRING;
}, },
_isBoolean(obj) { _isBoolean(obj: any) {
return Object.prototype.toString.call(obj) === OBJECT_BOOLEAN; return Object.prototype.toString.call(obj) === OBJECT_BOOLEAN;
}, },
// arrays are objects too // arrays are objects too
isObject(val) { isObject(val: any) {
return val instanceof Object; return val instanceof Object;
}, },
isValidSelector(selector) { isValidSelector(selector: any) {
if (typeof selector !== 'string') { if (typeof selector !== 'string') {
return false; return false;
} }
@ -532,7 +539,7 @@ export const Util = {
firstChar === firstChar.toUpperCase() firstChar === firstChar.toUpperCase()
); );
}, },
_sign(number) { _sign(number: number) {
if (number === 0) { if (number === 0) {
return 0; return 0;
} }
@ -542,13 +549,13 @@ export const Util = {
return -1; return -1;
} }
}, },
animQueue: [],
requestAnimFrame(callback) { requestAnimFrame(callback: Function) {
Util.animQueue.push(callback); animQueue.push(callback);
if (Util.animQueue.length === 1) { if (animQueue.length === 1) {
requestAnimationFrame(function() { requestAnimationFrame(function() {
const queue = Util.animQueue; const queue = animQueue;
Util.animQueue = []; animQueue = [];
queue.forEach(function(cb) { queue.forEach(function(cb) {
cb(); cb();
}); });
@ -568,7 +575,7 @@ export const Util = {
createImageElement() { createImageElement() {
return document.createElement('img'); return document.createElement('img');
}, },
_isInDocument(el) { _isInDocument(el: any) {
while ((el = el.parentNode)) { while ((el = el.parentNode)) {
if (el == document) { if (el == document) {
return true; return true;
@ -576,7 +583,7 @@ export const Util = {
} }
return false; return false;
}, },
_simplifyArray(arr) { _simplifyArray(arr: []) {
var retArr = [], var retArr = [],
len = arr.length, len = arr.length,
util = Util, util = Util,
@ -599,20 +606,18 @@ export const Util = {
/* /*
* arg can be an image object or image data * arg can be an image object or image data
*/ */
_urlToImage(url, callback) { _urlToImage(url: string, callback: Function) {
var imageObj;
// if arg is a string, then it's a data url // if arg is a string, then it's a data url
imageObj = new glob.Image(); var imageObj = new glob.Image();
imageObj.onload = function() { imageObj.onload = function() {
callback(imageObj); callback(imageObj);
}; };
imageObj.src = url; imageObj.src = url;
}, },
_rgbToHex(r, g, b) { _rgbToHex(r: number, g: number, b: number) {
return ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); return ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}, },
_hexToRgb(hex) { _hexToRgb(hex: string) {
hex = hex.replace(HASH, EMPTY_STRING); hex = hex.replace(HASH, EMPTY_STRING);
var bigint = parseInt(hex, 16); var bigint = parseInt(hex, 16);
return { return {

View File

@ -18,6 +18,26 @@ suite('FastLayer', function() {
stage.add(layer); stage.add(layer);
}); });
test('should not throw on shape render', function() {
var stage = addStage();
var layer = new Konva.FastLayer();
var circle = new Konva.Circle({
x: 100,
y: stage.getHeight() / 2,
radius: 70,
fill: 'green',
stroke: 'black',
strokeWidth: 4
});
layer.add(circle);
stage.add(layer);
circle.draw();
});
test('transform', function() { test('transform', function() {
var stage = addStage(); var stage = addStage();

View File

@ -529,6 +529,26 @@ suite('Stage', function() {
); );
}); });
// ======================================================
test('Should not throw on clip for stage', function() {
// no asserts, because we check throw
var stage = addStage({
clipFunc: () => {}
});
var layer = new Konva.Layer();
var text = new Konva.Text({
x: 0,
y: 0,
text: 'Hello world',
fontSize: 50,
name: 'intersectText'
});
layer.add(text);
stage.add(layer);
});
// ====================================================== // ======================================================
test('scale stage after add layer', function() { test('scale stage after add layer', function() {
var stage = addStage(); var stage = addStage();

View File

@ -6,6 +6,7 @@
"target": "es5", "target": "es5",
"noEmitOnError": true, "noEmitOnError": true,
"lib": ["es2015", "dom"] "lib": ["es2015", "dom"]
// "strict": true
}, },
"include": [ "include": [
"src/index.ts" "src/index.ts"