Add new method getClientRect(). rethink caching.

This commit is contained in:
lavrton 2015-02-12 14:10:36 +07:00
parent b9c6bc2d10
commit e39d7861c3
37 changed files with 1813 additions and 453 deletions

View File

@ -80,7 +80,7 @@
* @memberof Konva.Canvas.prototype
* @param {Number} pixelRatio KonvaJS automatically handles pixel ratio adustments in order to render crisp drawings
* on all devices. Most desktops, low end tablets, and low end phones, have device pixel ratios
* of 1. Some high end tablets and phones, like iPhones and iPads (not the mini) have a device pixel ratio
* of 1. Some high end tablets and phones, like iPhones and iPads have a device pixel ratio
* of 2. Some Macbook Pros, and iMacs also have a device pixel ratio of 2. Some high end Android devices have pixel
* ratios of 2 or 3. Some browsers like Firefox allow you to configure the pixel ratio of the viewport. Unless otherwise
* specificed, the pixel ratio will be defaulted to the actual device pixel ratio. You can override the device pixel

View File

@ -303,7 +303,7 @@
child.index = n;
});
},
drawScene: function(can, top) {
drawScene: function(can, top, caching) {
var layer = this.getLayer(),
canvas = can || (layer && layer.getCanvas()),
context = canvas && canvas.getContext(),
@ -311,8 +311,11 @@
cachedSceneCanvas = cachedCanvas && cachedCanvas.scene;
if (this.isVisible()) {
if (cachedSceneCanvas) {
if (!caching && cachedSceneCanvas) {
context.save();
layer._applyTransform(this, context, top);
this._drawCachedSceneCanvas(context);
context.restore();
}
else {
this._drawChildren(canvas, 'drawScene', top);
@ -320,7 +323,7 @@
}
return this;
},
drawHit: function(can, top) {
drawHit: function(can, top, caching) {
var layer = this.getLayer(),
canvas = can || (layer && layer.hitCanvas),
context = canvas && canvas.getContext(),
@ -331,8 +334,11 @@
if (layer) {
layer.clearHitCache();
}
if (cachedHitCanvas) {
if (!caching && cachedHitCanvas) {
context.save();
layer._applyTransform(this, context, top);
this._drawCachedHitCanvas(context);
context.restore();
}
else {
this._drawChildren(canvas, 'drawHit', top);
@ -374,6 +380,27 @@
var layerUnderDrag = dd && Konva.isDragging() && (Konva.DD.anim.getLayers().indexOf(layer) !== -1);
return (canvas && canvas.isCache) || (layer && layer.hitGraphEnabled())
&& this.isVisible() && !layerUnderDrag;
},
getClientRect : function(skipTransform) {
var minX, minY, maxX, maxY;
this.children.each(function(child) {
var rect = child.getClientRect();
minX = Math.min(minX, rect.x) || rect.x;
minY = Math.min(minY, rect.y) || rect.y;
maxX = Math.max(maxX, rect.x + rect.width) || (rect.x + rect.width);
maxY = Math.max(maxY, rect.y + rect.height) || (rect.y + rect.height);
});
var rect = {
x : minX,
y : minY,
width : maxX - minX,
height : maxY - minY
};
if (!skipTransform) {
return this._transformedRect(rect);
}
return rect;
}
});

View File

@ -139,37 +139,47 @@
* y: -30,
* width: 100,
* height: 200,
* offset : 10,
* drawBorder: true
* });
*/
cache: function(config) {
var conf = config || {},
x = conf.x || 0,
y = conf.y || 0,
width = conf.width || this.width(),
height = conf.height || this.height(),
rect = this.getClientRect(true),
width = conf.width || rect.width,
height = conf.height || rect.height,
x = conf.x || rect.x,
y = conf.y || rect.y,
offset = conf.offset || 0,
drawBorder = conf.drawBorder || false;
if (width === 0 || height === 0) {
Konva.Util.warn('Width or height of caching configuration equals 0. Cache is ignored.');
return;
if (!width || !height) {
throw new Error('Width or height of caching configuration equals 0.');
}
width += offset * 2;
height += offset * 2;
x -= offset;
y -= offset;
var cachedSceneCanvas = new Konva.SceneCanvas({
pixelRatio: 1,
width: width,
height: height
}),
cachedFilterCanvas = new Konva.SceneCanvas({
pixelRatio: 1,
width: width,
height: height
}),
cachedHitCanvas = new Konva.HitCanvas({
width: width,
height: height
}),
sceneContext = cachedSceneCanvas.getContext(),
hitContext = cachedHitCanvas.getContext();
pixelRatio: 1,
width: width,
height: height
}),
cachedFilterCanvas = new Konva.SceneCanvas({
pixelRatio: 1,
width: width,
height: height
}),
cachedHitCanvas = new Konva.HitCanvas({
width: width,
height: height
}),
sceneContext = cachedSceneCanvas.getContext(),
hitContext = cachedHitCanvas.getContext();
cachedHitCanvas.isCache = true;
@ -178,6 +188,15 @@
sceneContext.save();
hitContext.save();
sceneContext.translate(-x, -y);
hitContext.translate(-x, -y);
this.drawScene(cachedSceneCanvas, this, true);
this.drawHit(cachedHitCanvas, this, true);
sceneContext.restore();
hitContext.restore();
// this will draw a red border around the cached box for
// debugging purposes
if (drawBorder) {
@ -191,36 +210,80 @@
sceneContext.restore();
}
sceneContext.translate(x * -1, y * -1);
hitContext.translate(x * -1, y * -1);
// don't need to translate canvas if shape is not added to layer
if (this.nodeType === 'Shape') {
sceneContext.translate(this.x() * -1, this.y() * -1);
hitContext.translate(this.x() * -1, this.y() * -1);
}
this.drawScene(cachedSceneCanvas, this);
this.drawHit(cachedHitCanvas, this);
sceneContext.restore();
hitContext.restore();
this._cache.canvas = {
scene: cachedSceneCanvas,
filter: cachedFilterCanvas,
hit: cachedHitCanvas
hit: cachedHitCanvas,
x : x,
y : y
};
return this;
},
/**
* return client rectangle (x, y, width, height) of node. This rectangle also include all styling (strokes, shadows, etc)
* @method
* @memberof Konva.Node.prototype
* @param {Boolean} [skipTransform] flag should we apply transformation to rectangle
* @returns {Object} rect with {x, y, width, height} properties
* @example
*
* circle.getClientRect(true);
*/
getClientRect : function() {
// abstract method
// redefine in Container and Shape
throw 'abstract "getClientRect" method call';
},
_transformedRect : function(rect) {
var points = [
{x : rect.x, y : rect.y},
{x : rect.x + rect.width, y : rect.y},
{x : rect.x + rect.width, y : rect.y + rect.height},
{x : rect.x, y : rect.y + rect.height}
];
var minX, minY, maxX, maxY;
var trans = this.getTransform();
points.forEach(function(point) {
var transformed = trans.point(point);
if (minX === undefined) {
minX = maxX = transformed.x;
minY = maxY = transformed.y;
}
minX = Math.min(minX, transformed.x);
minY = Math.min(minY, transformed.y);
maxX = Math.max(maxX, transformed.x);
maxY = Math.max(maxY, transformed.y);
});
return {
x : Math.round(minX),
y : Math.round(minY),
width : Math.round(maxX - minX),
height : Math.round(maxY - minY)
};
},
_drawCachedSceneCanvas: function(context) {
context.save();
this.getLayer()._applyTransform(this, context);
context._applyOpacity(this);
context.translate(
this._cache.canvas.x,
this._cache.canvas.y
);
context.drawImage(this._getCachedSceneCanvas()._canvas, 0, 0);
context.restore();
},
_drawCachedHitCanvas: function(context) {
var cachedCanvas = this._cache.canvas,
hitCanvas = cachedCanvas.hit;
context.save();
context.translate(
this._cache.canvas.x,
this._cache.canvas.y
);
context.drawImage(hitCanvas._canvas, 0, 0);
context.restore();
},
_getCachedSceneCanvas: function() {
var filters = this.filters(),
cachedCanvas = this._cache.canvas,
@ -258,15 +321,6 @@
return sceneCanvas;
}
},
_drawCachedHitCanvas: function(context) {
var cachedCanvas = this._cache.canvas,
hitCanvas = cachedCanvas.hit;
context.save();
this.getLayer()._applyTransform(this, context);
context.drawImage(hitCanvas._canvas, 0, 0);
context.restore();
},
/**
* bind events to the node. KonvaJS supports mouseover, mousemove,
* mouseout, mouseenter, mouseleave, mousedown, mouseup, mousewheel, click, dblclick, touchstart, touchmove,
@ -1348,6 +1402,9 @@
width: this.getWidth(),
height: this.getHeight()
};
},
getTransformedSize : function() {
},
getWidth: function() {
return this.attrs.width || 0;

View File

@ -143,11 +143,58 @@
delete Konva.shapes[this.colorKey];
},
_useBufferCanvas: function() {
// return false;
return (this.perfectDrawEnabled() && (this.getAbsoluteOpacity() !== 1) && this.hasFill() && this.hasStroke() && this.getStage()) ||
(this.perfectDrawEnabled() && this.hasShadow() && (this.getAbsoluteOpacity() !== 1) && this.hasFill() && this.hasStroke() && this.getStage());
},
drawScene: function(can, top) {
/**
* return self rectangle (x, y, width, height) of shape.
* This method are not taken into account transformation and styles.
* @method
* @memberof Konva.Node.prototype
* @returns {Object} rect with {x, y, width, height} properties
* @example
*
* rect.getSelfRect(); // return {x:0, y:0, width:rect.width(), height:rect.height()}
* circle.getSelfRect(); // return {x: - circle.width() / 2, y: - circle.height() / 2, width:circle.width(), height:circle.height()}
*
*/
getSelfRect : function() {
var size = this.getSize();
return {
x : this._centroid ? Math.round(-size.width / 2) : 0,
y : this._centroid ? Math.round(-size.height / 2) : 0,
width : size.width,
height : size.height
};
},
getClientRect : function(skipTransform) {
var fillRect = this.getSelfRect();
var strokeWidth = (this.hasStroke() && this.strokeWidth()) || 0;
var fillAndStrokeWidth = fillRect.width + strokeWidth;
var fillAndStrokeHeight = fillRect.height + strokeWidth;
var shadowOffsetX = this.shadowOffsetX();
var shadowOffsetY = this.shadowOffsetY();
var preWidth = fillAndStrokeWidth + Math.abs(shadowOffsetX);
var preHeight = fillAndStrokeHeight + Math.abs(shadowOffsetY);
var blurRadius = (this.hasShadow() && this.shadowBlur() || 0);
var width = preWidth + blurRadius * 2;
var height = preHeight + blurRadius * 2;
var rect = {
width : width,
height : height,
x : -Math.round(strokeWidth / 2 + blurRadius) + Math.min(shadowOffsetX, 0) + fillRect.x,
y : -Math.round(strokeWidth / 2 + blurRadius) + Math.min(shadowOffsetY, 0) + fillRect.y
};
if (!skipTransform) {
return this._transformedRect(rect);
}
return rect;
},
drawScene: function(can, top, caching) {
var layer = this.getLayer(),
canvas = can || layer.getCanvas(),
context = canvas.getContext(),
@ -159,7 +206,10 @@
if(this.isVisible()) {
if (cachedCanvas) {
context.save();
layer._applyTransform(this, context, top);
this._drawCachedSceneCanvas(context);
context.restore();
}
else if (drawFunc) {
context.save();
@ -210,11 +260,13 @@
else {
context._applyLineJoin(this);
// layer might be undefined if we are using cache before adding to layer
if (layer) {
layer._applyTransform(this, context, top);
} else {
var o = this.getAbsoluteTransform(top).getMatrix();
context.transform(o[0], o[1], o[2], o[3], o[4], o[5]);
if (!caching) {
if (layer) {
layer._applyTransform(this, context, top);
} else {
var o = this.getAbsoluteTransform(top).getMatrix();
context.transform(o[0], o[1], o[2], o[3], o[4], o[5]);
}
}
if (hasShadow && hasStroke && !canvas.hitCanvas) {
@ -247,7 +299,7 @@
return this;
},
drawHit: function(can, top) {
drawHit: function(can, top, caching) {
var layer = this.getLayer(),
canvas = can || layer.hitCanvas,
context = canvas.getContext(),
@ -260,16 +312,21 @@
layer.clearHitCache();
}
if (cachedHitCanvas) {
context.save();
layer._applyTransform(this, context, top);
this._drawCachedHitCanvas(context);
context.restore();
}
else if (drawFunc) {
context.save();
context._applyLineJoin(this);
if (layer) {
layer._applyTransform(this, context, top);
} else {
var m = this.getAbsoluteTransform(top).getMatrix();
context.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
if (!caching) {
if (layer) {
layer._applyTransform(this, context, top);
} else {
var o = this.getAbsoluteTransform(top).getMatrix();
context.transform(o[0], o[1], o[2], o[3], o[4], o[5]);
}
}
drawFunc.call(this, context);

View File

@ -98,7 +98,7 @@
/*
* The usage of this class was inspired by some of the work done by a forked
* project, KonvaJS-Ext by Wappworks, which is based on Simon's Transform
* project, KineticJS-Ext by Wappworks, which is based on Simon's Transform
* class. Modified by Eric Rowell
*/

View File

@ -241,6 +241,34 @@
context.closePath();
context.fillStrokeShape(this);
},
getSelfRect : function() {
var x = 0,
y = 0,
pointerWidth = this.getPointerWidth(),
pointerHeight = this.getPointerHeight(),
direction = this.pointerDirection(),
width = this.getWidth(),
height = this.getHeight();
if (direction === UP) {
y -= pointerHeight;
height += pointerHeight;
} else if (direction === DOWN) {
height += pointerHeight;
} else if (direction === LEFT) {
// ARGH!!! I have no idea why should I used magic 1.5!!!!!!!!!
x -= pointerWidth * 1.5;
width += pointerWidth;
} else if (direction === RIGHT) {
width += pointerWidth * 1.5;
}
return {
x : x,
y : y,
width : width,
height : height
};
}
};

View File

@ -89,6 +89,30 @@
else {
context.strokeShape(this);
}
},
getSelfRect : function() {
var points = [];
this.dataArray.forEach(function(data) {
points = points.concat(data.points);
});
var minX = points[0];
var maxX = points[0];
var minY = points[0];
var maxY = points[0];
var x,y;
for (var i = 0; i<points.length / 2; i++) {
x = points[i * 2]; y = points[i * 2 + 1];
minX = Math.min(minX, x);
maxX = Math.max(maxX, x);
minY = Math.min(minY, y);
maxY = Math.max(maxY, y);
}
return {
x : Math.round(minX),
y : Math.round(minY),
width : Math.round(maxX - minX),
height : Math.round(maxY - minY)
};
}
};
Konva.Util.extend(Konva.Path, Konva.Shape);

View File

@ -25,6 +25,7 @@
};
Konva.RegularPolygon.prototype = {
_centroid : true,
___init: function(config) {
// call super constructor
Konva.Shape.call(this, config);
@ -46,6 +47,27 @@
}
context.closePath();
context.fillStrokeShape(this);
},
getWidth: function() {
return this.getRadius() * 2;
},
// implements Shape.prototype.getHeight()
getHeight: function() {
return this.getRadius() * 2;
},
// implements Shape.prototype.setWidth()
setWidth: function(width) {
Konva.Node.prototype.setWidth.call(this, width);
if (this.radius() !== width / 2) {
this.setRadius(width / 2);
}
},
// implements Shape.prototype.setHeight()
setHeight: function(height) {
Konva.Node.prototype.setHeight.call(this, height);
if (this.radius() !== height / 2) {
this.setRadius(height / 2);
}
}
};
Konva.Util.extend(Konva.RegularPolygon, Konva.Shape);

View File

@ -27,6 +27,7 @@
};
Konva.Star.prototype = {
_centroid : true,
___init: function(config) {
// call super constructor
Konva.Shape.call(this, config);
@ -50,6 +51,28 @@
context.closePath();
context.fillStrokeShape(this);
},
// implements Shape.prototype.getWidth()
getWidth: function() {
return this.getOuterRadius() * 2;
},
// implements Shape.prototype.getHeight()
getHeight: function() {
return this.getOuterRadius() * 2;
},
// implements Shape.prototype.setWidth()
setWidth: function(width) {
Konva.Node.prototype.setWidth.call(this, width);
if (this.outerRadius() !== width / 2) {
this.setOuterRadius(width / 2);
}
},
// implements Shape.prototype.setHeight()
setHeight: function(height) {
Konva.Node.prototype.setHeight.call(this, height);
if (this.outerRadius() !== height / 2) {
this.setOuterRadius(height / 2);
}
}
};
Konva.Util.extend(Konva.Star, Konva.Shape);

View File

@ -321,6 +321,35 @@
});
p0 = p1;
}
},
getSelfRect : function() {
var points = [];
var fontSize = this.fontSize();
this.glyphInfo.forEach(function(info) {
points.push(info.p0.x);
points.push(info.p0.y);
points.push(info.p1.x);
points.push(info.p1.y);
});
var minX = points[0];
var maxX = points[0];
var minY = points[0];
var maxY = points[0];
var x,y;
for (var i = 0; i<points.length / 2; i++) {
x = points[i * 2]; y = points[i * 2 + 1];
minX = Math.min(minX, x);
maxX = Math.max(maxX, x);
minY = Math.min(minY, y);
maxY = Math.max(maxY, y);
}
return {
x : Math.round(minX) - fontSize,
y : Math.round(minY) - fontSize,
width : Math.round(maxX - minX) + fontSize * 2,
height : Math.round(maxY - minY) + fontSize * 2
};
}
};

