mirror of
https://github.com/konvajs/konva.git
synced 2025-04-05 20:48:28 +08:00
cache + pixelRatio
This commit is contained in:
parent
7d65463e3c
commit
c3511210f2
@ -87,8 +87,9 @@
|
|||||||
* ratio for special situations, or, if you don't want the pixel ratio to be taken into account, you can set it to 1.
|
* ratio for special situations, or, if you don't want the pixel ratio to be taken into account, you can set it to 1.
|
||||||
*/
|
*/
|
||||||
setPixelRatio: function(pixelRatio) {
|
setPixelRatio: function(pixelRatio) {
|
||||||
|
var previousRatio = this.pixelRatio;
|
||||||
this.pixelRatio = pixelRatio;
|
this.pixelRatio = pixelRatio;
|
||||||
this.setSize(this.getWidth(), this.getHeight());
|
this.setSize(this.getWidth() / previousRatio, this.getHeight() / previousRatio);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* set width
|
* set width
|
||||||
@ -100,6 +101,10 @@
|
|||||||
// take into account pixel ratio
|
// take into account pixel ratio
|
||||||
this.width = this._canvas.width = width * this.pixelRatio;
|
this.width = this._canvas.width = width * this.pixelRatio;
|
||||||
this._canvas.style.width = width + 'px';
|
this._canvas.style.width = width + 'px';
|
||||||
|
|
||||||
|
var pixelRatio = this.pixelRatio,
|
||||||
|
_context = this.getContext()._context;
|
||||||
|
_context.scale(pixelRatio, pixelRatio);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* set height
|
* set height
|
||||||
@ -111,6 +116,9 @@
|
|||||||
// take into account pixel ratio
|
// take into account pixel ratio
|
||||||
this.height = this._canvas.height = height * this.pixelRatio;
|
this.height = this._canvas.height = height * this.pixelRatio;
|
||||||
this._canvas.style.height = height + 'px';
|
this._canvas.style.height = height + 'px';
|
||||||
|
var pixelRatio = this.pixelRatio,
|
||||||
|
_context = this.getContext()._context;
|
||||||
|
_context.scale(pixelRatio, pixelRatio);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* get width
|
* get width
|
||||||
@ -177,29 +185,13 @@
|
|||||||
this.setSize(width, height);
|
this.setSize(width, height);
|
||||||
};
|
};
|
||||||
|
|
||||||
Konva.SceneCanvas.prototype = {
|
|
||||||
setWidth: function(width) {
|
|
||||||
var pixelRatio = this.pixelRatio,
|
|
||||||
_context = this.getContext()._context;
|
|
||||||
|
|
||||||
Konva.Canvas.prototype.setWidth.call(this, width);
|
|
||||||
_context.scale(pixelRatio, pixelRatio);
|
|
||||||
},
|
|
||||||
setHeight: function(height) {
|
|
||||||
var pixelRatio = this.pixelRatio,
|
|
||||||
_context = this.getContext()._context;
|
|
||||||
|
|
||||||
Konva.Canvas.prototype.setHeight.call(this, height);
|
|
||||||
_context.scale(pixelRatio, pixelRatio);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Konva.Util.extend(Konva.SceneCanvas, Konva.Canvas);
|
Konva.Util.extend(Konva.SceneCanvas, Konva.Canvas);
|
||||||
|
|
||||||
Konva.HitCanvas = function(config) {
|
Konva.HitCanvas = function(config) {
|
||||||
var conf = config || {};
|
var conf = config || {};
|
||||||
var width = conf.width || 0,
|
var width = conf.width || 0,
|
||||||
height = conf.height || 0;
|
height = conf.height || 0;
|
||||||
|
|
||||||
Konva.Canvas.call(this, conf);
|
Konva.Canvas.call(this, conf);
|
||||||
this.context = new Konva.HitContext(this);
|
this.context = new Konva.HitContext(this);
|
||||||
this.setSize(width, height);
|
this.setSize(width, height);
|
||||||
|
@ -201,7 +201,7 @@
|
|||||||
this.clearRect(bounds.x || 0, bounds.y || 0, bounds.width || 0, bounds.height || 0);
|
this.clearRect(bounds.x || 0, bounds.y || 0, bounds.width || 0, bounds.height || 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
|
this.clearRect(0, 0, canvas.getWidth() / canvas.pixelRatio, canvas.getHeight() / canvas.pixelRatio);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_applyLineCap: function(shape) {
|
_applyLineCap: function(shape) {
|
||||||
@ -381,7 +381,11 @@
|
|||||||
that[methodName] = function() {
|
that[methodName] = function() {
|
||||||
args = _simplifyArray(Array.prototype.slice.call(arguments, 0));
|
args = _simplifyArray(Array.prototype.slice.call(arguments, 0));
|
||||||
ret = origMethod.apply(that, arguments);
|
ret = origMethod.apply(that, arguments);
|
||||||
|
|
||||||
|
if (methodName === 'clearRect') {
|
||||||
|
args[2] = args[2] / that.canvas.getPixelRatio();
|
||||||
|
args[3] = args[3] / that.canvas.getPixelRatio();
|
||||||
|
}
|
||||||
that._trace({
|
that._trace({
|
||||||
method: methodName,
|
method: methodName,
|
||||||
args: args
|
args: args
|
||||||
|
@ -29,7 +29,9 @@
|
|||||||
____init: function(config) {
|
____init: function(config) {
|
||||||
this.nodeType = 'Layer';
|
this.nodeType = 'Layer';
|
||||||
this.canvas = new Konva.SceneCanvas();
|
this.canvas = new Konva.SceneCanvas();
|
||||||
this.hitCanvas = new Konva.HitCanvas();
|
this.hitCanvas = new Konva.HitCanvas({
|
||||||
|
pixelRatio : 1
|
||||||
|
});
|
||||||
// call super constructor
|
// call super constructor
|
||||||
Konva.BaseLayer.call(this, config);
|
Konva.BaseLayer.call(this, config);
|
||||||
},
|
},
|
||||||
@ -111,10 +113,10 @@
|
|||||||
];
|
];
|
||||||
},
|
},
|
||||||
_getIntersection: function(pos) {
|
_getIntersection: function(pos) {
|
||||||
var p = this.hitCanvas.context.getImageData(pos.x, pos.y, 1, 1).data,
|
var ratio = this.hitCanvas.pixelRatio;
|
||||||
|
var p = this.hitCanvas.context.getImageData(Math.round(pos.x * ratio), Math.round(pos.y * ratio), 1, 1).data,
|
||||||
p3 = p[3],
|
p3 = p[3],
|
||||||
colorKey, shape;
|
colorKey, shape;
|
||||||
|
|
||||||
// fully opaque pixel
|
// fully opaque pixel
|
||||||
if(p3 === 255) {
|
if(p3 === 255) {
|
||||||
colorKey = Konva.Util._rgbToHex(p[0], p[1], p[2]);
|
colorKey = Konva.Util._rgbToHex(p[0], p[1], p[2]);
|
||||||
|
10
src/Node.js
10
src/Node.js
@ -165,16 +165,15 @@
|
|||||||
|
|
||||||
|
|
||||||
var cachedSceneCanvas = new Konva.SceneCanvas({
|
var cachedSceneCanvas = new Konva.SceneCanvas({
|
||||||
pixelRatio: 1,
|
|
||||||
width: width,
|
width: width,
|
||||||
height: height
|
height: height
|
||||||
}),
|
}),
|
||||||
cachedFilterCanvas = new Konva.SceneCanvas({
|
cachedFilterCanvas = new Konva.SceneCanvas({
|
||||||
pixelRatio: 1,
|
|
||||||
width: width,
|
width: width,
|
||||||
height: height
|
height: height
|
||||||
}),
|
}),
|
||||||
cachedHitCanvas = new Konva.HitCanvas({
|
cachedHitCanvas = new Konva.HitCanvas({
|
||||||
|
pixelRatio : 1,
|
||||||
width: width,
|
width: width,
|
||||||
height: height
|
height: height
|
||||||
}),
|
}),
|
||||||
@ -264,13 +263,16 @@
|
|||||||
},
|
},
|
||||||
_drawCachedSceneCanvas: function(context) {
|
_drawCachedSceneCanvas: function(context) {
|
||||||
context.save();
|
context.save();
|
||||||
|
context._applyOpacity(this);
|
||||||
context.translate(
|
context.translate(
|
||||||
this._cache.canvas.x,
|
this._cache.canvas.x,
|
||||||
this._cache.canvas.y
|
this._cache.canvas.y
|
||||||
);
|
);
|
||||||
|
|
||||||
context.drawImage(this._getCachedSceneCanvas()._canvas, 0, 0);
|
var cacheCanvas = this._getCachedSceneCanvas();
|
||||||
|
var ratio = context.canvas.pixelRatio;
|
||||||
|
|
||||||
|
context.drawImage(cacheCanvas._canvas, 0, 0, cacheCanvas.width / ratio, cacheCanvas.height /ratio);
|
||||||
context.restore();
|
context.restore();
|
||||||
},
|
},
|
||||||
_drawCachedHitCanvas: function(context) {
|
_drawCachedHitCanvas: function(context) {
|
||||||
|
59
src/Shape.js
59
src/Shape.js
@ -142,8 +142,8 @@
|
|||||||
Konva.Node.prototype.destroy.call(this);
|
Konva.Node.prototype.destroy.call(this);
|
||||||
delete Konva.shapes[this.colorKey];
|
delete Konva.shapes[this.colorKey];
|
||||||
},
|
},
|
||||||
_useBufferCanvas: function() {
|
_useBufferCanvas: function(caching) {
|
||||||
return (this.perfectDrawEnabled() && (this.getAbsoluteOpacity() !== 1) && this.hasFill() && this.hasStroke() && this.getStage()) ||
|
return !caching && (this.perfectDrawEnabled() && (this.getAbsoluteOpacity() !== 1) && this.hasFill() && this.hasStroke() && this.getStage()) ||
|
||||||
(this.perfectDrawEnabled() && this.hasShadow() && (this.getAbsoluteOpacity() !== 1) && this.hasFill() && this.hasStroke() && this.getStage());
|
(this.perfectDrawEnabled() && this.hasShadow() && (this.getAbsoluteOpacity() !== 1) && this.hasFill() && this.hasStroke() && this.getStage());
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@ -183,9 +183,17 @@
|
|||||||
|
|
||||||
var width = preWidth + blurRadius * 2;
|
var width = preWidth + blurRadius * 2;
|
||||||
var height = preHeight + blurRadius * 2;
|
var height = preHeight + blurRadius * 2;
|
||||||
|
|
||||||
|
// if stroke, for example = 3
|
||||||
|
// we need to set x to 1.5, but after Math.round it will be 2
|
||||||
|
// as we have additional offset we need to increase width and height by 1 pixel
|
||||||
|
var roundingOffset = 0;
|
||||||
|
if (Math.round(strokeWidth / 2) !== strokeWidth / 2) {
|
||||||
|
roundingOffset = 1;
|
||||||
|
}
|
||||||
var rect = {
|
var rect = {
|
||||||
width : width,
|
width : width + roundingOffset,
|
||||||
height : height,
|
height : height + roundingOffset,
|
||||||
x : -Math.round(strokeWidth / 2 + blurRadius) + Math.min(shadowOffsetX, 0) + fillRect.x,
|
x : -Math.round(strokeWidth / 2 + blurRadius) + Math.min(shadowOffsetX, 0) + fillRect.x,
|
||||||
y : -Math.round(strokeWidth / 2 + blurRadius) + Math.min(shadowOffsetY, 0) + fillRect.y
|
y : -Math.round(strokeWidth / 2 + blurRadius) + Math.min(shadowOffsetY, 0) + fillRect.y
|
||||||
};
|
};
|
||||||
@ -214,7 +222,7 @@
|
|||||||
else if (drawFunc) {
|
else if (drawFunc) {
|
||||||
context.save();
|
context.save();
|
||||||
// if buffer canvas is needed
|
// if buffer canvas is needed
|
||||||
if (this._useBufferCanvas()) {
|
if (this._useBufferCanvas(caching)) {
|
||||||
stage = this.getStage();
|
stage = this.getStage();
|
||||||
bufferCanvas = stage.bufferCanvas;
|
bufferCanvas = stage.bufferCanvas;
|
||||||
bufferContext = bufferCanvas.getContext();
|
bufferContext = bufferCanvas.getContext();
|
||||||
@ -222,35 +230,24 @@
|
|||||||
bufferContext.save();
|
bufferContext.save();
|
||||||
bufferContext._applyLineJoin(this);
|
bufferContext._applyLineJoin(this);
|
||||||
// layer might be undefined if we are using cache before adding to layer
|
// layer might be undefined if we are using cache before adding to layer
|
||||||
if (layer) {
|
if (!caching) {
|
||||||
layer._applyTransform(this, bufferContext, top);
|
if (layer) {
|
||||||
} else {
|
layer._applyTransform(this, bufferContext, top);
|
||||||
var m = this.getAbsoluteTransform(top).getMatrix();
|
} else {
|
||||||
context.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
|
var m = this.getAbsoluteTransform(top).getMatrix();
|
||||||
|
context.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
drawFunc.call(this, bufferContext);
|
drawFunc.call(this, bufferContext);
|
||||||
bufferContext.restore();
|
bufferContext.restore();
|
||||||
|
|
||||||
if (hasShadow && !canvas.hitCanvas) {
|
if (hasShadow && !canvas.hitCanvas) {
|
||||||
// if (this.getShadowBlur()) {
|
|
||||||
// context.save();
|
|
||||||
//// bufferContext.clear();
|
|
||||||
// var buffer2 = stage.bufferCanvas2;
|
|
||||||
// buffer2.getContext()._applyShadow(this);
|
|
||||||
// buffer2.getContext().drawImage(bufferCanvas._canvas);
|
|
||||||
// buffer2.getContext().fill();
|
|
||||||
//// drawFunc.call(this, bufferContext);
|
|
||||||
//// context._applyOpacity(this);
|
|
||||||
// context.drawImage(buffer2._canvas, 0, 0);
|
|
||||||
// context.restore();
|
|
||||||
// } else {
|
|
||||||
context.save();
|
context.save();
|
||||||
context._applyShadow(this);
|
context._applyShadow(this);
|
||||||
context._applyOpacity(this);
|
context._applyOpacity(this);
|
||||||
context.drawImage(bufferCanvas._canvas, 0, 0);
|
context.drawImage(bufferCanvas._canvas, 0, 0);
|
||||||
context.restore();
|
context.restore();
|
||||||
// }
|
|
||||||
} else {
|
} else {
|
||||||
context._applyOpacity(this);
|
context._applyOpacity(this);
|
||||||
context.drawImage(bufferCanvas._canvas, 0, 0);
|
context.drawImage(bufferCanvas._canvas, 0, 0);
|
||||||
@ -272,24 +269,30 @@
|
|||||||
if (hasShadow && hasStroke && !canvas.hitCanvas) {
|
if (hasShadow && hasStroke && !canvas.hitCanvas) {
|
||||||
context.save();
|
context.save();
|
||||||
// apply shadow
|
// apply shadow
|
||||||
context._applyOpacity(this);
|
if (!caching) {
|
||||||
|
context._applyOpacity(this);
|
||||||
|
}
|
||||||
context._applyShadow(this);
|
context._applyShadow(this);
|
||||||
drawFunc.call(this, context);
|
drawFunc.call(this, context);
|
||||||
context.restore();
|
context.restore();
|
||||||
// if shape has stroke we need to redraw shape
|
// if shape has stroke we need to redraw shape
|
||||||
// otherwise we will see shadow under stroke (and over fill)
|
// otherwise we will see a shadow under stroke (and over fill)
|
||||||
// but I think is is unexpected behavior
|
// but I think this is unexpected behavior
|
||||||
if (this.hasFill() && this.getShadowForStrokeEnabled()) {
|
if (this.hasFill() && this.getShadowForStrokeEnabled()) {
|
||||||
drawFunc.call(this, context);
|
drawFunc.call(this, context);
|
||||||
}
|
}
|
||||||
} else if (hasShadow && !canvas.hitCanvas) {
|
} else if (hasShadow && !canvas.hitCanvas) {
|
||||||
context.save();
|
context.save();
|
||||||
context._applyOpacity(this);
|
if (!caching) {
|
||||||
|
context._applyOpacity(this);
|
||||||
|
}
|
||||||
context._applyShadow(this);
|
context._applyShadow(this);
|
||||||
drawFunc.call(this, context);
|
drawFunc.call(this, context);
|
||||||
context.restore();
|
context.restore();
|
||||||
} else {
|
} else {
|
||||||
context._applyOpacity(this);
|
if (!caching) {
|
||||||
|
context._applyOpacity(this);
|
||||||
|
}
|
||||||
drawFunc.call(this, context);
|
drawFunc.call(this, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -473,7 +473,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
_mouseup: function(evt) {
|
_mouseup: function(evt) {
|
||||||
|
|
||||||
// workaround for mobile IE to force touch event when unhandled pointer event elevates into a mouse event
|
// workaround for mobile IE to force touch event when unhandled pointer event elevates into a mouse event
|
||||||
if (Konva.UA.ieMobile) {
|
if (Konva.UA.ieMobile) {
|
||||||
return this._touchend(evt);
|
return this._touchend(evt);
|
||||||
|
@ -168,10 +168,10 @@
|
|||||||
maxY = Math.max(maxY, y);
|
maxY = Math.max(maxY, y);
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
x : minX,
|
x : Math.round(minX),
|
||||||
y : minY,
|
y : Math.round(minY),
|
||||||
width : maxX - minX,
|
width : Math.round(maxX - minX),
|
||||||
height : maxY - minY
|
height : Math.round(maxY - minY)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1311,4 +1311,40 @@ suite('MouseEvents', function() {
|
|||||||
}, 20);
|
}, 20);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('change ratio for hit graph', function() {
|
||||||
|
var stage = addStage();
|
||||||
|
var layer = new Konva.Layer();
|
||||||
|
var circle = new Konva.Circle({
|
||||||
|
x : stage.width() / 2,
|
||||||
|
y : stage.height() / 2,
|
||||||
|
radius : 50,
|
||||||
|
stroke : 'black',
|
||||||
|
fill : 'red',
|
||||||
|
strokeWidth : 5,
|
||||||
|
draggable : true
|
||||||
|
});
|
||||||
|
|
||||||
|
layer.add(circle);
|
||||||
|
stage.add(layer);
|
||||||
|
|
||||||
|
layer.getHitCanvas().setPixelRatio(0.5);
|
||||||
|
|
||||||
|
layer.draw();
|
||||||
|
var shape = layer.getIntersection({
|
||||||
|
x : stage.width() / 2 - 55,
|
||||||
|
y : stage.height() / 2 - 55
|
||||||
|
});
|
||||||
|
assert.equal(!!shape, false, 'no shape here');
|
||||||
|
shape = layer.getIntersection({
|
||||||
|
x : stage.width() / 2 + 55,
|
||||||
|
y : stage.height() / 2 + 55
|
||||||
|
});
|
||||||
|
assert.equal(!!shape, false, 'no shape here');
|
||||||
|
shape = layer.getIntersection({
|
||||||
|
x : stage.width() / 2,
|
||||||
|
y : stage.height() / 2
|
||||||
|
});
|
||||||
|
assert.equal(shape, circle);
|
||||||
|
});
|
||||||
});
|
});
|
@ -265,6 +265,42 @@ suite('Manual', function() {
|
|||||||
layer.add(rect, text);
|
layer.add(rect, text);
|
||||||
|
|
||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('change hit graph ratio', function() {
|
||||||
|
var stage = addStage();
|
||||||
|
var layer = new Konva.Layer();
|
||||||
|
var circle = new Konva.Circle({
|
||||||
|
x : stage.width() / 2,
|
||||||
|
y : stage.height() / 2,
|
||||||
|
radius : 50,
|
||||||
|
stroke : 'black',
|
||||||
|
fill : 'red',
|
||||||
|
strokeWidth : 5,
|
||||||
|
draggable : true
|
||||||
|
});
|
||||||
|
|
||||||
|
var text = new Konva.Text({
|
||||||
|
text : "click on circle to decrease hit grpah retion"
|
||||||
|
});
|
||||||
|
|
||||||
|
layer.add(circle, text);
|
||||||
|
stage.add(layer);
|
||||||
|
showHit(layer);
|
||||||
|
|
||||||
|
circle.on('mouseenter', function() {
|
||||||
|
document.body.style.cursor = 'pointer';
|
||||||
|
});
|
||||||
|
|
||||||
|
circle.on('mouseleave', function() {
|
||||||
|
document.body.style.cursor = 'default';
|
||||||
|
});
|
||||||
|
|
||||||
|
circle.on('click', function() {
|
||||||
|
var ratio = layer.getHitCanvas().getPixelRatio() * 0.8;
|
||||||
|
console.log('new ratio', ratio);
|
||||||
|
layer.getHitCanvas().setPixelRatio(ratio);
|
||||||
|
layer.draw();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
70
test/performance/hit-ratio.html
Normal file
70
test/performance/hit-ratio.html
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
canvas {
|
||||||
|
border: 1px solid #9C9898;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="container"></div>
|
||||||
|
|
||||||
|
<script src="../../dist/konva-dev.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var stage = new Konva.Stage({
|
||||||
|
container: 'container',
|
||||||
|
width: 500,
|
||||||
|
height: 250
|
||||||
|
});
|
||||||
|
var layer = new Konva.Layer();
|
||||||
|
|
||||||
|
for(var j =0; j < 20; j++) {
|
||||||
|
layer.add(new Konva.Circle({
|
||||||
|
x : stage.width() * Math.random(),
|
||||||
|
y : stage.height() * Math.random(),
|
||||||
|
radius : 50,
|
||||||
|
stroke : 'black',
|
||||||
|
fill : Konva.Util.getRandomColor(),
|
||||||
|
strokeWidth : 5,
|
||||||
|
draggable : true
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
stage.add(layer);
|
||||||
|
var i, count = 500, start;
|
||||||
|
|
||||||
|
var start = Date.now();
|
||||||
|
for(i = 0; i< count; i++) {
|
||||||
|
layer.draw();
|
||||||
|
}
|
||||||
|
var defTime = Date.now() - start;
|
||||||
|
|
||||||
|
layer.getHitCanvas().setPixelRatio(1);
|
||||||
|
// layer.getCanvas().setPixelRatio(1);
|
||||||
|
layer.draw();
|
||||||
|
|
||||||
|
start = Date.now();
|
||||||
|
for(i = 0; i< count; i++) {
|
||||||
|
layer.draw();
|
||||||
|
}
|
||||||
|
var time1 = Date.now() - start;
|
||||||
|
|
||||||
|
layer.getHitCanvas().setPixelRatio(0.2);
|
||||||
|
// layer.getCanvas().setPixelRatio(0.5);
|
||||||
|
layer.draw();
|
||||||
|
|
||||||
|
start = Date.now();
|
||||||
|
for(i = 0; i< count; i++) {
|
||||||
|
layer.draw();
|
||||||
|
}
|
||||||
|
var time05 = Date.now() - start;
|
||||||
|
alert('def ' + defTime + ', 1 ration ' + time1 + ', 05 ration ' + time05)
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -65,6 +65,7 @@ function init() {
|
|||||||
|
|
||||||
Konva.enableTrace = true;
|
Konva.enableTrace = true;
|
||||||
Konva.showWarnings = true;
|
Konva.showWarnings = true;
|
||||||
|
//Konva.pixelRatio = 2;
|
||||||
|
|
||||||
function addStats() {
|
function addStats() {
|
||||||
stats = new Stats();
|
stats = new Stats();
|
||||||
@ -103,8 +104,10 @@ function addStage() {
|
|||||||
|
|
||||||
function createCanvas() {
|
function createCanvas() {
|
||||||
var canvas = document.createElement('canvas');
|
var canvas = document.createElement('canvas');
|
||||||
canvas.width = 578;
|
var ratio = (Konva.pixelRatio || window.devicePixelRatio);
|
||||||
canvas.height = 200;
|
canvas.width = 578 * ratio;
|
||||||
|
canvas.height = 200 * ratio;
|
||||||
|
canvas.getContext('2d').scale(ratio, ratio);
|
||||||
return canvas;
|
return canvas;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,4 +215,12 @@ beforeEach(function(){
|
|||||||
Konva.DD.node = undefined;
|
Konva.DD.node = undefined;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Konva.UA.mobile = false;
|
||||||
|
|
||||||
|
afterEach(function(){
|
||||||
|
// Konva.stages.forEach(function(stage) {
|
||||||
|
// stage.destroy();
|
||||||
|
// });
|
||||||
|
});
|
||||||
|
|
||||||
init();
|
init();
|
@ -6,12 +6,13 @@ suite('Canvas', function() {
|
|||||||
var layer = new Konva.Layer();
|
var layer = new Konva.Layer();
|
||||||
|
|
||||||
var circle = new Konva.Circle({
|
var circle = new Konva.Circle({
|
||||||
x: 578/2,
|
x: 100,
|
||||||
y: 100,
|
y: 70,
|
||||||
radius: 70,
|
radius: 70,
|
||||||
fill: 'green',
|
fill: 'green',
|
||||||
stroke: 'blue',
|
stroke: 'blue',
|
||||||
strokeWidth: 4
|
strokeWidth: 4,
|
||||||
|
draggable : true
|
||||||
});
|
});
|
||||||
|
|
||||||
layer.add(circle);
|
layer.add(circle);
|
||||||
@ -22,6 +23,7 @@ suite('Canvas', function() {
|
|||||||
stage.setHeight(100);
|
stage.setHeight(100);
|
||||||
|
|
||||||
stage.draw();
|
stage.draw();
|
||||||
|
assert.equal(layer.getCanvas().getPixelRatio(), Konva.pixelRatio || window.devicePixelRatio || 1);
|
||||||
|
|
||||||
layer.getCanvas().setPixelRatio(1);
|
layer.getCanvas().setPixelRatio(1);
|
||||||
assert.equal(layer.getCanvas().getPixelRatio(), 1);
|
assert.equal(layer.getCanvas().getPixelRatio(), 1);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
suite('Caching', function() {
|
suite('Caching', function() {
|
||||||
|
this.timeout(5000);
|
||||||
// CACHING SHAPE
|
// CACHING SHAPE
|
||||||
|
|
||||||
test('cache simple rectangle', function() {
|
test('cache simple rectangle', function() {
|
||||||
@ -12,7 +12,8 @@ suite('Caching', function() {
|
|||||||
y: 50,
|
y: 50,
|
||||||
width: 100,
|
width: 100,
|
||||||
height: 50,
|
height: 50,
|
||||||
fill: 'green'
|
fill: 'green',
|
||||||
|
draggable : true
|
||||||
});
|
});
|
||||||
rect.cache();
|
rect.cache();
|
||||||
|
|
||||||
@ -26,8 +27,10 @@ suite('Caching', function() {
|
|||||||
context.closePath();
|
context.closePath();
|
||||||
context.fillStyle = 'green';
|
context.fillStyle = 'green';
|
||||||
context.fill();
|
context.fill();
|
||||||
|
|
||||||
compareLayerAndCanvas(layer, canvas, 10);
|
compareLayerAndCanvas(layer, canvas, 10);
|
||||||
compareSceneAndHit(layer);
|
cloneAndCompareLayer(layer);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('cache simple rectangle with transform', function() {
|
test('cache simple rectangle with transform', function() {
|
||||||
@ -60,8 +63,8 @@ suite('Caching', function() {
|
|||||||
context.fill();
|
context.fill();
|
||||||
|
|
||||||
if (!window.mochaPhantomJS) {
|
if (!window.mochaPhantomJS) {
|
||||||
compareLayerAndCanvas(layer, canvas, 40);
|
compareLayerAndCanvas(layer, canvas, 200);
|
||||||
compareSceneAndHit(layer);
|
cloneAndCompareLayer(layer, 150);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -94,8 +97,89 @@ suite('Caching', function() {
|
|||||||
context.fill();
|
context.fill();
|
||||||
context.lineWidth = 20;
|
context.lineWidth = 20;
|
||||||
context.stroke();
|
context.stroke();
|
||||||
compareLayerAndCanvas(layer, canvas, 10);
|
compareLayerAndCanvas(layer, canvas, 50);
|
||||||
compareSceneAndHit(layer);
|
cloneAndCompareLayer(layer, 50);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
test.skip('cache rectangle with fill and opacity', function() {
|
||||||
|
var stage = addStage();
|
||||||
|
|
||||||
|
var layer = new Konva.Layer();
|
||||||
|
|
||||||
|
var rect = new Konva.Rect({
|
||||||
|
x: 100,
|
||||||
|
y: 50,
|
||||||
|
width: 100,
|
||||||
|
height: 50,
|
||||||
|
fill: 'green',
|
||||||
|
opacity : 0.5
|
||||||
|
});
|
||||||
|
rect.cache();
|
||||||
|
rect.opacity(0.3);
|
||||||
|
|
||||||
|
layer.add(rect);
|
||||||
|
stage.add(layer);
|
||||||
|
|
||||||
|
var canvas = createCanvas();
|
||||||
|
var context = canvas.getContext('2d');
|
||||||
|
context.globalAlpha = 0.3;
|
||||||
|
context.beginPath();
|
||||||
|
context.rect(100, 50, 100, 50);
|
||||||
|
context.closePath();
|
||||||
|
context.fillStyle = 'green';
|
||||||
|
context.fill();
|
||||||
|
compareLayerAndCanvas(layer, canvas, 5);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('cache rectangle with fill, stroke opacity', function() {
|
||||||
|
var stage = addStage();
|
||||||
|
|
||||||
|
var layer = new Konva.Layer();
|
||||||
|
|
||||||
|
var rect = new Konva.Rect({
|
||||||
|
x: 100,
|
||||||
|
y: 50,
|
||||||
|
width: 100,
|
||||||
|
height: 50,
|
||||||
|
fill: 'green',
|
||||||
|
opacity : 0.5,
|
||||||
|
stroke : 'black',
|
||||||
|
strokeWidth : 10
|
||||||
|
});
|
||||||
|
rect.cache();
|
||||||
|
rect.opacity(0.3);
|
||||||
|
|
||||||
|
layer.add(rect);
|
||||||
|
stage.add(layer);
|
||||||
|
|
||||||
|
cloneAndCompareLayer(layer, 100);
|
||||||
|
});
|
||||||
|
|
||||||
|
test.skip('cache rectangle with fill, shadow and opacity', function() {
|
||||||
|
var stage = addStage();
|
||||||
|
|
||||||
|
var layer = new Konva.Layer();
|
||||||
|
|
||||||
|
var rect = new Konva.Rect({
|
||||||
|
x: 100,
|
||||||
|
y: 50,
|
||||||
|
width: 100,
|
||||||
|
height: 50,
|
||||||
|
fill: 'green',
|
||||||
|
opacity : 0.5,
|
||||||
|
shadowBlur : 10,
|
||||||
|
shadowColor : 'black'
|
||||||
|
});
|
||||||
|
rect.cache();
|
||||||
|
rect.opacity(0.3);
|
||||||
|
|
||||||
|
layer.add(rect);
|
||||||
|
stage.add(layer);
|
||||||
|
|
||||||
|
if (!window.mochaPhantomJS) {
|
||||||
|
cloneAndCompareLayer(layer, 10);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('cache rectangle with fill and simple shadow', function() {
|
test('cache rectangle with fill and simple shadow', function() {
|
||||||
@ -110,7 +194,8 @@ suite('Caching', function() {
|
|||||||
height: 50,
|
height: 50,
|
||||||
fill: 'green',
|
fill: 'green',
|
||||||
shadowColor : 'black',
|
shadowColor : 'black',
|
||||||
shadowBlur : 10
|
shadowBlur : 10,
|
||||||
|
draggable : true
|
||||||
});
|
});
|
||||||
rect.cache();
|
rect.cache();
|
||||||
|
|
||||||
@ -126,6 +211,10 @@ suite('Caching', function() {
|
|||||||
context.shadowColor = 'black';
|
context.shadowColor = 'black';
|
||||||
context.shadowBlur = 10;
|
context.shadowBlur = 10;
|
||||||
context.fill();
|
context.fill();
|
||||||
|
|
||||||
|
showCanvas(rect._cache.canvas.scene._canvas);
|
||||||
|
showCanvas(rect._cache.canvas.hit._canvas);
|
||||||
|
showHit(layer);
|
||||||
compareLayerAndCanvas(layer, canvas, 10);
|
compareLayerAndCanvas(layer, canvas, 10);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -273,7 +362,7 @@ suite('Caching', function() {
|
|||||||
context.fillStyle = 'green';
|
context.fillStyle = 'green';
|
||||||
context.fill();
|
context.fill();
|
||||||
compareLayerAndCanvas(layer, canvas, 10);
|
compareLayerAndCanvas(layer, canvas, 10);
|
||||||
compareSceneAndHit(layer);
|
cloneAndCompareLayer(layer);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('cache group with simple rectangle with transform', function() {
|
test('cache group with simple rectangle with transform', function() {
|
||||||
@ -311,7 +400,7 @@ suite('Caching', function() {
|
|||||||
context.fill();
|
context.fill();
|
||||||
if (!window.mochaPhantomJS) {
|
if (!window.mochaPhantomJS) {
|
||||||
compareLayerAndCanvas(layer, canvas, 150);
|
compareLayerAndCanvas(layer, canvas, 150);
|
||||||
compareSceneAndHit(layer);
|
cloneAndCompareLayer(layer, 150);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -504,6 +593,86 @@ suite('Caching', function() {
|
|||||||
context.restore();
|
context.restore();
|
||||||
|
|
||||||
|
|
||||||
compareLayerAndCanvas(layer, canvas, 50);
|
compareLayerAndCanvas(layer, canvas, 150);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('cache shape that is larger than stage but need buffer canvas', function(){
|
||||||
|
var stage = addStage();
|
||||||
|
var layer = new Konva.Layer();
|
||||||
|
var group = new Konva.Group();
|
||||||
|
var circle = new Konva.Circle({
|
||||||
|
x: stage.width() / 2,
|
||||||
|
y: stage.height() / 2,
|
||||||
|
radius: 400,
|
||||||
|
fill: 'red',
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 50,
|
||||||
|
opacity : 0.5,
|
||||||
|
scaleX : 1 / 5,
|
||||||
|
scaleY : 1 / 5
|
||||||
|
});
|
||||||
|
|
||||||
|
group.add(circle);
|
||||||
|
layer.add(group);
|
||||||
|
stage.add(layer);
|
||||||
|
circle.cache();
|
||||||
|
layer.draw();
|
||||||
|
|
||||||
|
cloneAndCompareLayer(layer, 200);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('cache nested groups', function() {
|
||||||
|
var stage = addStage();
|
||||||
|
var layer = new Konva.Layer();
|
||||||
|
|
||||||
|
var groupOuter = new Konva.Group({
|
||||||
|
x: 50,
|
||||||
|
y: 10
|
||||||
|
});
|
||||||
|
|
||||||
|
var groupInner = new Konva.Group({
|
||||||
|
x: 10,
|
||||||
|
y: 10,
|
||||||
|
draggable : true
|
||||||
|
});
|
||||||
|
var rect = new Konva.Rect({
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
stroke: 'grey',
|
||||||
|
strokeWidth: 3,
|
||||||
|
fill: 'yellow'
|
||||||
|
});
|
||||||
|
|
||||||
|
var text = new Konva.Text({
|
||||||
|
x: 18,
|
||||||
|
y: 15,
|
||||||
|
text: 'A',
|
||||||
|
fill: 'black',
|
||||||
|
fontSize: 24
|
||||||
|
});
|
||||||
|
|
||||||
|
groupInner.add(rect);
|
||||||
|
groupInner.add(text);
|
||||||
|
|
||||||
|
groupOuter.add(groupInner);
|
||||||
|
|
||||||
|
layer.add(groupOuter);
|
||||||
|
stage.add(layer);
|
||||||
|
|
||||||
|
groupInner.cache();
|
||||||
|
|
||||||
|
layer.draw();
|
||||||
|
cloneAndCompareLayer(layer, 150);
|
||||||
|
|
||||||
|
groupInner.clearCache();
|
||||||
|
groupOuter.cache();
|
||||||
|
layer.draw();
|
||||||
|
cloneAndCompareLayer(layer, 150);
|
||||||
|
|
||||||
|
groupOuter.clearCache();
|
||||||
|
groupInner.clearCache();
|
||||||
|
rect.cache();
|
||||||
|
layer.draw();
|
||||||
|
cloneAndCompareLayer(layer, 150);
|
||||||
});
|
});
|
||||||
});
|
});
|
@ -2689,8 +2689,9 @@ suite('Node', function() {
|
|||||||
layer.on('click', function() {
|
layer.on('click', function() {
|
||||||
layerClick += 1;
|
layerClick += 1;
|
||||||
});
|
});
|
||||||
|
showHit(layer);
|
||||||
var top = stage.content.getBoundingClientRect().top;
|
var top = stage.content.getBoundingClientRect().top;
|
||||||
|
|
||||||
stage._mousedown({
|
stage._mousedown({
|
||||||
clientX: 150,
|
clientX: 150,
|
||||||
clientY: 75 + top
|
clientY: 75 + top
|
||||||
@ -2701,7 +2702,7 @@ suite('Node', function() {
|
|||||||
clientY: 75 + top
|
clientY: 75 + top
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.equal(rectClick, 1, 'click on rectange');
|
assert.equal(rectClick, 1, 'click on rectangle');
|
||||||
assert.equal(groupClick, 0, 'no click on group');
|
assert.equal(groupClick, 0, 'no click on group');
|
||||||
assert.equal(layerClick, 0, 'no click on layer');
|
assert.equal(layerClick, 0, 'no click on layer');
|
||||||
});
|
});
|
||||||
|
@ -505,7 +505,8 @@ suite('Stage', function() {
|
|||||||
clientY: clientY
|
clientY: clientY
|
||||||
});
|
});
|
||||||
Konva.DD._endDragAfter({dragEndNode:rect});
|
Konva.DD._endDragAfter({dragEndNode:rect});
|
||||||
|
assert.equal(Konva.isDragging(), false);
|
||||||
|
assert.equal(Konva.DD.node, undefined);
|
||||||
// simulate click
|
// simulate click
|
||||||
stage._mousedown({
|
stage._mousedown({
|
||||||
clientX: 66,
|
clientX: 66,
|
||||||
@ -516,5 +517,8 @@ suite('Stage', function() {
|
|||||||
clientX: 66,
|
clientX: 66,
|
||||||
clientY: clientY
|
clientY: clientY
|
||||||
});
|
});
|
||||||
})
|
Konva.DD._endDragBefore({dragEndNode:rect});
|
||||||
|
assert.equal(Konva.isDragging(), false);
|
||||||
|
assert.equal(Konva.DD.node, undefined);
|
||||||
|
});
|
||||||
});
|
});
|
@ -132,7 +132,6 @@ suite('Tween', function() {
|
|||||||
|
|
||||||
|
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
"use strict";
|
|
||||||
assert.equal(circle.x(), 200);
|
assert.equal(circle.x(), 200);
|
||||||
assert.equal(circle.y(), 100);
|
assert.equal(circle.y(), 100);
|
||||||
done();
|
done();
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
suite('Blur', function() {
|
suite('Blur', function() {
|
||||||
// ======================================================
|
// ======================================================
|
||||||
test('basic blur', function(done) {
|
test('basic blur', function(done) {
|
||||||
|
this.timeout(5000);
|
||||||
var stage = addStage();
|
var stage = addStage();
|
||||||
|
|
||||||
var imageObj = new Image();
|
var imageObj = new Image();
|
||||||
|
@ -214,7 +214,7 @@ suite('Label', function() {
|
|||||||
|
|
||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
|
|
||||||
cloneAndCompareLayer(layer, 150);
|
cloneAndCompareLayer(layer, 220);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
@ -414,6 +414,7 @@ suite('Path', function() {
|
|||||||
|
|
||||||
// ======================================================
|
// ======================================================
|
||||||
test('Tiger (RAWR!)', function() {
|
test('Tiger (RAWR!)', function() {
|
||||||
|
this.timeout(5000);
|
||||||
var stage = addStage();
|
var stage = addStage();
|
||||||
var layer = new Konva.Layer();
|
var layer = new Konva.Layer();
|
||||||
var group = new Konva.Group();
|
var group = new Konva.Group();
|
||||||
|
@ -143,7 +143,7 @@ suite('RegularPolygon', function() {
|
|||||||
width : 100
|
width : 100
|
||||||
});
|
});
|
||||||
if (!window.mochaPhantomJS) {
|
if (!window.mochaPhantomJS) {
|
||||||
cloneAndCompareLayer(layer, 50);
|
cloneAndCompareLayer(layer, 200);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -106,12 +106,13 @@ suite('Blob', function(){
|
|||||||
tension: 0.3,
|
tension: 0.3,
|
||||||
closed: true
|
closed: true
|
||||||
});
|
});
|
||||||
|
|
||||||
blob.cache();
|
blob.cache();
|
||||||
layer.add(blob);
|
layer.add(blob);
|
||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
|
|
||||||
if (!window.mochaPhantomJS) {
|
if (!window.mochaPhantomJS) {
|
||||||
cloneAndCompareLayer(layer, 50);
|
cloneAndCompareLayer(layer, 100);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
@ -266,6 +266,6 @@ suite('Circle', function(){
|
|||||||
context.fill();
|
context.fill();
|
||||||
context.lineWidth = 4;
|
context.lineWidth = 4;
|
||||||
context.stroke();
|
context.stroke();
|
||||||
compareLayerAndCanvas(layer, canvas, 50);
|
compareLayerAndCanvas(layer, canvas, 100);
|
||||||
});
|
});
|
||||||
});
|
});
|
@ -366,5 +366,35 @@ suite('Text', function(){
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test.skip('cache text', function() {
|
||||||
|
var stage = addStage();
|
||||||
|
var layer = new Konva.Layer();
|
||||||
|
|
||||||
|
var text = new Konva.Text({
|
||||||
|
fontSize: 20,
|
||||||
|
y : 50,
|
||||||
|
x : 50,
|
||||||
|
fill: 'black',
|
||||||
|
text: 'Hello world with cache!\nHow are you?',
|
||||||
|
draggable : true
|
||||||
|
});
|
||||||
|
|
||||||
|
text.cache();
|
||||||
|
layer.add(text);
|
||||||
|
|
||||||
|
var text2 = new Konva.Text({
|
||||||
|
fontSize: 20,
|
||||||
|
y : 50,
|
||||||
|
x : 260,
|
||||||
|
fill: 'black',
|
||||||
|
text: 'Hello world without cache!\nHow are you?',
|
||||||
|
draggable : true
|
||||||
|
});
|
||||||
|
|
||||||
|
layer.add(text2);
|
||||||
|
|
||||||
|
stage.add(layer);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
Loading…
Reference in New Issue
Block a user