diff --git a/src/Container.ts b/src/Container.ts index 35f8fc47..73f8c2e9 100644 --- a/src/Container.ts +++ b/src/Container.ts @@ -404,7 +404,7 @@ export abstract class Container extends Node { var layer = this.getLayer(), canvas = can || (layer && layer.getCanvas()), context = canvas && canvas.getContext(), - cachedCanvas = this._cache.canvas, + cachedCanvas = this._getCanvasCache(), cachedSceneCanvas = cachedCanvas && cachedCanvas.scene; if (this.isVisible() || caching) { @@ -423,7 +423,7 @@ export abstract class Container extends Node { var layer = this.getLayer(), canvas = can || (layer && layer.hitCanvas), context = canvas && canvas.getContext(), - cachedCanvas = this._cache.canvas, + cachedCanvas = this._getCanvasCache(), cachedHitCanvas = cachedCanvas && cachedCanvas.hit; if (this.shouldDrawHit(canvas) || caching) { diff --git a/src/Node.ts b/src/Node.ts index a43fc947..c637df3f 100644 --- a/src/Node.ts +++ b/src/Node.ts @@ -70,6 +70,7 @@ type globalCompositeOperationType = var ABSOLUTE_OPACITY = 'absoluteOpacity', ABSOLUTE_TRANSFORM = 'absoluteTransform', ABSOLUTE_SCALE = 'absoluteScale', + CANVAS = 'canvas', CHANGE = 'Change', CHILDREN = 'children', KONVA = 'konva', @@ -116,7 +117,7 @@ export abstract class Node { attrs: any = {}; index = 0; parent: Container = null; - _cache: any = {}; + _cache: Map = new Map(); _lastPos = null; _filterUpToDate = false; @@ -160,21 +161,25 @@ export abstract class Node { /** @lends Konva.Node.prototype */ _clearCache(attr) { if (attr) { - delete this._cache[attr]; + this._cache.delete(attr); } else { - this._cache = {}; + this._cache.clear(); } } _getCache(attr, privateGetter) { - var cache = this._cache[attr]; + var cache = this._cache.get(attr); // if not cached, we need to set it using the private getter method. if (cache === undefined) { - this._cache[attr] = cache = privateGetter.call(this); + cache = privateGetter.call(this); + this._cache.set(attr, cache); } return cache; } + _getCanvasCache() { + return this._cache.get(CANVAS); + } /* * when the logic for a cached result depends on ancestor propagation, use this * method to clear self and children cache @@ -183,7 +188,7 @@ export abstract class Node { this._clearCache(attr); // skip clearing if node is cached with canvas - if (this._cache.canvas) { + if (this._getCanvasCache()) { return; } if (this.children) { @@ -201,7 +206,7 @@ export abstract class Node { * node.clearCache(); */ clearCache() { - delete this._cache.canvas; + this._cache.delete(CANVAS); this._filterUpToDate = false; this._clearSelfAndDescendantCache(); return this; @@ -339,13 +344,13 @@ export abstract class Node { sceneContext.restore(); } - this._cache.canvas = { + this._cache.set(CANVAS, { scene: cachedSceneCanvas, filter: cachedFilterCanvas, hit: cachedHitCanvas, x: x, y: y - }; + }); return this; } @@ -430,7 +435,9 @@ export abstract class Node { context.save(); context._applyOpacity(this); context._applyGlobalCompositeOperation(this); - context.translate(this._cache.canvas.x, this._cache.canvas.y); + + const canvasCache = this._getCanvasCache(); + context.translate(canvasCache.x, canvasCache.y); var cacheCanvas = this._getCachedSceneCanvas(); var ratio = cacheCanvas.pixelRatio; @@ -445,16 +452,16 @@ export abstract class Node { context.restore(); } _drawCachedHitCanvas(context) { - var cachedCanvas = this._cache.canvas, - hitCanvas = cachedCanvas.hit; + var canvasCache = this._getCanvasCache(), + hitCanvas = canvasCache.hit; context.save(); - context.translate(this._cache.canvas.x, this._cache.canvas.y); + context.translate(canvasCache.x, canvasCache.y); context.drawImage(hitCanvas._canvas, 0, 0); context.restore(); } _getCachedSceneCanvas() { var filters = this.filters(), - cachedCanvas = this._cache.canvas, + cachedCanvas = this._getCanvasCache(), sceneCanvas = cachedCanvas.scene, filterCanvas = cachedCanvas.filter, filterContext = filterCanvas.getContext(), diff --git a/src/Shape.ts b/src/Shape.ts index 9070843f..4d835fc3 100644 --- a/src/Shape.ts +++ b/src/Shape.ts @@ -406,7 +406,7 @@ export class Shape extends Node { var layer = this.getLayer(), canvas = can || layer.getCanvas(), context = canvas.getContext(), - cachedCanvas = this._cache.canvas, + cachedCanvas = this._getCanvasCache(), drawFunc = this.sceneFunc(), hasShadow = this.hasShadow(), hasStroke = this.hasStroke(), @@ -530,7 +530,7 @@ export class Shape extends Node { canvas = can || layer.hitCanvas, context = canvas.getContext(), drawFunc = this.hitFunc() || this.sceneFunc(), - cachedCanvas = this._cache.canvas, + cachedCanvas = this._getCanvasCache(), cachedHitCanvas = cachedCanvas && cachedCanvas.hit; if (!this.colorKey) { @@ -581,7 +581,7 @@ export class Shape extends Node { */ drawHitFromCache(alphaThreshold) { var threshold = alphaThreshold || 0, - cachedCanvas = this._cache.canvas, + cachedCanvas = this._getCanvasCache(), sceneCanvas = this._getCachedSceneCanvas(), hitCanvas = cachedCanvas.hit, hitContext = hitCanvas.getContext(), diff --git a/test/unit/Node-cache-test.js b/test/unit/Node-cache-test.js index 67e6ca2f..faea95cd 100644 --- a/test/unit/Node-cache-test.js +++ b/test/unit/Node-cache-test.js @@ -210,8 +210,8 @@ suite('Caching', function() { context.shadowBlur = 10; context.fill(); - showCanvas(rect._cache.canvas.scene._canvas); - showCanvas(rect._cache.canvas.hit._canvas); + showCanvas(rect._getCanvasCache().scene._canvas); + showCanvas(rect._getCanvasCache().hit._canvas); showHit(layer); compareLayerAndCanvas(layer, canvas, 10); Konva.pixelRatio = undefined; @@ -596,7 +596,7 @@ suite('Caching', function() { layer.add(group); stage.add(layer); - assert.equal(circle._cache.canvas, undefined); + assert.equal(circle._getCanvasCache(), undefined); var canvas = createCanvas(); var context = canvas.getContext('2d'); diff --git a/test/unit/Node-test.js b/test/unit/Node-test.js index 7b273ada..1d675cdb 100644 --- a/test/unit/Node-test.js +++ b/test/unit/Node-test.js @@ -150,17 +150,17 @@ suite('Node', function() { strokeWidth: 4 }); - assert.equal(circle._cache.transform, undefined); + assert.equal(circle._cache.get('transform'), undefined); layer.add(circle); stage.add(layer); // transform cache - assert.notEqual(circle._cache.transform, undefined); + assert.notEqual(circle._cache.get('transform'), undefined); circle.setX(100); - assert.equal(circle._cache.transform, undefined); + assert.equal(circle._cache.get('transform'), undefined); layer.draw(); - assert.notEqual(circle._cache.transform, undefined); + assert.notEqual(circle._cache.get('transform'), undefined); }); // ====================================================== @@ -179,15 +179,15 @@ suite('Node', function() { stage.add(layer); // visible cache - assert.equal(circle._cache.visible, true); + assert.equal(circle._cache.get('visible'), true); circle.hide(); - assert.equal(circle._cache.visible, undefined); + assert.equal(circle._cache.get('visible'), undefined); stage.draw(); - assert.equal(circle._cache.visible, false); + assert.equal(circle._cache.get('visible'), false); circle.show(); - assert.equal(circle._cache.visible, undefined); + assert.equal(circle._cache.get('visible'), undefined); layer.draw(); - assert.equal(circle._cache.visible, true); + assert.equal(circle._cache.get('visible'), true); }); // ====================================================== @@ -206,14 +206,14 @@ suite('Node', function() { stage.add(layer); // shadow cache - assert.equal(circle._cache.hasShadow, false); + assert.equal(circle._cache.get('hasShadow'), false); circle.setShadowColor('red'); circle.setShadowOffset(10); - assert.equal(circle._cache.hasShadow, undefined); + assert.equal(circle._cache.get('hasShadow'), undefined); layer.draw(); - assert.equal(circle._cache.hasShadow, true); + assert.equal(circle._cache.get('hasShadow'), true); layer.draw(); - assert.equal(circle._cache.hasShadow, true); + assert.equal(circle._cache.get('hasShadow'), true); }); // ====================================================== @@ -255,11 +255,11 @@ suite('Node', function() { stage.add(layer); // opacity cache - assert.equal(circle._cache.absoluteOpacity, 1); + assert.equal(circle._cache.get('absoluteOpacity'), 1); circle.setOpacity(0.5); - assert.equal(circle._cache.absoluteOpacity, undefined); + assert.equal(circle._cache.get('absoluteOpacity'), undefined); layer.draw(); - assert.equal(circle._cache.absoluteOpacity, 0.5); + assert.equal(circle._cache.get('absoluteOpacity'), 0.5); }); // ====================================================== @@ -282,11 +282,11 @@ suite('Node', function() { // prime the cache circle.isListening(); - assert.equal(circle._cache.listening, true); + assert.equal(circle._cache.get('listening'), true); circle.setListening(false); - assert.equal(circle._cache.listening, undefined); + assert.equal(circle._cache.get('listening'), undefined); circle.isListening(); - assert.equal(circle._cache.listening, false); + assert.equal(circle._cache.get('listening'), false); }); // ====================================================== @@ -306,7 +306,7 @@ suite('Node', function() { // stage cache var st = circle.getStage(); - assert.equal(circle._cache.stage._id, stage._id); + assert.equal(circle._cache.get('stage')._id, stage._id); }); // ====================================================== @@ -3405,7 +3405,7 @@ suite('Node', function() { layer.add(group); stage.add(layer); - assert.equal(circle._cache.canvas, undefined); + assert.equal(circle._getCanvasCache(), undefined); circle .cache({ @@ -3419,19 +3419,19 @@ suite('Node', function() { y: 74 }); - assert.notEqual(circle._cache.canvas.scene, undefined); - assert.notEqual(circle._cache.canvas.hit, undefined); + assert.notEqual(circle._getCanvasCache().scene, undefined); + assert.notEqual(circle._getCanvasCache().hit, undefined); layer.draw(); - //document.body.appendChild(circle._cache.canvas.scene._canvas); - // document.body.appendChild(circle._cache.canvas.hit._canvas); + //document.body.appendChild(circle._getCanvasCache().scene._canvas); + // document.body.appendChild(circle._getCanvasCache().hit._canvas); showHit(layer); //assert.equal(layer.getContext().getTrace(), 'clearRect(0,0,578,200);save();transform(1,0,0,1,74,74);beginPath();arc(0,0,70,0,6.283,false);closePath();fillStyle=green;fill();lineWidth=4;strokeStyle=black;stroke();restore();clearRect(0,0,578,200);save();transform(1,0,0,1,0,0);drawImage([object HTMLCanvasElement],0,0);restore();'); - //assert.equal(circle._cache.canvas.scene.getContext().getTrace(), 'save();translate(74,74);beginPath();arc(0,0,70,0,6.283,false);closePath();fillStyle=green;fill();lineWidth=4;strokeStyle=black;stroke();restore();'); + //assert.equal(circle._getCanvasCache().scene.getContext().getTrace(), 'save();translate(74,74);beginPath();arc(0,0,70,0,6.283,false);closePath();fillStyle=green;fill();lineWidth=4;strokeStyle=black;stroke();restore();'); }); test('cache shape before adding to layer', function() { @@ -3457,7 +3457,7 @@ suite('Node', function() { }); group.add(rect); - assert.equal(rect._cache.canvas, undefined); + assert.equal(rect._getCanvasCache(), undefined); group.cache({ x: 0, y: 0, @@ -3466,8 +3466,8 @@ suite('Node', function() { }); stage.add(layer); - assert(group._cache.canvas.scene); - assert(group._cache.canvas.hit); + assert(group._getCanvasCache().scene); + assert(group._getCanvasCache().hit); layer.add(group); layer.draw(); diff --git a/test/unit/Shape-test.js b/test/unit/Shape-test.js index ae9efad2..9efc4846 100644 --- a/test/unit/Shape-test.js +++ b/test/unit/Shape-test.js @@ -904,7 +904,7 @@ suite('Shape', function() { lion.cache(); - //document.body.appendChild(lion._cache.canvas.hit._canvas); + //document.body.appendChild(lion._getCanvasCache().hit._canvas); lion.drawHitFromCache(); diff --git a/test/unit/filters/Blur-test.js b/test/unit/filters/Blur-test.js index d90b1024..50f18832 100644 --- a/test/unit/filters/Blur-test.js +++ b/test/unit/filters/Blur-test.js @@ -108,7 +108,7 @@ suite('Blur', function() { layer.draw(); - //document.body.appendChild(group._cache.canvas.hit._canvas); + //document.body.appendChild(group._getCanvasCache().hit._canvas); //showHit(layer); }); @@ -293,11 +293,11 @@ suite('Blur', function() { darth.drawHitFromCache(100); layer.draw(); - showCanvas(darth._cache.canvas.hit._canvas); + showCanvas(darth._getCanvasCache().hit._canvas); - //console.log(darth._cache.canvas.hit.getContext().getTrace()); + //console.log(darth._getCanvasCache().hit.getContext().getTrace()); - //assert.equal(darth._cache.canvas.hit.getContext().getTrace(true), 'save();translate();beginPath();rect();closePath();save();fillStyle;fill();restore();restore();clearRect();getImageData();putImageData();'); + //assert.equal(darth._getCanvasCache().hit.getContext().getTrace(true), 'save();translate();beginPath();rect();closePath();save();fillStyle;fill();restore();restore();clearRect();getImageData();putImageData();'); done(); }; diff --git a/test/unit/shapes/Transformer-test.js b/test/unit/shapes/Transformer-test.js index c9844559..c7921ab5 100644 --- a/test/unit/shapes/Transformer-test.js +++ b/test/unit/shapes/Transformer-test.js @@ -1294,7 +1294,7 @@ suite('Transformer', function() { layer.draw(); - assert.equal(tr._cache.transform.m[4], 50); + assert.equal(tr._cache.get('transform').m[4], 50); var rect = new Konva.Rect({ x: 50, @@ -1308,7 +1308,7 @@ suite('Transformer', function() { tr.forceUpdate(); layer.draw(); - assert.equal(tr._cache.transform.m[4], 100); + assert.equal(tr._cache.get('transform').m[4], 100); // tr._fitNodeInto({ // x: 100,