View File

@ -27,6 +27,7 @@
};
Konva.Arc.prototype = {
_centroid : true,
___init: function(config) {
// call super constructor
Konva.Shape.call(this, config);
@ -42,6 +43,28 @@
context.arc(0, 0, this.getInnerRadius(), angle, 0, !clockwise);
context.closePath();
context.fillStrokeShape(this);
},
// implements Shape.prototype.getWidth()
getWidth: function() {
return this.getOuterRadius() * 2;
},
// implements Shape.prototype.getHeight()
getHeight: function() {
return this.getOuterRadius() * 2;
},
// implements Shape.prototype.setWidth()
setWidth: function(width) {
Konva.Node.prototype.setWidth.call(this, width);
if (this.getOuterRadius() !== width / 2) {
this.setOuterRadius(width / 2);
}
},
// implements Shape.prototype.setHeight()
setHeight: function(height) {
Konva.Node.prototype.setHeight.call(this, height);
if (this.getOuterRadius() !== height / 2) {
this.setOuterRadius(height / 2);
}
}
};
Konva.Util.extend(Konva.Arc, Konva.Shape);

View File

@ -26,6 +26,7 @@
};
Konva.Circle.prototype = {
_centroid : true,
___init: function(config) {
// call super constructor
Konva.Shape.call(this, config);
@ -59,17 +60,12 @@
if (this.radius() !== height / 2) {
this.setRadius(height / 2);
}
},
setRadius : function(val) {
this._setAttr('radius', val);
this.setWidth(val * 2);
this.setHeight(val * 2);
}
};
Konva.Util.extend(Konva.Circle, Konva.Shape);
// add getters setters
Konva.Factory.addGetter(Konva.Circle, 'radius', 0);
Konva.Factory.addGetterSetter(Konva.Circle, 'radius', 0);
Konva.Factory.addOverloadedGetterSetter(Konva.Circle, 'radius');
/**

View File

@ -25,6 +25,7 @@
};
Konva.Ellipse.prototype = {
_centroid : true,
___init: function(config) {
// call super constructor
Konva.Shape.call(this, config);

View File

@ -140,6 +140,39 @@
]);
return tp;
},
getWidth : function() {
return this.getSelfRect().width;
},
getHeight : function() {
return this.getSelfRect().height;
},
// overload size detection
getSelfRect : function() {
var points;
if (this.getTension() !== 0) {
points = this._getTensionPoints();
} else {
points = this.getPoints();
}
var minX = points[0];
var maxX = points[0];
var minY = points[0];
var maxY = points[0];
var x,y;
for (var i = 0; i<points.length / 2; i++) {
x = points[i * 2]; y = points[i * 2 + 1];
minX = Math.min(minX, x);
maxX = Math.max(maxX, x);
minY = Math.min(minY, y);
maxY = Math.max(maxY, y);
}
return {
x : minX,
y : minY,
width : maxX - minX,
height : maxY - minY
};
}
};
Konva.Util.extend(Konva.Line, Konva.Shape);

View File

@ -26,6 +26,7 @@
};
Konva.Ring.prototype = {
_centroid : true,
___init: function(config) {
// call super constructor
Konva.Shape.call(this, config);

View File

@ -25,6 +25,7 @@
};
Konva.Wedge.prototype = {
_centroid : true,
___init: function(config) {
// call super constructor
Konva.Shape.call(this, config);
@ -37,6 +38,28 @@
context.lineTo(0, 0);
context.closePath();
context.fillStrokeShape(this);
},
// implements Shape.prototype.getWidth()
getWidth: function() {
return this.getRadius() * 2;
},
// implements Shape.prototype.getHeight()
getHeight: function() {
return this.getRadius() * 2;
},
// implements Shape.prototype.setWidth()
setWidth: function(width) {
Konva.Node.prototype.setWidth.call(this, width);
if (this.radius() !== width / 2) {
this.setRadius(width / 2);
}
},
// implements Shape.prototype.setHeight()
setHeight: function(height) {
Konva.Node.prototype.setHeight.call(this, height);
if (this.radius() !== height / 2) {
this.setRadius(height / 2);
}
}
};
Konva.Util.extend(Konva.Wedge, Konva.Shape);

View File

@ -730,10 +730,7 @@ suite('MouseEvents', function() {
group.add(greenCircle);
layer.add(group);
group.cache({
width : stage.width(),
height : stage.height()
});
group.cache();
group.scale({
x : 5,
y : 5
@ -741,6 +738,8 @@ suite('MouseEvents', function() {
group.on('mousedown', function() {
groupMousedowns++;
});
layer.add(circle);
stage.add(layer);
layer.draw();
@ -749,6 +748,7 @@ suite('MouseEvents', function() {
clientX: 135,
clientY: 30 + top
});
assert.equal(groupMousedowns, 1, 'groupMousedowns should be 1');
});
test('test mousemove events with antialiasing', function() {
@ -776,10 +776,6 @@ suite('MouseEvents', function() {
});
group.add(rect1).add(rect2);
layer.add(group);
group.cache({
width : rect1.width(),
height : rect1.height()
});
group.scaleX(5);
group.scaleY(5);
var mouseenterCount = 0;

View File

@ -224,4 +224,47 @@ suite('Manual', function() {
tween.play();
});
test('Make sure that all texts are inside rectangles.', function() {
var stage = addStage();
var layer = new Konva.Layer();
var text = new Konva.Text({
fontSize: 50,
y : 5,
x : 25,
fill: 'black',
text: 'text'
});
var params = text.getSelfRect();
var rect = new Konva.Rect({
x : text.x() + params.x,
y : text.y() + params.y,
width : params.width,
height : params.height,
stroke : 'black'
});
layer.add(rect, text);
text = new Konva.Text({
fontSize: 40,
y : 40,
x : 150,
fill: 'black',
text: 'Hello\nWorld! How Are you?',
align : 'center'
});
params = text.getSelfRect();
rect = new Konva.Rect({
x : text.x() + params.x,
y : text.y() + params.y,
width : params.width,
height : params.height,
stroke : 'black'
});
layer.add(rect, text);
stage.add(layer);
});
});

View File

@ -46,7 +46,8 @@
<script src="unit/Global-test.js"></script>
<script src="unit/Util-test.js"></script>
<script src="unit/Canvas-test.js"></script>
<script src="unit/Node-test.js"></script>
<script src="unit/Node-test.js"></script>
<script src="unit/Node-cache-test.js"></script>
<script src="unit/Container-test.js"></script>
<script src="unit/Stage-test.js"></script>
<script src="unit/BaseLayer-test.js"></script>

View File

@ -64,7 +64,7 @@ function init() {
Konva.enableTrace = true;
Konva.showWarnings = false;
Konva.showWarnings = true;
function addStats() {
stats = new Stats();
@ -115,15 +115,16 @@ function get (element, content) {
}
return element;
}
function compareLayerAndCanvas(layer, canvas, tol) {
var equal = imagediff.equal(layer.getCanvas()._canvas, canvas, tol);
function compareCanvases(canvas1, canvas2, tol) {
// don't test in PhantomJS as it use old chrome engine
// it it has opacity + shadow bug
var equal = imagediff.equal(canvas1, canvas2, tol);
if (!equal) {
var
div = get('div'),
b = get('div', '<div>Expected:</div>'),
c = get('div', '<div>Diff:</div>'),
diff = imagediff.diff(layer.getCanvas()._canvas, canvas),
diff = imagediff.diff(canvas1, canvas2),
diffCanvas = get('canvas'),
context;
@ -134,18 +135,47 @@ function compareLayerAndCanvas(layer, canvas, tol) {
b.style.float = 'left';
c.style.float = 'left';
canvas2.style.position = '';
canvas2.style.display = '';
context = diffCanvas.getContext('2d');
context.putImageData(diff, 0, 0);
b.appendChild(canvas);
b.appendChild(canvas2);
c.appendChild(diffCanvas);
div.appendChild(b);
div.appendChild(c);
konvaContainer.appendChild(div);
}
assert.equal(equal, true);
assert.equal(equal, true, 'Result from Konva is different with canvas result');
}
function compareLayerAndCanvas(layer, canvas, tol) {
compareCanvases(layer.getCanvas()._canvas, canvas, tol);
}
function compareLayers(layer1, layer2, tol) {
compareLayerAndCanvas(layer1, layer2.getCanvas()._canvas, tol);
}
function cloneAndCompareLayer(layer, tol) {
var layer2 = layer.clone();
layer.getStage().add(layer2);
layer2.hide();
compareLayers(layer, layer2, tol);
}
function cloneAndCompareLayerWithHit(layer, tol) {
var layer2 = layer.clone();
layer.getStage().add(layer2);
layer2.hide();
compareLayers(layer, layer2, tol);
compareCanvases(layer.getHitCanvas()._canvas, layer2.getHitCanvas()._canvas, tol);
}
function compareSceneAndHit(layer) {
compareLayerAndCanvas(layer, layer.getHitCanvas()._canvas, 254);
}
function addContainer() {

View File

@ -350,4 +350,13 @@ suite('Layer', function() {
// after drawing group hit cache should be cleared
assert.equal(count, 2, 'while creating new cache getImageData should be called');
});
it('get/set layer size', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
assert.deepEqual(layer.size(), stage.size());
assert.equal(layer.width(), stage.width());
assert.equal(layer.height(), stage.height());
});
});

View File

@ -0,0 +1,509 @@
suite('Caching', function() {
// CACHING SHAPE
test('cache simple rectangle', function() {
var stage = addStage();
var layer = new Konva.Layer();
var rect = new Konva.Rect({
x: 100,
y: 50,
width: 100,
height: 50,
fill: 'green'
});
rect.cache();
layer.add(rect);
stage.add(layer);
var canvas = createCanvas();
var context = canvas.getContext('2d');
context.beginPath();
context.rect(100, 50, 100, 50);
context.closePath();
context.fillStyle = 'green';
context.fill();
compareLayerAndCanvas(layer, canvas, 10);
compareSceneAndHit(layer);
});
test('cache simple rectangle with transform', function() {
var stage = addStage();
var layer = new Konva.Layer();
var rect = new Konva.Rect({
x: 100,
y: 50,
width: 100,
height: 50,
rotation : 45,
scaleY : 2,
fill: 'green'
});
rect.cache();
layer.add(rect);
stage.add(layer);
var canvas = createCanvas();
var context = canvas.getContext('2d');
context.translate(100, 50);
context.rotate(Math.PI / 4);
context.beginPath();
context.rect(0, 0, 100, 100);
context.closePath();
context.fillStyle = 'green';
context.fill();
if (!window.mochaPhantomJS) {
compareLayerAndCanvas(layer, canvas, 40);
compareSceneAndHit(layer);
}
});
test('cache rectangle with fill and stroke', function() {
var stage = addStage();
var layer = new Konva.Layer();
var rect = new Konva.Rect({
x: 100,
y: 50,
width: 100,
height: 50,
fill: 'green',
stroke : 'black',
strokeWidth : 20
});
rect.cache();
layer.add(rect);
stage.add(layer);
var canvas = createCanvas();
var context = canvas.getContext('2d');
context.beginPath();
context.rect(100, 50, 100, 50);
context.closePath();
context.fillStyle = 'green';
context.fill();
context.lineWidth = 20;
context.stroke();
compareLayerAndCanvas(layer, canvas, 10);
compareSceneAndHit(layer);
});
test('cache rectangle with fill and simple shadow', function() {
var stage = addStage();
var layer = new Konva.Layer();
var rect = new Konva.Rect({
x: 100,
y: 50,
width: 100,
height: 50,
fill: 'green',
shadowColor : 'black',
shadowBlur : 10
});
rect.cache();
layer.add(rect);
stage.add(layer);
var canvas = createCanvas();
var context = canvas.getContext('2d');
context.beginPath();
context.rect(100, 50, 100, 50);
context.closePath();
context.fillStyle = 'green';
context.shadowColor = 'black';
context.shadowBlur = 10;
context.fill();
compareLayerAndCanvas(layer, canvas, 10);
});
test('cache rectangle with fill and shadow with offset', function() {
var stage = addStage();
var layer = new Konva.Layer();
var rect = new Konva.Rect({
x: 100,
y: 50,
width: 50,
height: 25,
fill: 'green',
shadowOffsetX : 10,
shadowOffsetY : 10,
shadowColor : 'black',
shadowBlur : 10
});
rect.cache();
layer.add(rect);
stage.add(layer);
var canvas = createCanvas();
var context = canvas.getContext('2d');
context.translate(100, 50);
context.beginPath();
context.rect(0, 0, 50, 25);
context.closePath();
context.fillStyle = 'green';
context.shadowColor = 'black';
context.shadowBlur = 10;
context.shadowOffsetX = 10;
context.shadowOffsetY = 10;
context.fill();
compareLayerAndCanvas(layer, canvas, 50);
});
test('cache rectangle with fill and shadow with negative offset', function() {
var stage = addStage();
var layer = new Konva.Layer();
var rect = new Konva.Rect({
x: 100,
y: 50,
width: 50,
height: 25,
fill: 'green',
shadowOffsetX : -10,
shadowOffsetY : -10,
shadowColor : 'black',
shadowBlur : 10
});
rect.cache();
layer.add(rect);
stage.add(layer);
var canvas = createCanvas();
var context = canvas.getContext('2d');
context.translate(100, 50);
context.beginPath();
context.rect(0, 0, 50, 25);
context.closePath();
context.fillStyle = 'green';
context.shadowColor = 'black';
context.shadowBlur = 10;
context.shadowOffsetX = -10;
context.shadowOffsetY = -10;
context.fill();
compareLayerAndCanvas(layer, canvas, 50);
});
test('cache rectangle with fill and shadow and some transform', function() {
var stage = addStage();
var layer = new Konva.Layer();
var rect = new Konva.Rect({
x: 100,
y: 50,
width: 50,
height: 25,
fill: 'green',
shadowOffsetX : -10,
shadowOffsetY : -10,
shadowColor : 'black',
shadowBlur : 10,
offsetX : 50,
offsetY : 25
});
rect.cache();
layer.add(rect);
stage.add(layer);
var canvas = createCanvas();
var context = canvas.getContext('2d');
context.translate(50, 25);
context.beginPath();
context.rect(0, 0, 50, 25);
context.closePath();
context.fillStyle = 'green';
context.shadowColor = 'black';
context.shadowBlur = 10;
context.shadowOffsetX = -10;
context.shadowOffsetY = -10;
context.fill();
compareLayerAndCanvas(layer, canvas, 50);
});
// CACHING CONTAINERS
test('cache group with simple rectangle', function() {
var stage = addStage();
var layer = new Konva.Layer();
var group = new Konva.Group({
x: 100,
y: 50
});
var rect = new Konva.Rect({
width: 100,
height: 50,
fill: 'green'
});
group.add(rect);
group.cache();
layer.add(group);
stage.add(layer);
var canvas = createCanvas();
var context = canvas.getContext('2d');
context.beginPath();
context.rect(100, 50, 100, 50);
context.closePath();
context.fillStyle = 'green';
context.fill();
compareLayerAndCanvas(layer, canvas, 10);
compareSceneAndHit(layer);
});
test('cache group with simple rectangle with transform', function() {
var stage = addStage();
var layer = new Konva.Layer();
var group = new Konva.Group({
x: 50,
y: 25
});
var rect = new Konva.Rect({
x : 50,
y : 25,
width: 100,
height: 50,
fill: 'green',
rotation : 45
});
group.add(rect);
group.cache();
layer.add(group);
stage.add(layer);
var canvas = createCanvas();
var context = canvas.getContext('2d');
context.translate(100, 50);
context.rotate(Math.PI / 4);
context.beginPath();
context.rect(0, 0, 100, 50);
context.closePath();
context.fillStyle = 'green';
context.fill();
if (!window.mochaPhantomJS) {
compareLayerAndCanvas(layer, canvas, 150);
compareSceneAndHit(layer);
}
});
test('cache group with several shape with transform', function() {
var stage = addStage();
var layer = new Konva.Layer();
var group = new Konva.Group({
x: 50,
y: 25
});
var rect = new Konva.Rect({
x : 50,
y : 25,
width: 100,
height: 50,
fill: 'green',
shadowOffsetX : 10,
shadowOffsetY : 10,
shadowBlur : 10
});
group.add(rect);
var circle = new Konva.Circle({
x : 250,
y : 50,
radius : 25,
fill: 'red',
// rotation on circle should not have any effects
rotation : 45,
stroke : 2,
scaleX : 2,
scaleY : 2
});
group.add(circle);
group.cache();
layer.add(group);
stage.add(layer);
var canvas = createCanvas();
var context = canvas.getContext('2d');
// draw rect
context.save();
context.beginPath();
context.rect(100, 50, 100, 50);
context.closePath();
context.fillStyle = 'green';
context.shadowColor = 'black';
context.shadowBlur = 10;
context.shadowOffsetX = 10;
context.shadowOffsetY = 10;
context.fill();
context.restore();
// circle
context.save();
context.beginPath();
context.arc(300, 75, 50, 0, Math.PI * 2);
context.closePath();
context.fillStyle = 'red';
context.lineWidth = 4;
context.fill();
context.stroke();
context.restore();
compareLayerAndCanvas(layer, canvas, 150);
// recache
group.cache();
layer.draw();
compareLayerAndCanvas(layer, canvas, 150);
});
test('cache layer with several shape with transform', function() {
var stage = addStage();
var layer = new Konva.Layer({
draggable : true
});
var group = new Konva.Group({
x: 50,
y: 25
});
var rect = new Konva.Rect({
x : 50,
y : 25,
width: 100,
height: 50,
fill: 'green',
shadowOffsetX : 10,
shadowOffsetY : 10,
shadowBlur : 10
});
group.add(rect);
var circle = new Konva.Circle({
x : 250,
y : 50,
radius : 25,
fill: 'red',
// rotation on circle should not have any effects
rotation : 45,
stroke : 2,
scaleX : 2,
scaleY : 2
});
group.add(circle);
group.cache();
layer.add(group);
stage.add(layer);
var canvas = createCanvas();
var context = canvas.getContext('2d');
// draw rect
context.save();
context.beginPath();
context.rect(100, 50, 100, 50);
context.closePath();
context.fillStyle = 'green';
context.shadowColor = 'black';
context.shadowBlur = 10;
context.shadowOffsetX = 10;
context.shadowOffsetY = 10;
context.fill();
context.restore();
// circle
context.save();
context.beginPath();
context.arc(300, 75, 50, 0, Math.PI * 2);
context.closePath();
context.fillStyle = 'red';
context.lineWidth = 4;
context.fill();
context.stroke();
context.restore();
compareLayerAndCanvas(layer, canvas, 150);
// recache
group.cache();
layer.draw();
compareLayerAndCanvas(layer, canvas, 150);
});
test('cache shape that is larger than stage', function(){
var stage = addStage();
var layer = new Konva.Layer();
var group = new Konva.Group();
var circle = new Konva.Circle({
x: 74,
y: 74,
radius: 300,
fill: 'red',
stroke: 'black',
strokeWidth: 4,
scaleX : 1 /2,
scaleY : 1 / 2
});
group.add(circle);
layer.add(group);
stage.add(layer);
assert.equal(circle._cache.canvas, undefined);
var canvas = createCanvas();
var context = canvas.getContext('2d');
// circle
context.save();
context.beginPath();
context.arc(74, 74, 150, 0, Math.PI * 2);
context.closePath();
context.fillStyle = 'red';
context.lineWidth = 2;
context.fill();
context.stroke();
context.restore();
compareLayerAndCanvas(layer, canvas, 50);
});
});

View File

@ -2961,358 +2961,6 @@ suite('Node', function() {
y : 35
});
assert.equal(shape, rect, 'rect found');
assert.equal(layer.canvas.getContext().getTrace(), 'clearRect(0,0,578,200);clearRect(0,0,578,200);save();transform(1,0,0,1,0,0);drawImage([object HTMLCanvasElement],0,0);restore();');
});
test('cache shape inside transformed group', function(){
var stage = addStage();
var layer = new Konva.Layer();
var group = new Konva.Group({
x: 50,
y: 50
});
var circle = new Konva.Circle({
x: 74,
y: 74,
radius: 70,
fill: 'green',
stroke: 'black',
strokeWidth: 4,
name: 'myCircle',
draggable: true
});
group.add(circle);
layer.add(group);
stage.add(layer);
assert.equal(circle._cache.canvas, undefined);
circle.cache({
x: -74,
y: -74,
width: 148,
height: 148
}).offset({
x: 74,
y: 74
});
assert.notEqual(circle._cache.canvas.scene, undefined);
assert.notEqual(circle._cache.canvas.hit, undefined);
layer.draw();
//document.body.appendChild(circle._cache.canvas.scene._canvas);
// document.body.appendChild(circle._cache.canvas.hit._canvas);
showHit(layer)
assert.equal(layer.getContext().getTrace(), 'clearRect(0,0,578,200);save();transform(1,0,0,1,124,124);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,50,50);drawImage([object HTMLCanvasElement],0,0);restore();');
assert.equal(circle._cache.canvas.scene.getContext().getTrace(), 'save();translate(74,74);translate(-74,-74);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();restore();');
});
test('cache shape thats larger than stage', function(){
var stage = addStage();
var layer = new Konva.Layer();
var group = new Konva.Group();
var circle = new Konva.Circle({
x: 74,
y: 74,
radius: 300,
fill: 'green',
stroke: 'black',
strokeWidth: 4,
name: 'myCircle',
draggable: true
});
group.add(circle);
layer.add(group);
stage.add(layer);
assert.equal(circle._cache.canvas, undefined);
circle.cache({
x: -304,
y: -304,
width: 608,
height: 608
}).offset({
x: 304,
y: 304
});
layer.draw();
});
test('show cache border', function(){
var stage = addStage();
var layer = new Konva.Layer();
var group = new Konva.Group();
var circle = new Konva.Circle({
x: 200,
y: 74,
radius: 70,
fill: 'green',
stroke: 'black',
strokeWidth: 4,
name: 'myCircle',
draggable: true
});
group.add(circle);
layer.add(group);
stage.add(layer);
assert.equal(circle._cache.canvas, undefined);
circle.cache({
x: -74,
y: -74,
width: 148,
height: 148,
drawBorder: true
}).offset({
x: 74,
y: 74
});
assert.notEqual(circle._cache.canvas.scene, undefined);
assert.notEqual(circle._cache.canvas.hit, undefined);
layer.draw();
showHit(layer);
//console.log(circle._cache.canvas.scene.getContext().getTrace());
// make sure the border rectangle was drawn onto the cached scene canvas
assert.equal(circle._cache.canvas.scene.getContext().getTrace(),'save();save();beginPath();rect(0,0,148,148);closePath();strokeStyle=red;lineWidth=5;stroke();restore();translate(74,74);translate(-200,-74);save();transform(1,0,0,1,200,74);beginPath();arc(0,0,70,0,6.283,false);closePath();fillStyle=green;fill();lineWidth=4;strokeStyle=black;stroke();restore();restore();');
});
test('cache group', function(){
var stage = addStage();
var layer = new Konva.Layer();
var group = new Konva.Group({
x: 100,
y: 100,
draggable: true
});
var top = new Konva.Circle({
x: 0,
y: -70,
radius: 30,
fill: 'green',
stroke: 'black',
strokeWidth: 4
});
var right = new Konva.Circle({
x: 70,
y: 0,
radius: 30,
fill: 'red',
stroke: 'black',
strokeWidth: 4
});
var bottom = new Konva.Circle({
x: 0,
y: 70,
radius: 30,
fill: 'blue',
stroke: 'black',
strokeWidth: 4
});
var left = new Konva.Circle({
x: -70,
y: 0,
radius: 30,
fill: 'yellow',
stroke: 'black',
strokeWidth: 4
});
group.add(top).add(right).add(bottom).add(left);
layer.add(group);
stage.add(layer);
//console.log('---before cache')
assert.equal(group._cache.canvas, undefined);
group.cache({
width: 80,
height: 80
});
assert.notEqual(group._cache.canvas.scene, undefined);
assert.notEqual(group._cache.canvas.hit, undefined);
//console.log('---before first draw')
layer.draw();
//console.log(layer.getContext().getTrace())
//document.body.appendChild(group._cache.canvas.scene._canvas);
//console.log('---before second draw')
layer.draw();
assert.equal(layer.getContext().getTrace(), 'clearRect(0,0,578,200);save();transform(1,0,0,1,100,30);beginPath();arc(0,0,30,0,6.283,false);closePath();fillStyle=green;fill();lineWidth=4;strokeStyle=black;stroke();restore();save();transform(1,0,0,1,170,100);beginPath();arc(0,0,30,0,6.283,false);closePath();fillStyle=red;fill();lineWidth=4;strokeStyle=black;stroke();restore();save();transform(1,0,0,1,100,170);beginPath();arc(0,0,30,0,6.283,false);closePath();fillStyle=blue;fill();lineWidth=4;strokeStyle=black;stroke();restore();save();transform(1,0,0,1,30,100);beginPath();arc(0,0,30,0,6.283,false);closePath();fillStyle=yellow;fill();lineWidth=4;strokeStyle=black;stroke();restore();clearRect(0,0,578,200);save();transform(1,0,0,1,100,100);drawImage([object HTMLCanvasElement],0,0);restore();clearRect(0,0,578,200);save();transform(1,0,0,1,100,100);drawImage([object HTMLCanvasElement],0,0);restore();');
showHit(layer);
});
test('cache transformed group', function(){
var stage = addStage();
var layer = new Konva.Layer();
var group = new Konva.Group({
x: 100,
y: 100,
draggable: true,
rotation: 20,
scaleX: 2,
scaleY: 2
});
var top = new Konva.Circle({
x: 0,
y: -70,
radius: 50,
fill: 'green',
stroke: 'black',
strokeWidth: 4
});
var right = new Konva.Circle({
x: 70,
y: 0,
radius: 30,
fill: 'red',
stroke: 'black',
strokeWidth: 4
});
var bottom = new Konva.Circle({
x: 0,
y: 70,
radius: 30,
fill: 'blue',
stroke: 'black',
strokeWidth: 4
});
var left = new Konva.Circle({
x: -70,
y: 0,
radius: 30,
fill: 'yellow',
stroke: 'black',
strokeWidth: 4
});
group.add(top).add(right).add(bottom).add(left);
layer.add(group);
stage.add(layer);
//console.log('---before cache')
//console.log(group.getAbsoluteTransform().getTranslation())
group.cache({
x: -104,
y: -104,
width: 208,
height: 208
});
group.offsetX(104).offsetY(104);
//console.log('--after cache');
//console.log(group.getAbsoluteTransform().getTranslation())
//console.log(group.getAbsolutePosition());
//console.log('---before first draw')
layer.draw();
//document.body.appendChild(group._cache.canvas.scene._canvas);
//console.log('---before second draw')
layer.draw();
//console.log(layer.getContext().getTrace())
assert.equal(layer.getContext().getTrace(), 'clearRect(0,0,578,200);save();transform(1.879,0.684,-0.684,1.879,147.883,-31.557);beginPath();arc(0,0,50,0,6.283,false);closePath();fillStyle=green;fill();lineWidth=4;strokeStyle=black;stroke();restore();save();transform(1.879,0.684,-0.684,1.879,231.557,147.883);beginPath();arc(0,0,30,0,6.283,false);closePath();fillStyle=red;fill();lineWidth=4;strokeStyle=black;stroke();restore();save();transform(1.879,0.684,-0.684,1.879,52.117,231.557);beginPath();arc(0,0,30,0,6.283,false);closePath();fillStyle=blue;fill();lineWidth=4;strokeStyle=black;stroke();restore();save();transform(1.879,0.684,-0.684,1.879,-31.557,52.117);beginPath();arc(0,0,30,0,6.283,false);closePath();fillStyle=yellow;fill();lineWidth=4;strokeStyle=black;stroke();restore();clearRect(0,0,578,200);save();transform(1.879,0.684,-0.684,1.879,-24.316,-166.596);drawImage([object HTMLCanvasElement],0,0);restore();clearRect(0,0,578,200);save();transform(1.879,0.684,-0.684,1.879,-24.316,-166.596);drawImage([object HTMLCanvasElement],0,0);restore();');
showHit(layer);
});
test('cache layer', function(){
var stage = addStage();
var layer = new Konva.Layer({
x: 100,
y: 100,
draggable: true
});
var group = new Konva.Group();
var top = new Konva.Circle({
x: 0,
y: -70,
radius: 30,
fill: 'green',
stroke: 'black',
strokeWidth: 4
});
var right = new Konva.Circle({
x: 70,
y: 0,
radius: 30,
fill: 'red',
stroke: 'black',
strokeWidth: 4
});
var bottom = new Konva.Circle({
x: 0,
y: 70,
radius: 30,
fill: 'blue',
stroke: 'black',
strokeWidth: 4
});
var left = new Konva.Circle({
x: -70,
y: 0,
radius: 30,
fill: 'yellow',
stroke: 'black',
strokeWidth: 4
});
group.add(top).add(right).add(bottom).add(left);
layer.add(group);
stage.add(layer);
assert.equal(layer._cache.canvas, undefined);
layer.cache({
width: 80,
height: 80
});
assert.notEqual(layer._cache.canvas.scene, undefined);
assert.notEqual(layer._cache.canvas.hit, undefined);
layer.draw();
layer.draw();
//console.log(layer.getContext().getTrace());
assert.equal(layer.getContext().getTrace(), 'clearRect(0,0,578,200);save();transform(1,0,0,1,100,30);beginPath();arc(0,0,30,0,6.283,false);closePath();fillStyle=green;fill();lineWidth=4;strokeStyle=black;stroke();restore();save();transform(1,0,0,1,170,100);beginPath();arc(0,0,30,0,6.283,false);closePath();fillStyle=red;fill();lineWidth=4;strokeStyle=black;stroke();restore();save();transform(1,0,0,1,100,170);beginPath();arc(0,0,30,0,6.283,false);closePath();fillStyle=blue;fill();lineWidth=4;strokeStyle=black;stroke();restore();save();transform(1,0,0,1,30,100);beginPath();arc(0,0,30,0,6.283,false);closePath();fillStyle=yellow;fill();lineWidth=4;strokeStyle=black;stroke();restore();clearRect(0,0,578,200);save();transform(1,0,0,1,100,100);drawImage([object HTMLCanvasElement],0,0);restore();clearRect(0,0,578,200);save();transform(1,0,0,1,100,100);drawImage([object HTMLCanvasElement],0,0);restore();');
// make sure that the hit graph is also rendered after caching the layer
assert.equal(layer.hitCanvas.getContext().getTrace(true), 'clearRect();save();transform();beginPath();arc();closePath();save();fillStyle;fill();restore();lineWidth;strokeStyle;stroke();restore();save();transform();beginPath();arc();closePath();save();fillStyle;fill();restore();lineWidth;strokeStyle;stroke();restore();save();transform();beginPath();arc();closePath();save();fillStyle;fill();restore();lineWidth;strokeStyle;stroke();restore();save();transform();beginPath();arc();closePath();save();fillStyle;fill();restore();lineWidth;strokeStyle;stroke();restore();clearRect();clearRect();save();transform();drawImage();restore();clearRect();save();transform();drawImage();restore();');
showHit(layer);
});
test('stage.toObject() when stage contains an image', function(done){

View File

@ -99,4 +99,122 @@ suite('Label', function() {
assert.equal(stage.find('Label')[0], label);
});
test('cache label', function() {
var stage = addStage();
var layer = new Konva.Layer();
// tooltip
var tooltip = new Konva.Label({
x: 170,
y: 75,
opacity: 0.75
});
tooltip.add(new Konva.Tag({
fill: 'black',
pointerDirection: 'down',
pointerWidth: 10,
pointerHeight: 10,
lineJoin: 'round',
shadowColor: 'black',
shadowBlur: 10,
shadowOffset: 10,
shadowOpacity: 0.5
}));
tooltip.add(new Konva.Text({
text: 'Tooltip pointing down',
fontFamily: 'Calibri',
fontSize: 18,
padding: 5,
fill: 'white'
}));
var tooltipUp = new Konva.Label({
x: 170,
y: 75,
opacity: 0.75
});
tooltipUp.add(new Konva.Tag({
fill: 'black',
pointerDirection: 'up',
pointerWidth: 10,
pointerHeight: 10,
lineJoin: 'round',
shadowColor: 'black',
shadowBlur: 10,
shadowOffset: 10,
shadowOpacity: 0.5
}));
tooltipUp.add(new Konva.Text({
text: 'Tooltip pointing up',
fontFamily: 'Calibri',
fontSize: 18,
padding: 5,
fill: 'white'
}));
// label with left pointer
var labelLeft = new Konva.Label({
x: 20,
y: 130,
opacity: 0.75
});
labelLeft.add(new Konva.Tag({
fill: 'green',
pointerDirection: 'left',
pointerWidth: 30,
pointerHeight: 28,
lineJoin: 'round'
}));
labelLeft.add(new Konva.Text({
text: 'Label pointing left',
fontFamily: 'Calibri',
fontSize: 18,
padding: 5,
fill: 'white'
}));
// label with left pointer
var labelRight = new Konva.Label({
x: 160,
y: 170,
offsetX : 20,
opacity: 0.75
});
labelRight.add(new Konva.Tag({
fill: 'green',
pointerDirection: 'right',
pointerWidth: 20,
pointerHeight: 28,
lineJoin: 'round'
}));
labelRight.add(new Konva.Text({
text: 'Label right',
fontFamily: 'Calibri',
fontSize: 18,
padding: 5,
fill: 'white'
}));
// simple label
var simpleLabel = new Konva.Label({
x: 180,
y: 150,
opacity: 0.75
});
simpleLabel.add(new Konva.Tag({
fill: 'yellow'
}));
simpleLabel.add(new Konva.Text({
text: 'Simple label',
fontFamily: 'Calibri',
fontSize: 18,
padding: 5,
fill: 'black'
}));
// add the labels to layer
layer.add(tooltip, tooltipUp, labelLeft, labelRight, simpleLabel);
layer.children.cache();
stage.add(layer);
cloneAndCompareLayer(layer, 150);
});
});

View File

@ -102,6 +102,32 @@ suite('Path', function() {
stage.add(layer);
});
//=======================================================
test('complex path made of many different closed and open paths (Sopwith Camel) cached', function() {
var stage = addStage();
var layer = new Konva.Layer();
var path = new Konva.Path({
data: 'm 15.749277,58.447629 8.495831,-0.05348 m 0.319898,-15.826548 -0.202438,17.295748 0.942206,0.941911 1.345933,-1.816987 0.20211,-11.642611 z m 77.458374,28.680768 c 0,5.308829 -4.303525,9.612686 -9.612485,9.612686 -5.30873,0 -9.612194,-4.303857 -9.612194,-9.612686 0,-5.308829 4.303464,-9.61226 9.612194,-9.61226 5.30896,0 9.612485,4.303431 9.612485,9.61226 z m -3.520874,0 c 0,3.364079 -2.72763,6.091348 -6.091611,6.091348 -3.364243,0 -6.091119,-2.727269 -6.091119,-6.091348 0,-3.363719 2.726876,-6.090791 6.091119,-6.090791 3.363981,0 6.091611,2.727072 6.091611,6.090791 z m -3.997576,0 c 0,1.156718 -0.937743,2.093937 -2.094035,2.093937 -1.156062,0 -2.093871,-0.937219 -2.093871,-2.093937 0,-1.156357 0.937809,-2.093773 2.093871,-2.093773 1.156292,0 2.094035,0.937416 2.094035,2.093773 z m 45.77821,4.283023 c -0.24607,1.90039 5.06492,3.680204 7.61403,5.520093 0.50662,0.514199 0.27889,0.975967 -0.0984,1.427532 l 3.9019,-1.141987 c -0.59258,-0.121397 -1.85951,0.01969 -1.71294,-0.380038 -0.85894,-1.950525 -3.68693,-2.761261 -5.61518,-4.092495 -1.06971,-1.03496 0.0997,-1.60766 0.76126,-2.284203 z M 43.206396,42.60133 55.578964,74.008743 58.71987,73.910313 47.203939,44.40726 c -1.109013,-0.737406 -1.174108,-2.1004 -3.997543,-1.808752 z m -18.654022,-0.570632 12.467721,31.692335 3.140643,0.09843 -12.467656,-31.692927 z m 2.285318,42.353106 -2.636648,-0.06431 0.163066,0.734584 3.709372,9.956142 2.357927,-1.168202 z m 19.411934,0.566268 -6.370726,9.901284 2.090163,1.615665 7.13671,-11.417403 0.303821,-0.4347 -2.942667,-0.02953 z m -12.091915,8.286013 c -5.729323,0 -10.367941,4.560169 -10.367941,10.184405 0,5.62429 4.638618,10.18489 10.367941,10.18489 5.729424,0 10.37654,-4.5606 10.37654,-10.18489 0,-5.624236 -4.647083,-10.184405 -10.37654,-10.184405 z m 0,2.473319 c 4.310029,0 7.811352,3.453552 7.811352,7.711086 0,4.25776 -3.50129,7.71167 -7.811352,7.71167 -4.310157,0 -7.803016,-3.45391 -7.803016,-7.71167 0,-4.257534 3.492859,-7.711086 7.803016,-7.711086 z m 3.528526,-21.795876 c -1.29032,-0.0066 -2.97525,0.03839 -3.402437,1.45155 l -0.01969,7.494437 c 0.586775,0.761915 1.42432,0.688978 2.236565,0.71411 l 26.529545,-0.14502 8.636784,0.761324 0,-7.518487 C 71.56989,75.908478 71.09444,75.467051 70.239377,75.338961 61.126027,73.734287 49.244756,73.929146 37.690371,73.911166 z M 20.959576,41.269176 c -0.0098,0.603377 0.575258,0.881409 0.575258,0.881409 L 58.95771,42.33629 c -4.893946,-0.985482 -16.592629,-2.859625 -32.835015,-2.783473 -1.570354,0.107617 -5.151439,1.109571 -5.163119,1.712718 z m 3.353022,14.276273 c -2.79955,0.01312 -5.595489,0.02953 -8.382964,0.05545 l 0,9.9e-5 0.0033,1.447677 -1.173484,0.01312 0.0066,1.244485 1.184048,0.05807 c -1.34298,0.220812 -2.956414,1.305807 -3.054779,3.476618 0.0098,3.269061 0.01312,6.538943 0.01312,9.808103 l -1.21197,0.0033 -0.01969,-2.361569 -4.6851755,0.0033 0,5.901969 4.6323185,0.0066 -0.02953,-1.7556 1.308596,-0.02297 0.0098,9.180447 c -0.0066,1.315781 2.739048,3.634336 4.542583,3.634336 l 4.811756,-2.995032 c 1.616583,-0.107617 1.758126,0.482078 1.884346,1.076924 l 35.667571,0.318914 6.909664,-0.81031 m 4.994738,-0.585889 85.216614,-9.991675 c 4.93952,-0.487623 14.9162,-22.255511 -3.75098,-25.556727 -5.12814,-0.887479 -15.53194,4.839613 -21.44018,9.104984 -2.31314,1.954593 -1.74166,4.084194 0.0263,5.982879 l -72.209399,-8.111923 -2.12281,-0.0012 c -0.966453,1.390128 -3.158262,3.260465 -4.554559,4.053123 M 49.36027,58.361483 c -1.699757,-1.038536 -2.965602,-2.804438 -4.533856,-2.875275 -3.903936,0.0011 -7.904399,0.0066 -11.882849,0.01312 m -3.081192,0.0066 c -1.043195,0.0033 -2.082715,0.0066 -3.116396,0.0098',
stroke: '#000',
strokeWidth: 1,
lineCap: 'round',
lineJoin: 'round',
draggable : true
});
layer.add(path);
stage.add(layer);
path.cache();
layer.draw();
// layer.draw();
cloneAndCompareLayer(layer, 230);
showHit(layer)
});
@ -404,6 +430,29 @@ suite('Path', function() {
showHit(layer);
});
// ======================================================
test.skip('Tiger (RAWR!) cached', function() {
var stage = addStage();
var layer = new Konva.Layer();
var group = new Konva.Group();
for(var i = 0; i < tiger.length; i++) {
var path = new Konva.Path(tiger[i]);
group.add(path);
}
group.setDraggable(true);
layer.add(group);
stage.add(layer);
group.cache();
layer.draw();
showHit(layer);
cloneAndCompareLayer(layer, 200);
});
// ======================================================
test('Able to determine point on line some distance from another point on line', function() {

View File

@ -86,5 +86,65 @@ suite('RegularPolygon', function() {
layer.add(poly);
stage.add(layer);
});
// ======================================================
test('attr sync', function() {
var stage = addStage();
var layer = new Konva.Layer();
var poly = new Konva.RegularPolygon({
x: 200,
y: 100,
sides: 5,
radius: 50,
fill: 'green',
stroke: 'blue',
strokeWidth: 5,
name: 'foobar'
});
layer.add(poly);
stage.add(layer);
assert.equal(poly.getWidth(), 100);
assert.equal(poly.getHeight(), 100);
poly.setWidth(120);
assert.equal(poly.radius(), 60);
assert.equal(poly.getHeight(), 120);
poly.setHeight(140);
assert.equal(poly.radius(), 70);
assert.equal(poly.getHeight(), 140);
});
test('polygon cache', function() {
var stage = addStage();
var layer = new Konva.Layer();
var poly = new Konva.RegularPolygon({
x: 200,
y: 100,
sides: 5,
radius: 50,
fill: 'green',
stroke: 'blue',
strokeWidth: 5,
name: 'foobar'
});
poly.cache();
layer.add(poly);
stage.add(layer);
assert.deepEqual(poly.getSelfRect(), {
x : -50,
y : -50,
height : 100,
width : 100
});
if (!window.mochaPhantomJS) {
cloneAndCompareLayer(layer, 50);
}
});
});

View File

@ -53,7 +53,7 @@ suite('Star', function() {
fill: 'green',
stroke: 'blue',
strokeWidth: 5,
lineJoin: "round",
lineJoin: 'round',
shadowColor: 'black',
shadowBlur: 10,
shadowOffset: [20, 20],
@ -72,4 +72,77 @@ suite('Star', function() {
star.setLineJoin('round');
});
// ======================================================
test('attr sync', function() {
var stage = addStage();
var layer = new Konva.Layer();
var star = new Konva.Star({
x: 200,
y: 100,
numPoints: 5,
innerRadius: 30,
outerRadius: 50,
fill: 'green',
stroke: 'blue',
strokeWidth: 5,
lineJoin: 'round',
shadowColor: 'black',
shadowBlur: 10,
shadowOffset: [20, 20],
shadowOpacity: 0.5,
draggable: true
});
layer.add(star);
stage.add(layer);
assert.equal(star.getWidth(), 100);
assert.equal(star.getHeight(), 100);
star.setWidth(120);
assert.equal(star.outerRadius(), 60);
assert.equal(star.getHeight(), 120);
star.setHeight(140);
assert.equal(star.outerRadius(), 70);
assert.equal(star.getHeight(), 140);
});
// ======================================================
test('star cache', function() {
var stage = addStage();
var layer = new Konva.Layer();
var star = new Konva.Star({
x: 200,
y: 100,
numPoints: 5,
innerRadius: 30,
outerRadius: 50,
fill: 'green',
stroke: 'blue',
strokeWidth: 5,
lineJoin: 'round',
shadowColor: 'black',
shadowBlur: 10,
shadowOffset: [20, 20],
shadowOpacity: 0.5,
draggable: true
});
layer.add(star);
star.cache();
stage.add(layer);
assert.deepEqual(star.getSelfRect(), {
x : -50,
y : -50,
height : 100,
width : 100
});
cloneAndCompareLayer(layer, 50);
});
});

View File

@ -188,4 +188,31 @@ suite('TextPath', function() {
layer.add(textpath);
stage.add(layer);
});
// ======================================================
test('Render Text Along complex path cached', function() {
var stage = addStage();
var layer = new Konva.Layer();
var c = "M10,10 C0,0 10,150 100,100 S300,150 400,50";
var textpath = new Konva.TextPath({
stroke: 'black',
strokeWidth: 1,
fill: 'orange',
fontSize: 10,
fontFamily: 'Arial',
text: 'All the world\'s a stage, and all the men and women merely players. They have their exits and their entrances; And one man in his time plays many parts.',
data: c,
draggable : true
});
textpath.cache();
layer.add(textpath);
stage.add(layer);
cloneAndCompareLayer(layer,50);
showHit(layer);
});
});

View File

@ -26,4 +26,92 @@ suite('Arc', function() {
assert.equal(trace, 'clearRect(0,0,578,200);save();transform(1,0,0,1,100,100);beginPath();arc(0,0,80,0,1.571,false);arc(0,0,50,1.571,0,true);closePath();fillStyle=green;fill();lineWidth=4;strokeStyle=black;stroke();restore();');
});
// ======================================================
test('attrs sync', function() {
var stage = addStage();
var layer = new Konva.Layer();
var arc = new Konva.Arc({
x: 100,
y: 100,
innerRadius: 50,
outerRadius: 80,
angle: 90,
fill: 'green',
stroke: 'black',
strokeWidth: 4,
name: 'myArc',
draggable: true
});
layer.add(arc);
stage.add(layer);
assert.equal(arc.getWidth(), 160);
assert.equal(arc.getHeight(), 160);
arc.setWidth(100);
assert.equal(arc.outerRadius(), 50);
assert.equal(arc.getHeight(), 100);
arc.setHeight(120);
assert.equal(arc.outerRadius(), 60);
assert.equal(arc.getHeight(), 120);
});
test('getSelfRect', function() {
var stage = addStage();
var layer = new Konva.Layer();
var arc = new Konva.Arc({
x: 100,
y: 100,
innerRadius: 50,
outerRadius: 80,
angle: 90,
fill: 'green',
stroke: 'black',
strokeWidth: 4,
name: 'myArc',
draggable: true
});
layer.add(arc);
stage.add(layer);
assert.deepEqual(arc.getSelfRect(), {
x : -80,
y : -80,
width : 160,
height : 160
});
});
test('cache', function() {
var stage = addStage();
var layer = new Konva.Layer();
var arc = new Konva.Arc({
x: 100,
y: 100,
innerRadius: 50,
outerRadius: 80,
angle: 90,
fill: 'green',
stroke: 'black',
strokeWidth: 4,
});
layer.add(arc);
stage.add(layer);
var canvas = createCanvas();
var context = canvas.getContext('2d');
context.beginPath();
context.arc(100, 100, 80, 0, Math.PI / 2, false);
context.arc(100, 100, 50, Math.PI / 2, 0, true);
context.closePath();
context.fillStyle = 'green';
context.fill();
context.lineWidth = 4;
context.stroke();
compareLayerAndCanvas(layer, canvas, 10);
});
});

View File

@ -91,4 +91,27 @@ suite('Blob', function(){
assert.equal(blob.eventListeners.pointsChange, undefined);
assert.equal(blob.eventListeners.tensionChange, undefined);
});
test('cache', function() {
var stage = addStage();
var layer = new Konva.Layer();
var blob = new Konva.Line({
x : 50,
y : 50,
points: [-25,50,250,-30,150,50,250,110],
stroke: 'blue',
strokeWidth: 10,
draggable: true,
fill: '#aaf',
tension: 0.3,
closed: true
});
blob.cache();
layer.add(blob);
stage.add(layer);
if (!window.mochaPhantomJS) {
cloneAndCompareLayer(layer, 50);
}
});
});

View File

@ -188,7 +188,6 @@ suite('Circle', function(){
stage.add(layer);
assert.equal(circle.getWidth(), 140);
assert.equal(circle.attrs.height, 140);
assert.equal(circle.getHeight(), 140);
circle.setWidth(100);
@ -218,4 +217,55 @@ suite('Circle', function(){
stage.add(layer);
});
test('getSelfRect', function() {
var stage = addStage();
var layer = new Konva.Layer();
var circle = new Konva.Circle({
x: 100,
y: 100,
radius: 50,
fill: 'green',
stroke: 'black',
strokeWidth: 4,
draggable: true
});
layer.add(circle);
stage.add(layer);
assert.deepEqual(circle.getSelfRect(), {
x : -50,
y : -50,
width : 100,
height : 100
});
});
test('cache', function() {
var stage = addStage();
var layer = new Konva.Layer();
var circle = new Konva.Circle({
x: 100,
y: 100,
radius: 50,
fill: 'green',
stroke: 'black',
strokeWidth: 4
});
layer.add(circle);
stage.add(layer);
var canvas = createCanvas();
var context = canvas.getContext('2d');
context.beginPath();
context.arc(100, 100, 50, 0, Math.PI * 2, false);
context.closePath();
context.fillStyle = 'green';
context.fill();
context.lineWidth = 4;
context.stroke();
compareLayerAndCanvas(layer, canvas, 50);
});
});

View File

@ -1,7 +1,7 @@
suite('Ellipse', function(){
// ======================================================
test('add ellipse', function(){
// ======================================================
test('add ellipse', function(){
var stage = addStage();
var layer = new Konva.Layer();
var ellipse = new Konva.Ellipse({
@ -18,5 +18,84 @@ suite('Ellipse', function(){
var trace = layer.getContext().getTrace();
assert.equal(trace, 'clearRect(0,0,578,200);save();transform(1,0,0,1,289,100);beginPath();save();scale(1,0.5);arc(0,0,70,0,6.283,false);restore();closePath();fillStyle=green;fill();lineWidth=8;strokeStyle=black;stroke();restore();');
});
});
// ======================================================
test('attrs sync', function() {
var stage = addStage();
var layer = new Konva.Layer();
var ellipse = new Konva.Ellipse({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
radius: {x:70, y:35},
fill: 'green',
stroke: 'black',
strokeWidth: 8
});
layer.add(ellipse);
stage.add(layer);
assert.equal(ellipse.getWidth(), 140);
assert.equal(ellipse.getHeight(), 70);
ellipse.setWidth(100);
assert.equal(ellipse.radiusX(), 50);
assert.equal(ellipse.radiusY(), 35);
ellipse.setHeight(120);
assert.equal(ellipse.radiusX(), 50);
assert.equal(ellipse.radiusY(), 60);
});
test('getSelfRect', function() {
var stage = addStage();
var layer = new Konva.Layer();
var ellipse = new Konva.Ellipse({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
radius: {x:70, y:35},
fill: 'green',
stroke: 'black',
strokeWidth: 8
});
layer.add(ellipse);
stage.add(layer);
assert.deepEqual(ellipse.getSelfRect(), {
x : -70,
y : -35,
width : 140,
height : 70
});
});
test('cache', function() {
var stage = addStage();
var layer = new Konva.Layer();
var ellipse = new Konva.Ellipse({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
radius: {x:70, y:35},
fill: 'green',
stroke: 'black',
strokeWidth: 8
});
ellipse.cache();
layer.add(ellipse);
stage.add(layer);
var canvas = createCanvas();
var context = canvas.getContext('2d');
context.save();
context.beginPath();
context.scale(1, 0.5);
context.arc(stage.getWidth() / 2, stage.getHeight(), 70, 0, Math.PI * 2, false);
context.closePath();
context.restore();
context.fillStyle = 'green';
context.fill();
context.lineWidth = 8;
context.stroke();
compareLayerAndCanvas(layer, canvas, 50);
});
});

View File

@ -312,4 +312,38 @@ suite('Image', function(){
};
imageObj.src = 'assets/darth-vader.jpg';
});
// ======================================================
test('image caching', function(done) {
var imageObj = new Image();
imageObj.onload = function() {
var stage = addStage();
var layer = new Konva.Layer();
var darth = new Konva.Image({
x: 200,
y: 60,
image: imageObj,
width: 100,
height: 100,
draggable: true
});
darth.cache();
layer.add(darth);
stage.add(layer);
assert.deepEqual(darth.getSelfRect(), {
x : 0, y : 0, width : 100, height : 100
});
var canvas = createCanvas();
var context = canvas.getContext('2d');
context.drawImage(imageObj, 200, 60, 100, 100);
compareLayerAndCanvas(layer, canvas, 10);
done();
};
imageObj.src = 'assets/darth-vader.jpg';
});
});

View File

@ -205,4 +205,73 @@ suite('Line', function() {
});
assert.equal(shape, line1, 'first line detected');
});
test('line get size', function() {
var stage = addStage();
var layer = new Konva.Layer();
var line = new Konva.Line({
points: [73, 160, 340, 23, 500, 109, 500, 180],
stroke: 'blue',
strokeWidth: 10
});
layer.add(line);
stage.add(layer);
assert.deepEqual(line.size(), {
width : 500 - 73,
height : 180 - 23
});
});
test('getSelfRect', function() {
var stage = addStage();
var layer = new Konva.Layer();
var blob = new Konva.Line({
x : 50,
y : 50,
points: [-25,50,250,-30,150,50,250,110],
stroke: 'blue',
strokeWidth: 10,
draggable: true,
fill: '#aaf',
closed: true
});
layer.add(blob);
stage.add(layer);
assert.deepEqual(blob.getSelfRect(), {
x : -25,
y : -30,
width : 275,
height : 140
});
});
test('line caching', function() {
var stage = addStage();
var layer = new Konva.Layer();
var blob = new Konva.Line({
x : 50,
y : 50,
points: [-25,50,250,-30,150,50,250,110],
stroke: 'blue',
strokeWidth: 10,
draggable: true,
closed : true
});
layer.add(blob);
var layer2 = layer.clone();
blob.cache({
offset : 30
});
stage.add(layer);
stage.add(layer2);
layer2.hide();
compareLayers(layer, layer2);
});
});

View File

@ -23,7 +23,6 @@ suite('Ring', function() {
});
// ======================================================
// test for https://github.com/ericdrowell/KonvaJS/issues/987
test('ring attrs sync', function() {
var stage = addStage();
var layer = new Konva.Layer();
@ -31,8 +30,6 @@ suite('Ring', function() {
name: 'ring',
x: 30,
y: 50,
width: 50,
height: 50,
innerRadius: 15,
outerRadius: 30,
fill: 'green',
@ -43,11 +40,50 @@ suite('Ring', function() {
layer.add(ring);
stage.add(layer);
assert(ring.width(),60);
assert(ring.height(), 60);
var cring = ring.clone();
assert.equal(cring.outerRadius(), ring.outerRadius());
ring.height(100);
assert(ring.width(), 100);
assert(ring.outerRadius(), 50);
assert.equal(ring.attrs.width, ring.outerRadius() * 2);
ring.width(120);
assert(ring.height(), 120);
assert(ring.outerRadius(), 60);
});
test('ring cache', function() {
var stage = addStage();
var layer = new Konva.Layer();
var ring = new Konva.Ring({
name: 'ring',
x: 30,
y: 50,
innerRadius: 15,
outerRadius: 30,
fill: 'green',
stroke: 'black',
strokeWidth: 4,
draggable: true
});
layer.add(ring);
stage.add(layer);
assert.deepEqual(ring.getSelfRect(), {
x : -30,
y : -30,
width : 60,
height : 60
});
var layer2 = layer.clone();
stage.add(layer2);
layer2.hide();
compareLayers(layer, layer2);
});
});

View File

@ -344,5 +344,27 @@ suite('Text', function(){
compareLayerAndCanvas(layer, canvas);
});
test('text getSelfRect', function() {
var stage = addStage();
var layer = new Konva.Layer();
var text = new Konva.Text({
fontSize: 50,
y : 50,
x : 50,
fill: 'black',
text: 'text'
});
layer.add(text);
stage.add(layer);
var rect = text.getSelfRect();
assert.deepEqual(rect, {
x : 0,y : 0, width : text.width(), height : 50
});
});
});

View File

@ -25,4 +25,56 @@ suite('Wedge', function() {
assert.equal(trace, 'clearRect(0,0,578,200);save();transform(1,0,0,1,100,100);beginPath();arc(0,0,70,0,1.257,false);lineTo(0,0);closePath();fillStyle=green;fill();lineWidth=4;strokeStyle=black;stroke();restore();');
});
test('attrs sync', function() {
var stage = addStage();
var layer = new Konva.Layer();
var wedge = new Konva.Wedge({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
angle: 180 * 0.4,
radius: 70,
fill: 'green',
stroke: 'black',
strokeWidth: 4
});
layer.add(wedge);
stage.add(layer);
assert.equal(wedge.getWidth(), 140);
assert.equal(wedge.getHeight(), 140);
wedge.setWidth(100);
assert.equal(wedge.radius(), 50);
assert.equal(wedge.getHeight(), 100);
wedge.setHeight(120);
assert.equal(wedge.radius(), 60);
assert.equal(wedge.getHeight(), 120);
});
test('getSelfRect', function() {
var stage = addStage();
var layer = new Konva.Layer();
var wedge = new Konva.Wedge({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
angle: 180 * 0.4,
radius: 70,
fill: 'green',
stroke: 'black',
strokeWidth: 4
});
layer.add(wedge);
stage.add(layer);
assert.deepEqual(wedge.getSelfRect(), {
x : -70,
y : -70,
width : 140,
height : 140
});
});
});