new Canvas class to decouple layer and canvas, providing more flexibility. drawing operations now require a canvas object rather than an optional layer which contained a canvas. fixed some transformation issues introduced with a pull request that I pulled in last week

This commit is contained in:
Eric Rowell 2012-07-18 23:28:45 -07:00
parent 20adf7e036
commit d8bbbf6353
24 changed files with 548 additions and 555 deletions

View File

@ -3,7 +3,7 @@ require 'json/pure'
class Build < Thor class Build < Thor
# This is the list of files to concatenate. The first file will appear at the top of the final file. All files are relative to the lib directory. # This is the list of files to concatenate. The first file will appear at the top of the final file. All files are relative to the lib directory.
FILES = [ FILES = [
"license.js", "src/Global.js", "src/util/Type.js", "src/util/Class.js", "src/Animation.js", "src/Node.js", "src/Container.js", "src/Stage.js", "license.js", "src/Global.js", "src/util/Type.js", "src/util/Canvas.js", "src/util/Class.js", "src/Animation.js", "src/Node.js", "src/Container.js", "src/Stage.js",
"src/Layer.js", "src/Group.js", "src/Shape.js", "src/shapes/Rect.js", "src/shapes/Ellipse.js", "src/shapes/Image.js", "src/Layer.js", "src/Group.js", "src/Shape.js", "src/shapes/Rect.js", "src/shapes/Ellipse.js", "src/shapes/Image.js",
"src/shapes/Sprite.js", "src/shapes/Polygon.js", "src/shapes/RegularPolygon.js", "src/shapes/Star.js", "src/shapes/Text.js", "src/shapes/Sprite.js", "src/shapes/Polygon.js", "src/shapes/RegularPolygon.js", "src/shapes/Star.js", "src/shapes/Text.js",
"src/shapes/Line.js", "src/shapes/Path.js", "src/util/Transform.js", "src/Transition.js", "src/util/Tween.js", "src/filters/Grayscale.js" "src/shapes/Line.js", "src/shapes/Path.js", "src/util/Transform.js", "src/Transition.js", "src/util/Tween.js", "src/filters/Grayscale.js"

523
dist/kinetic-core.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -211,18 +211,18 @@ Kinetic.Container = Kinetic.Node.extend({
/** /**
* draw children * draw children
*/ */
_drawChildren: function(layer) { _drawChildren: function(canvas) {
var stage = this.getStage(); var stage = this.getStage();
var children = this.children; var children = this.children;
for(var n = 0; n < children.length; n++) { for(var n = 0; n < children.length; n++) {
var child = children[n]; var child = children[n];
if(child.nodeType === 'Shape') { if(child.nodeType === 'Shape') {
if(child.isVisible() && stage.isVisible()) { if(child.isVisible() && stage.isVisible()) {
child._draw( layer ? layer : child.getLayer()); child._draw(canvas);
} }
} }
else { else {
child.draw(layer); child.draw(canvas);
} }
} }
}, },
@ -230,27 +230,8 @@ Kinetic.Container = Kinetic.Node.extend({
* set children indices * set children indices
*/ */
_setChildrenIndices: function() { _setChildrenIndices: function() {
/*
* if reordering Layers, remove all canvas elements
* from the container except the buffer and backstage canvases
* and then readd all the layers
*/
if(this.nodeType === 'Stage') {
var canvases = this.content.children;
var bufferCanvas = canvases[0];
var backstageCanvas = canvases[1];
this.content.innerHTML = '';
this.content.appendChild(bufferCanvas);
this.content.appendChild(backstageCanvas);
}
for(var n = 0; n < this.children.length; n++) { for(var n = 0; n < this.children.length; n++) {
this.children[n].index = n; this.children[n].index = n;
if(this.nodeType === 'Stage') {
this.content.appendChild(this.children[n].canvas);
}
} }
} }
}); });

View File

@ -14,12 +14,12 @@ Kinetic.Group = Kinetic.Container.extend({
// call super constructor // call super constructor
this._super(config); this._super(config);
}, },
draw: function(layer) { draw: function(canvas) {
this._draw(layer); this._draw(canvas);
}, },
_draw: function(layer) { _draw: function(canvas) {
if(this.attrs.visible) { if(this.attrs.visible) {
this._drawChildren(layer); this._drawChildren(canvas);
} }
} }
}); });

View File

@ -20,9 +20,8 @@ Kinetic.Layer = Kinetic.Container.extend({
this.beforeDrawFunc = undefined; this.beforeDrawFunc = undefined;
this.afterDrawFunc = undefined; this.afterDrawFunc = undefined;
this.canvas = document.createElement('canvas'); this.canvas = new Kinetic.Canvas();
this.context = this.canvas.getContext('2d'); this.canvas.getElement().style.position = 'absolute';
this.canvas.style.position = 'absolute';
// call super constructor // call super constructor
this._super(config); this._super(config);
@ -33,7 +32,7 @@ Kinetic.Layer = Kinetic.Container.extend({
* @name draw * @name draw
* @methodOf Kinetic.Layer.prototype * @methodOf Kinetic.Layer.prototype
*/ */
draw: function(layer) { draw: function(canvas) {
var throttle = this.attrs.throttle; var throttle = this.attrs.throttle;
var date = new Date(); var date = new Date();
var time = date.getTime(); var time = date.getTime();
@ -41,7 +40,7 @@ Kinetic.Layer = Kinetic.Container.extend({
var tt = 1000 / throttle; var tt = 1000 / throttle;
if(timeDiff >= tt || throttle > 200) { if(timeDiff >= tt || throttle > 200) {
this._draw(layer); this._draw(canvas);
if(this.drawTimeout !== undefined) { if(this.drawTimeout !== undefined) {
clearTimeout(this.drawTimeout); clearTimeout(this.drawTimeout);
@ -58,7 +57,7 @@ Kinetic.Layer = Kinetic.Container.extend({
* wait 17ms before trying again (60fps) * wait 17ms before trying again (60fps)
*/ */
this.drawTimeout = setTimeout(function() { this.drawTimeout = setTimeout(function() {
that.draw(layer); that.draw(canvas);
}, 17); }, 17);
} }
}, },
@ -78,19 +77,6 @@ Kinetic.Layer = Kinetic.Container.extend({
afterDraw: function(func) { afterDraw: function(func) {
this.afterDrawFunc = func; this.afterDrawFunc = func;
}, },
/**
* clears the canvas context tied to the layer. Clearing
* a layer does not remove its children. The nodes within
* the layer will be redrawn whenever the .draw() method
* is used again.
* @name clear
* @methodOf Kinetic.Layer.prototype
*/
clear: function() {
var context = this.getContext();
var canvas = this.getCanvas();
context.clearRect(0, 0, canvas.width, canvas.height);
},
/** /**
* get layer canvas * get layer canvas
* @name getCanvas * @name getCanvas
@ -100,12 +86,12 @@ Kinetic.Layer = Kinetic.Container.extend({
return this.canvas; return this.canvas;
}, },
/** /**
* get layer context * get layer canvas context
* @name getContext * @name getContext
* @methodOf Kinetic.Layer.prototype * @methodOf Kinetic.Layer.prototype
*/ */
getContext: function() { getContext: function() {
return this.context; return this.canvas.context;
}, },
/** /**
* Creates a composite data URL. If MIME type is not * Creates a composite data URL. If MIME type is not
@ -115,7 +101,7 @@ Kinetic.Layer = Kinetic.Container.extend({
* based on what's draw on the layer, rather than drawing * based on what's draw on the layer, rather than drawing
* the current state of each child node * the current state of each child node
* @name toDataURL * @name toDataURL
* @methodOf Kinetic.Stage.prototype * @methodOf Kinetic.Layer.prototype
* @param {String} [mimeType] * @param {String} [mimeType]
* @param {Number} [quality] * @param {Number} [quality]
*/ */
@ -123,16 +109,24 @@ Kinetic.Layer = Kinetic.Container.extend({
try { try {
// If this call fails (due to browser bug, like in Firefox 3.6), // If this call fails (due to browser bug, like in Firefox 3.6),
// then revert to previous no-parameter image/png behavior // then revert to previous no-parameter image/png behavior
return this.getCanvas().toDataURL(mimeType, quality); return this.getCanvas().element.toDataURL(mimeType, quality);
} }
catch(e) { catch(e) {
return this.getCanvas().toDataURL(); return this.getCanvas().element.toDataURL();
} }
}, },
/** /**
* private draw children * private draw children
*/ */
_draw: function(layer) { _draw: function(canvas) {
/*
* if canvas is not defined, then use the canvas
* tied to the layer
*/
if(!canvas) {
canvas = this.getCanvas();
}
var date = new Date(); var date = new Date();
var time = date.getTime(); var time = date.getTime();
this.lastDrawTime = time; this.lastDrawTime = time;
@ -143,8 +137,7 @@ Kinetic.Layer = Kinetic.Container.extend({
} }
if(this.attrs.clearBeforeDraw) { if(this.attrs.clearBeforeDraw) {
var clearLayer = layer ? layer : this; canvas.clear();
clearLayer.clear();
} }
if(this.isVisible()) { if(this.isVisible()) {
@ -154,7 +147,7 @@ Kinetic.Layer = Kinetic.Container.extend({
} }
// draw children // draw children
this._drawChildren(layer); this._drawChildren(canvas);
} }
// after draw handler // after draw handler

View File

@ -386,7 +386,10 @@ Kinetic.Node = Kinetic.Class.extend({
* @methodOf Kinetic.Node.prototype * @methodOf Kinetic.Node.prototype
*/ */
getAbsolutePosition: function() { getAbsolutePosition: function() {
return this.getAbsoluteTransform().getTranslation(); var trans = this.getAbsoluteTransform();
var o = this.getOffset();
trans.translate(o.x, o.y);
return trans.getTranslation();
}, },
/** /**
* set absolute position relative to stage * set absolute position relative to stage
@ -416,9 +419,16 @@ Kinetic.Node = Kinetic.Class.extend({
x: 1, x: 1,
y: 1 y: 1
}; };
this.attrs.offset = {
x: 0,
y: 0
};
var o = this.getOffset();
// unravel transform // unravel transform
var it = this.getAbsoluteTransform(); var it = this.getAbsoluteTransform();
it.invert(); it.invert();
it.translate(pos.x, pos.y); it.translate(pos.x, pos.y);
pos = { pos = {
@ -434,6 +444,10 @@ Kinetic.Node = Kinetic.Class.extend({
x: scale.x, x: scale.x,
y: scale.y y: scale.y
}; };
this.attrs.offset = {
x: offset.x,
y: offset.y
};
}, },
/** /**
* move node by an amount * move node by an amount
@ -727,7 +741,6 @@ Kinetic.Node = Kinetic.Class.extend({
for(var n = 0; n < family.length; n++) { for(var n = 0; n < family.length; n++) {
var node = family[n]; var node = family[n];
var m = node.getTransform(); var m = node.getTransform();
am.multiply(m); am.multiply(m);
} }
@ -803,14 +816,14 @@ Kinetic.Node = Kinetic.Class.extend({
saveImageData: function() { saveImageData: function() {
try { try {
var stage = this.getStage(); var stage = this.getStage();
var bufferLayer = stage.bufferLayer; var bufferCanvas = stage.bufferCanvas;
var bufferLayerContext = bufferLayer.getContext(); var bufferContext = bufferCanvas.getContext();
var width = stage.getWidth(); var width = stage.getWidth();
var height = stage.getHeight(); var height = stage.getHeight();
bufferLayer.clear(); bufferCanvas.clear();
this._draw(bufferLayer); this._draw(bufferCanvas);
var imageData = bufferLayerContext.getImageData(0, 0, width, height); var imageData = bufferContext.getImageData(0, 0, width, height);
this.imageData = imageData; this.imageData = imageData;
} }
catch(e) { catch(e) {
@ -838,24 +851,23 @@ Kinetic.Node = Kinetic.Class.extend({
* specified, then "image/png" will result. For "image/jpeg", specify a quality * specified, then "image/png" will result. For "image/jpeg", specify a quality
* level as quality (range 0.0 - 1.0) * level as quality (range 0.0 - 1.0)
* @name toDataURL * @name toDataURL
* @methodOf Kinetic.Stage.prototype * @methodOf Kinetic.Node.prototype
* @param {String} [mimeType] * @param {String} [mimeType]
* @param {Number} [quality] * @param {Number} [quality]
*/ */
toDataURL: function(mimeType, quality) { toDataURL: function(mimeType, quality) {
var bufferLayer = this.getStage().bufferLayer; var bufferCanvas = this.getStage().bufferCanvas;
var bufferCanvas = bufferLayer.getCanvas(); var bufferContext = bufferCanvas.getContext();
var bufferContext = bufferLayer.getContext(); bufferCanvas.clear();
bufferLayer.clear(); this._draw(bufferCanvas);
this._draw(bufferLayer);
try { try {
// If this call fails (due to browser bug, like in Firefox 3.6), // If this call fails (due to browser bug, like in Firefox 3.6),
// then revert to previous no-parameter image/png behavior // then revert to previous no-parameter image/png behavior
return bufferLayer.getCanvas().toDataURL(mimeType, quality); return bufferCanvas.element.toDataURL(mimeType, quality);
} }
catch(e) { catch(e) {
return bufferLayer.getCanvas().toDataURL(); return bufferCanvas.element.toDataURL();
} }
}, },
/** /**
@ -910,9 +922,10 @@ Kinetic.Node = Kinetic.Class.extend({
if(pos) { if(pos) {
var m = this.getTransform().getTranslation(); var m = this.getTransform().getTranslation();
var am = this.getAbsoluteTransform().getTranslation(); var am = this.getAbsoluteTransform().getTranslation();
var ap = this.getAbsolutePosition();
go.drag.node = this; go.drag.node = this;
go.drag.offset.x = pos.x - this.getAbsoluteTransform().getTranslation().x; go.drag.offset.x = pos.x - ap.x;
go.drag.offset.y = pos.y - this.getAbsoluteTransform().getTranslation().y; go.drag.offset.y = pos.y - ap.y;
} }
}, },
_onDraggableChange: function() { _onDraggableChange: function() {

View File

@ -30,24 +30,20 @@ Kinetic.Shape = Kinetic.Node.extend({
this._super(config); this._super(config);
}, },
/** /**
* get layer context where the shape is being drawn. When * get canvas context tied to the layer
* the shape is being rendered, .getContext() returns the context of the
* user created layer that contains the shape. When the event detection
* engine is determining whether or not an event has occured on that shape,
* .getContext() returns the context of the invisible path layer.
* @name getContext * @name getContext
* @methodOf Kinetic.Shape.prototype * @methodOf Kinetic.Shape.prototype
*/ */
getContext: function() { getContext: function() {
return this.tempLayer.getContext(); return this.getLayer().getContext();
}, },
/** /**
* get shape temp layer canvas * get canvas tied to the layer
* @name getCanvas * @name getCanvas
* @methodOf Kinetic.Shape.prototype * @methodOf Kinetic.Shape.prototype
*/ */
getCanvas: function() { getCanvas: function() {
return this.tempLayer.getCanvas(); return this.getLayer().getCanvas();
}, },
/** /**
* helper method to stroke the shape and apply * helper method to stroke the shape and apply
@ -55,15 +51,14 @@ Kinetic.Shape = Kinetic.Node.extend({
* @name stroke * @name stroke
* @methodOf Kinetic.Shape.prototype * @methodOf Kinetic.Shape.prototype
*/ */
stroke: function() { stroke: function(context) {
var go = Kinetic.Global; var go = Kinetic.Global;
var appliedShadow = false; var appliedShadow = false;
var context = this.getContext();
if(this.attrs.stroke || this.attrs.strokeWidth) { if(this.attrs.stroke || this.attrs.strokeWidth) {
context.save(); context.save();
if(this.attrs.shadow && !this.appliedShadow) { if(this.attrs.shadow && !this.appliedShadow) {
appliedShadow = this._applyShadow(); appliedShadow = this._applyShadow(context);
} }
var stroke = this.attrs.stroke ? this.attrs.stroke : 'black'; var stroke = this.attrs.stroke ? this.attrs.stroke : 'black';
@ -71,12 +66,12 @@ Kinetic.Shape = Kinetic.Node.extend({
context.lineWidth = strokeWidth; context.lineWidth = strokeWidth;
context.strokeStyle = stroke; context.strokeStyle = stroke;
context.stroke(); context.stroke(context);
context.restore(); context.restore();
} }
if(appliedShadow) { if(appliedShadow) {
this.stroke(); this.stroke(context);
} }
}, },
/** /**
@ -85,16 +80,15 @@ Kinetic.Shape = Kinetic.Node.extend({
* @name fill * @name fill
* @methodOf Kinetic.Shape.prototype * @methodOf Kinetic.Shape.prototype
* */ * */
fill: function() { fill: function(context) {
var appliedShadow = false; var appliedShadow = false;
var context = this.getContext();
context.save(); context.save();
var fill = this.attrs.fill; var fill = this.attrs.fill;
if(fill) { if(fill) {
if(this.attrs.shadow && !this.appliedShadow) { if(this.attrs.shadow && !this.appliedShadow) {
appliedShadow = this._applyShadow(); appliedShadow = this._applyShadow(context);
} }
var s = fill.start; var s = fill.start;
@ -105,7 +99,7 @@ Kinetic.Shape = Kinetic.Node.extend({
if( typeof fill == 'string') { if( typeof fill == 'string') {
f = this.attrs.fill; f = this.attrs.fill;
context.fillStyle = f; context.fillStyle = f;
context.fill(); context.fill(context);
} }
// pattern // pattern
else if(fill.image) { else if(fill.image) {
@ -122,12 +116,11 @@ Kinetic.Shape = Kinetic.Node.extend({
} }
context.fillStyle = f; context.fillStyle = f;
context.fill(); context.fill(context);
context.restore(); context.restore();
} }
// linear gradient // linear gradient
else if(!s.radius && !e.radius) { else if(!s.radius && !e.radius) {
var context = this.getContext();
var grd = context.createLinearGradient(s.x, s.y, e.x, e.y); var grd = context.createLinearGradient(s.x, s.y, e.x, e.y);
var colorStops = fill.colorStops; var colorStops = fill.colorStops;
@ -137,11 +130,10 @@ Kinetic.Shape = Kinetic.Node.extend({
} }
f = grd; f = grd;
context.fillStyle = f; context.fillStyle = f;
context.fill(); context.fill(context);
} }
// radial gradient // radial gradient
else if((s.radius || s.radius === 0) && (e.radius || e.radius === 0)) { else if((s.radius || s.radius === 0) && (e.radius || e.radius === 0)) {
var context = this.getContext();
var grd = context.createRadialGradient(s.x, s.y, s.radius, e.x, e.y, e.radius); var grd = context.createRadialGradient(s.x, s.y, s.radius, e.x, e.y, e.radius);
var colorStops = fill.colorStops; var colorStops = fill.colorStops;
@ -151,18 +143,18 @@ Kinetic.Shape = Kinetic.Node.extend({
} }
f = grd; f = grd;
context.fillStyle = f; context.fillStyle = f;
context.fill(); context.fill(context);
} }
else { else {
f = 'black'; f = 'black';
context.fillStyle = f; context.fillStyle = f;
context.fill(); context.fill(context);
} }
} }
context.restore(); context.restore();
if(appliedShadow) { if(appliedShadow) {
this.fill(); this.fill(context);
} }
}, },
/** /**
@ -171,13 +163,12 @@ Kinetic.Shape = Kinetic.Node.extend({
* @name fillText * @name fillText
* @methodOf Kinetic.Shape.prototype * @methodOf Kinetic.Shape.prototype
*/ */
fillText: function(text) { fillText: function(context, text) {
var appliedShadow = false; var appliedShadow = false;
var context = this.getContext();
context.save(); context.save();
if(this.attrs.textFill) { if(this.attrs.textFill) {
if(this.attrs.shadow && !this.appliedShadow) { if(this.attrs.shadow && !this.appliedShadow) {
appliedShadow = this._applyShadow(); appliedShadow = this._applyShadow(context);
} }
context.fillStyle = this.attrs.textFill; context.fillStyle = this.attrs.textFill;
context.fillText(text, 0, 0); context.fillText(text, 0, 0);
@ -185,7 +176,7 @@ Kinetic.Shape = Kinetic.Node.extend({
context.restore(); context.restore();
if(appliedShadow) { if(appliedShadow) {
this.fillText(text, 0, 0); this.fillText(context, text, 0, 0);
} }
}, },
/** /**
@ -195,13 +186,12 @@ Kinetic.Shape = Kinetic.Node.extend({
* @methodOf Kinetic.Shape.prototype * @methodOf Kinetic.Shape.prototype
* @param {String} text * @param {String} text
*/ */
strokeText: function(text) { strokeText: function(context, text) {
var appliedShadow = false; var appliedShadow = false;
var context = this.getContext();
context.save(); context.save();
if(this.attrs.textStroke || this.attrs.textStrokeWidth) { if(this.attrs.textStroke || this.attrs.textStrokeWidth) {
if(this.attrs.shadow && !this.appliedShadow) { if(this.attrs.shadow && !this.appliedShadow) {
appliedShadow = this._applyShadow(); appliedShadow = this._applyShadow(context);
} }
// defaults // defaults
@ -213,12 +203,12 @@ Kinetic.Shape = Kinetic.Node.extend({
} }
context.lineWidth = this.attrs.textStrokeWidth; context.lineWidth = this.attrs.textStrokeWidth;
context.strokeStyle = this.attrs.textStroke; context.strokeStyle = this.attrs.textStroke;
context.strokeText(text, 0, 0); context.strokeText(context, text, 0, 0);
} }
context.restore(); context.restore();
if(appliedShadow) { if(appliedShadow) {
this.strokeText(text, 0, 0); this.strokeText(context, text, 0, 0);
} }
}, },
/** /**
@ -229,21 +219,20 @@ Kinetic.Shape = Kinetic.Node.extend({
*/ */
drawImage: function() { drawImage: function() {
var appliedShadow = false; var appliedShadow = false;
var context = this.getContext(); var context = arguments[0];
context.save(); context.save();
var a = Array.prototype.slice.call(arguments); var a = Array.prototype.slice.call(arguments);
if(a.length === 5 || a.length === 9) { if(a.length === 6 || a.length === 10) {
if(this.attrs.shadow && !this.appliedShadow) { if(this.attrs.shadow && !this.appliedShadow) {
appliedShadow = this._applyShadow(); appliedShadow = this._applyShadow(context);
} }
switch(a.length) {
case 5: if(a.length === 6) {
context.drawImage(a[0], a[1], a[2], a[3], a[4]); context.drawImage(a[1], a[2], a[3], a[4], a[5]);
break; }
case 9: else {
context.drawImage(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]); context.drawImage(a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]);
break;
} }
} }
@ -259,8 +248,7 @@ Kinetic.Shape = Kinetic.Node.extend({
* @name applyLineJoin * @name applyLineJoin
* @methodOf Kinetic.Shape.prototype * @methodOf Kinetic.Shape.prototype
*/ */
applyLineJoin: function() { applyLineJoin: function(context) {
var context = this.getContext();
if(this.attrs.lineJoin) { if(this.attrs.lineJoin) {
context.lineJoin = this.attrs.lineJoin; context.lineJoin = this.attrs.lineJoin;
} }
@ -269,8 +257,7 @@ Kinetic.Shape = Kinetic.Node.extend({
* apply shadow. return true if shadow was applied * apply shadow. return true if shadow was applied
* and false if it was not * and false if it was not
*/ */
_applyShadow: function() { _applyShadow: function(context) {
var context = this.getContext();
var s = this.attrs.shadow; var s = this.attrs.shadow;
if(s) { if(s) {
var aa = this.getAbsoluteAlpha(); var aa = this.getAbsoluteAlpha();
@ -308,12 +295,12 @@ Kinetic.Shape = Kinetic.Node.extend({
// path detection // path detection
if(this.attrs.detectionType === 'path') { if(this.attrs.detectionType === 'path') {
var pathLayer = stage.pathLayer; var pathCanvas = stage.pathCanvas;
var pathLayerContext = pathLayer.getContext(); var pathCanvasContext = pathCanvas.getContext();
this._draw(pathLayer); this._draw(pathCanvas);
return pathLayerContext.isPointInPath(pos.x, pos.y); return pathCanvasContext.isPointInPath(pos.x, pos.y);
} }
// pixel detection // pixel detection
@ -326,10 +313,10 @@ Kinetic.Shape = Kinetic.Node.extend({
// default // default
return false; return false;
}, },
_draw: function(layer) { _draw: function(canvas) {
if(layer && this.attrs.drawFunc) { if(this.attrs.drawFunc) {
var stage = layer.getStage(); var stage = this.getStage();
var context = layer.getContext(); var context = canvas.getContext();
var family = []; var family = [];
var parent = this.parent; var parent = this.parent;
@ -348,8 +335,6 @@ Kinetic.Shape = Kinetic.Node.extend({
context.transform(m[0], m[1], m[2], m[3], m[4], m[5]); context.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
} }
this.tempLayer = layer;
/* /*
* pre styles include alpha, linejoin * pre styles include alpha, linejoin
*/ */
@ -357,11 +342,11 @@ Kinetic.Shape = Kinetic.Node.extend({
if(absAlpha !== 1) { if(absAlpha !== 1) {
context.globalAlpha = absAlpha; context.globalAlpha = absAlpha;
} }
this.applyLineJoin(); this.applyLineJoin(context);
// draw the shape // draw the shape
this.appliedShadow = false; this.appliedShadow = false;
this.attrs.drawFunc.call(this); this.attrs.drawFunc.call(this, canvas.getContext());
context.restore(); context.restore();
} }
} }

View File

@ -85,8 +85,8 @@ Kinetic.Stage = Kinetic.Container.extend({
* @name draw * @name draw
* @methodOf Kinetic.Stage.prototype * @methodOf Kinetic.Stage.prototype
*/ */
draw: function(layer) { draw: function(canvas) {
this._draw(layer); this._draw(canvas);
}, },
/** /**
* set stage size * set stage size
@ -288,37 +288,25 @@ Kinetic.Stage = Kinetic.Container.extend({
* @param {Number} [quality] * @param {Number} [quality]
*/ */
toDataURL: function(callback, mimeType, quality) { toDataURL: function(callback, mimeType, quality) {
/* var canvas = new Kinetic.Canvas(this.attrs.width, this.attrs.height);
* we need to create a temp layer rather than using var context = canvas.getContext();
* the bufferLayer because the stage toDataURL method
* is asynchronous, which means that other parts of the
* code base could be updating or clearing the bufferLayer
* while the stage toDataURL method is processing
*/
var tempLayer = new Kinetic.Layer();
tempLayer.getCanvas().width = this.attrs.width;
tempLayer.getCanvas().height = this.attrs.height;
tempLayer.parent = this;
var tempCanvas = tempLayer.getCanvas();
var tempContext = tempLayer.getContext();
var layers = this.children; var layers = this.children;
function drawLayer(n) { function drawLayer(n) {
var layer = layers[n]; var layer = layers[n];
var layerUrl; var canvasUrl;
try { try {
// If this call fails (due to browser bug, like in Firefox 3.6), // If this call fails (due to browser bug, like in Firefox 3.6),
// then revert to previous no-parameter image/png behavior // then revert to previous no-parameter image/png behavior
layerUrl = layer.getCanvas().toDataURL(mimeType, quality); canvasUrl = canvas.getElement().toDataURL(mimeType, quality);
} }
catch(e) { catch(e) {
layerUrl = layer.getCanvas().toDataURL(); canvasUrl = canvas.getElement().toDataURL();
} }
var imageObj = new Image(); var imageObj = new Image();
imageObj.onload = function() { imageObj.onload = function() {
tempContext.drawImage(imageObj, 0, 0); context.drawImage(imageObj, 0, 0);
if(n < layers.length - 1) { if(n < layers.length - 1) {
drawLayer(n + 1); drawLayer(n + 1);
@ -327,14 +315,14 @@ Kinetic.Stage = Kinetic.Container.extend({
try { try {
// If this call fails (due to browser bug, like in Firefox 3.6), // If this call fails (due to browser bug, like in Firefox 3.6),
// then revert to previous no-parameter image/png behavior // then revert to previous no-parameter image/png behavior
callback(tempLayer.getCanvas().toDataURL(mimeType, quality)); callback(canvas.getElement().toDataURL(mimeType, quality));
} }
catch(e) { catch(e) {
callback(tempLayer.getCanvas().toDataURL()); callback(canvas.getElement().toDataURL());
} }
} }
}; };
imageObj.src = layerUrl; imageObj.src = canvasUrl;
} }
drawLayer(0); drawLayer(0);
}, },
@ -360,18 +348,15 @@ Kinetic.Stage = Kinetic.Container.extend({
this.content.style.width = width + 'px'; this.content.style.width = width + 'px';
this.content.style.height = height + 'px'; this.content.style.height = height + 'px';
// set buffer layer and path layer sizes // set buffer canvas and path canvas sizes
this.bufferLayer.getCanvas().width = width; this.bufferCanvas.setSize(width, height);
this.bufferLayer.getCanvas().height = height; this.pathCanvas.setSize(width, height);
this.pathLayer.getCanvas().width = width;
this.pathLayer.getCanvas().height = height;
// set user defined layer dimensions // set user defined layer dimensions
var layers = this.children; var layers = this.children;
for(var n = 0; n < layers.length; n++) { for(var n = 0; n < layers.length; n++) {
var layer = layers[n]; var layer = layers[n];
layer.getCanvas().width = width; layer.getCanvas().setSize(width, height);
layer.getCanvas().height = height;
layer.draw(); layer.draw();
} }
}, },
@ -395,12 +380,11 @@ Kinetic.Stage = Kinetic.Container.extend({
* @param {Layer} layer * @param {Layer} layer
*/ */
_add: function(layer) { _add: function(layer) {
layer.canvas.width = this.attrs.width; layer.canvas.setSize(this.attrs.width, this.attrs.height);
layer.canvas.height = this.attrs.height;
// draw layer and append canvas to container // draw layer and append canvas to container
layer.draw(); layer.draw();
this.content.appendChild(layer.canvas); this.content.appendChild(layer.canvas.element);
/* /*
* set layer last draw time to zero * set layer last draw time to zero
@ -603,7 +587,7 @@ Kinetic.Stage = Kinetic.Container.extend({
this._setMousePosition(evt); this._setMousePosition(evt);
this._setTouchPosition(evt); this._setTouchPosition(evt);
this.pathLayer.clear(); this.pathCanvas.clear();
/* /*
* loop through layers. If at any point an event * loop through layers. If at any point an event
@ -794,28 +778,6 @@ Kinetic.Stage = Kinetic.Container.extend({
left: left left: left
}; };
}, },
/**
* modify path context
* @param {CanvasContext} context
*/
_modifyPathContext: function(context) {
context.stroke = function() {
};
context.fill = function() {
};
context.fillRect = function(x, y, width, height) {
context.rect(x, y, width, height);
};
context.strokeRect = function(x, y, width, height) {
context.rect(x, y, width, height);
};
context.drawImage = function() {
};
context.fillText = function() {
};
context.strokeText = function() {
};
},
/** /**
* end drag and drop * end drag and drop
*/ */
@ -910,34 +872,15 @@ Kinetic.Stage = Kinetic.Container.extend({
this.content.className = 'kineticjs-content'; this.content.className = 'kineticjs-content';
this.attrs.container.appendChild(this.content); this.attrs.container.appendChild(this.content);
// default layers this.bufferCanvas = new Kinetic.Canvas({
this.bufferLayer = new Kinetic.Layer({ width: this.attrs.width,
name: 'bufferLayer' height: this.attrs.height
}); });
this.pathLayer = new Kinetic.Layer({ this.pathCanvas = new Kinetic.Canvas({
name: 'pathLayer' width: this.attrs.width,
height: this.attrs.height
}); });
this.pathCanvas.strip();
// set parents
this.bufferLayer.parent = this;
this.pathLayer.parent = this;
// customize back stage context
this._modifyPathContext(this.pathLayer.context);
// hide canvases
this.bufferLayer.getCanvas().style.display = 'none';
this.pathLayer.getCanvas().style.display = 'none';
// add buffer layer
this.bufferLayer.canvas.className = 'kineticjs-buffer-layer';
this.content.appendChild(this.bufferLayer.canvas);
// add path layer
this.pathLayer.canvas.className = 'kineticjs-path-layer';
this.content.appendChild(this.pathLayer.canvas);
this.setSize(this.attrs.width, this.attrs.height);
this._resizeDOM(); this._resizeDOM();
}, },
_addId: function(node) { _addId: function(node) {
@ -1018,8 +961,8 @@ Kinetic.Stage = Kinetic.Container.extend({
this.anim = undefined; this.anim = undefined;
this.animRunning = false; this.animRunning = false;
}, },
_draw: function(layer) { _draw: function(canvas) {
this._drawChildren(layer); this._drawChildren(canvas);
} }
}); });

View File

@ -18,9 +18,7 @@ Kinetic.Ellipse = Kinetic.Shape.extend({
this.shapeType = "Ellipse"; this.shapeType = "Ellipse";
config.drawFunc = function() { config.drawFunc = function(context) {
var canvas = this.getCanvas();
var context = this.getContext();
var r = this.getRadius(); var r = this.getRadius();
context.beginPath(); context.beginPath();
context.save(); context.save();
@ -30,8 +28,8 @@ Kinetic.Ellipse = Kinetic.Shape.extend({
context.arc(0, 0, r.x, 0, Math.PI * 2, true); context.arc(0, 0, r.x, 0, Math.PI * 2, true);
context.restore(); context.restore();
context.closePath(); context.closePath();
this.fill(); this.fill(context);
this.stroke(); this.stroke(context);
}; };
// call super constructor // call super constructor
this._super(config); this._super(config);

View File

@ -14,18 +14,16 @@
Kinetic.Image = Kinetic.Shape.extend({ Kinetic.Image = Kinetic.Shape.extend({
init: function(config) { init: function(config) {
this.shapeType = "Image"; this.shapeType = "Image";
config.drawFunc = function() { config.drawFunc = function(context) {
if(!!this.attrs.image) { if(!!this.attrs.image) {
var width = this.getWidth(); var width = this.getWidth();
var height = this.getHeight(); var height = this.getHeight();
var canvas = this.getCanvas();
var context = this.getContext();
context.beginPath(); context.beginPath();
context.rect(0, 0, width, height); context.rect(0, 0, width, height);
context.closePath(); context.closePath();
this.fill(); this.fill(context);
this.stroke(); this.stroke(context);
// if cropping // if cropping
if(this.attrs.crop && this.attrs.crop.width && this.attrs.crop.height) { if(this.attrs.crop && this.attrs.crop.width && this.attrs.crop.height) {
@ -33,11 +31,11 @@ Kinetic.Image = Kinetic.Shape.extend({
var cropY = this.attrs.crop.y ? this.attrs.crop.y : 0; var cropY = this.attrs.crop.y ? this.attrs.crop.y : 0;
var cropWidth = this.attrs.crop.width; var cropWidth = this.attrs.crop.width;
var cropHeight = this.attrs.crop.height; var cropHeight = this.attrs.crop.height;
this.drawImage(this.attrs.image, cropX, cropY, cropWidth, cropHeight, 0, 0, width, height); this.drawImage(context, this.attrs.image, cropX, cropY, cropWidth, cropHeight, 0, 0, width, height);
} }
// no cropping // no cropping
else { else {
this.drawImage(this.attrs.image, 0, 0, width, height); this.drawImage(context, this.attrs.image, 0, 0, width, height);
} }
} }
}; };

View File

@ -17,8 +17,7 @@ Kinetic.Line = Kinetic.Shape.extend({
}); });
this.shapeType = "Line"; this.shapeType = "Line";
config.drawFunc = function() { config.drawFunc = function(context) {
var context = this.getContext();
var lastPos = {}; var lastPos = {};
context.beginPath(); context.beginPath();
@ -31,7 +30,7 @@ Kinetic.Line = Kinetic.Shape.extend({
// draw dashed line // draw dashed line
var lastX = this.attrs.points[n - 1].x; var lastX = this.attrs.points[n - 1].x;
var lastY = this.attrs.points[n - 1].y; var lastY = this.attrs.points[n - 1].y;
this._dashedLine(lastX, lastY, x, y, this.attrs.dashArray); this._dashedLine(context, lastX, lastY, x, y, this.attrs.dashArray);
} }
else { else {
// draw normal line // draw normal line
@ -43,7 +42,7 @@ Kinetic.Line = Kinetic.Shape.extend({
context.lineCap = this.attrs.lineCap; context.lineCap = this.attrs.lineCap;
} }
this.stroke(); this.stroke(context);
}; };
// call super constructor // call super constructor
this._super(config); this._super(config);
@ -51,8 +50,7 @@ Kinetic.Line = Kinetic.Shape.extend({
/** /**
* draw dashed line. Written by Phrogz * draw dashed line. Written by Phrogz
*/ */
_dashedLine: function(x, y, x2, y2, dashArray) { _dashedLine: function(context, x, y, x2, y2, dashArray) {
var context = this.getContext();
var dashCount = dashArray.length; var dashCount = dashArray.length;
var dx = (x2 - x), dy = (y2 - y); var dx = (x2 - x), dy = (y2 - y);

View File

@ -14,8 +14,7 @@ Kinetic.Path = Kinetic.Shape.extend({
this.dataArray = []; this.dataArray = [];
var that = this; var that = this;
config.drawFunc = function() { config.drawFunc = function(context) {
var context = this.getContext();
var ca = this.dataArray; var ca = this.dataArray;
// context position // context position
context.beginPath(); context.beginPath();
@ -56,8 +55,8 @@ Kinetic.Path = Kinetic.Shape.extend({
break; break;
} }
} }
this.fill(); this.fill(context);
this.stroke(); this.stroke(context);
}; };
// call super constructor // call super constructor
this._super(config); this._super(config);

View File

@ -14,16 +14,15 @@ Kinetic.Polygon = Kinetic.Shape.extend({
}); });
this.shapeType = "Polygon"; this.shapeType = "Polygon";
config.drawFunc = function() { config.drawFunc = function(context) {
var context = this.getContext();
context.beginPath(); context.beginPath();
context.moveTo(this.attrs.points[0].x, this.attrs.points[0].y); context.moveTo(this.attrs.points[0].x, this.attrs.points[0].y);
for(var n = 1; n < this.attrs.points.length; n++) { for(var n = 1; n < this.attrs.points.length; n++) {
context.lineTo(this.attrs.points[n].x, this.attrs.points[n].y); context.lineTo(this.attrs.points[n].x, this.attrs.points[n].y);
} }
context.closePath(); context.closePath();
this.fill(); this.fill(context);
this.stroke(); this.stroke(context);
}; };
// call super constructor // call super constructor
this._super(config); this._super(config);

View File

@ -17,8 +17,7 @@ Kinetic.Rect = Kinetic.Shape.extend({
this.shapeType = "Rect"; this.shapeType = "Rect";
config.drawFunc = function() { config.drawFunc = function(context) {
var context = this.getContext();
context.beginPath(); context.beginPath();
if(this.attrs.cornerRadius === 0) { if(this.attrs.cornerRadius === 0) {
// simple rect - don't bother doing all that complicated maths stuff. // simple rect - don't bother doing all that complicated maths stuff.
@ -38,8 +37,8 @@ Kinetic.Rect = Kinetic.Shape.extend({
} }
context.closePath(); context.closePath();
this.fill(); this.fill(context);
this.stroke(); this.stroke(context);
}; };
// call super constructor // call super constructor
this._super(config); this._super(config);

View File

@ -15,8 +15,7 @@ Kinetic.RegularPolygon = Kinetic.Shape.extend({
}); });
this.shapeType = "RegularPolygon"; this.shapeType = "RegularPolygon";
config.drawFunc = function() { config.drawFunc = function(context) {
var context = this.getContext();
context.beginPath(); context.beginPath();
context.moveTo(0, 0 - this.attrs.radius); context.moveTo(0, 0 - this.attrs.radius);
@ -26,8 +25,8 @@ Kinetic.RegularPolygon = Kinetic.Shape.extend({
context.lineTo(x, y); context.lineTo(x, y);
} }
context.closePath(); context.closePath();
this.fill(); this.fill(context);
this.stroke(); this.stroke(context);
}; };
// call super constructor // call super constructor
this._super(config); this._super(config);

View File

@ -14,9 +14,8 @@ Kinetic.Sprite = Kinetic.Shape.extend({
frameRate: 17 frameRate: 17
}); });
config.drawFunc = function() { config.drawFunc = function(context) {
if(!!this.attrs.image) { if(!!this.attrs.image) {
var context = this.getContext();
var anim = this.attrs.animation; var anim = this.attrs.animation;
var index = this.attrs.index; var index = this.attrs.index;
var f = this.attrs.animations[anim][index]; var f = this.attrs.animations[anim][index];
@ -25,7 +24,7 @@ Kinetic.Sprite = Kinetic.Shape.extend({
context.rect(0, 0, f.width, f.height); context.rect(0, 0, f.width, f.height);
context.closePath(); context.closePath();
this.drawImage(this.attrs.image, f.x, f.y, f.width, f.height, 0, 0, f.width, f.height); this.drawImage(context, this.attrs.image, f.x, f.y, f.width, f.height, 0, 0, f.width, f.height);
} }
}; };
// call super constructor // call super constructor

View File

@ -16,8 +16,7 @@ Kinetic.Star = Kinetic.Shape.extend({
}); });
this.shapeType = "Star"; this.shapeType = "Star";
config.drawFunc = function() { config.drawFunc = function(context) {
var context = this.getContext();
context.beginPath(); context.beginPath();
context.moveTo(0, 0 - this.attrs.outerRadius); context.moveTo(0, 0 - this.attrs.outerRadius);
@ -29,8 +28,8 @@ Kinetic.Star = Kinetic.Shape.extend({
} }
context.closePath(); context.closePath();
this.fill(); this.fill(context);
this.stroke(); this.stroke(context);
}; };
// call super constructor // call super constructor
this._super(config); this._super(config);

View File

@ -27,8 +27,7 @@ Kinetic.Text = Kinetic.Shape.extend({
this.dummyCanvas = document.createElement('canvas'); this.dummyCanvas = document.createElement('canvas');
this.shapeType = "Text"; this.shapeType = "Text";
config.drawFunc = function() { config.drawFunc = function(context) {
var context = this.getContext();
/* /*
* draw rect * draw rect
*/ */
@ -54,8 +53,8 @@ Kinetic.Text = Kinetic.Shape.extend({
} }
context.closePath(); context.closePath();
this.fill(); this.fill(context);
this.stroke(); this.stroke(context);
/* /*
* draw text * draw text
*/ */
@ -83,8 +82,8 @@ Kinetic.Text = Kinetic.Shape.extend({
context.translate((this.getBoxWidth() - this._getTextSize(text).width - p * 2) / 2, 0); context.translate((this.getBoxWidth() - this._getTextSize(text).width - p * 2) / 2, 0);
} }
this.fillText(text); this.fillText(context, text);
this.strokeText(text); this.strokeText(context, text);
context.restore(); context.restore();
context.translate(0, lineHeightPx); context.translate(0, lineHeightPx);

96
src/util/Canvas.js Normal file
View File

@ -0,0 +1,96 @@
///////////////////////////////////////////////////////////////////////
// Canvas
///////////////////////////////////////////////////////////////////////
/**
* Canvas wrapper constructor
* @constructor
* @param {Number} width
* @param {Number} height
*/
Kinetic.Canvas = function(width, height) {
this.element = document.createElement('canvas');
this.context = this.element.getContext('2d');
// set dimensions
this.element.width = width;
this.element.height = height;
};
Kinetic.Canvas.prototype = {
/**
* clear canvas
* @name clear
* @methodOf Kinetic.Canvas.prototype
*/
clear: function() {
var context = this.getContext();
var el = this.getElement();
context.clearRect(0, 0, el.width, el.height);
},
/**
* get element
* @name getElement
* @methodOf Kinetic.Canvas.prototype
*/
getElement: function() {
return this.element;
},
/**
* get context
* @name getContext
* @methodOf Kinetic.Canvas.prototype
*/
getContext: function() {
return this.context;
},
/**
* set width
* @name setWidth
* @methodOf Kinetic.Canvas.prototype
*/
setWidth: function(width) {
this.element.width = width;
},
/**
* set height
* @name setHeight
* @methodOf Kinetic.Canvas.prototype
*/
setHeight: function(height) {
this.element.height = height;
},
/**
* set size
* @name setSize
* @methodOf Kinetic.Canvas.prototype
*/
setSize: function(width, height) {
this.setWidth(width);
this.setHeight(height);
},
/**
* strip away all functions that draw pixels onto the bitmap
* @name strip
* @methodOf Kinetic.Canvas.prototype
* @param {CanvasContext} context
*/
strip: function() {
var context = this.context;
context.stroke = function() {
};
context.fill = function() {
};
context.fillRect = function(x, y, width, height) {
context.rect(x, y, width, height);
};
context.strokeRect = function(x, y, width, height) {
context.rect(x, y, width, height);
};
context.drawImage = function() {
};
context.fillText = function() {
};
context.strokeText = function() {
};
}
};

View File

@ -152,7 +152,7 @@ Test.prototype.tests = {
context.quadraticCurveTo(300, 100, 260, 170); context.quadraticCurveTo(300, 100, 260, 170);
context.closePath(); context.closePath();
context.fillStyle = 'blue'; context.fillStyle = 'blue';
context.fill(); context.fill(context);
}, },
draggable: true draggable: true
}); });

View File

@ -1349,8 +1349,7 @@ Test.prototype.tests = {
rect.rotate(0.01); rect.rotate(0.01);
layer.draw(); layer.draw();
}); });
//stage.start(); stage.start();
}, },
'STAGE - hide stage': function(containerId) { 'STAGE - hide stage': function(containerId) {
var stage = new Kinetic.Stage({ var stage = new Kinetic.Stage({

View File

@ -25,7 +25,7 @@ Test.prototype.tests = {
var imageData = context.getImageData(7, 7, 106, 106); var imageData = context.getImageData(7, 7, 106, 106);
endTimer('create image data'); endTimer('create image data');
layer.clear(); layer.canvas.clear();
startTimer(); startTimer();
for(var n = 0; n < 10000; n++) { for(var n = 0; n < 10000; n++) {
@ -62,7 +62,7 @@ Test.prototype.tests = {
var imageObj = new Image(); var imageObj = new Image();
imageObj.onload = function() { imageObj.onload = function() {
layer.clear(); layer.canvas.clear();
startTimer(); startTimer();
for(var n = 0; n < 10000; n++) { for(var n = 0; n < 10000; n++) {

View File

@ -68,8 +68,8 @@ Test.prototype.tests = {
test(stage.getSize().height === 155, 'stage height should be 155'); test(stage.getSize().height === 155, 'stage height should be 155');
test(stage.getDOM().style.width === '333px', 'content width should be 333'); test(stage.getDOM().style.width === '333px', 'content width should be 333');
test(stage.getDOM().style.height === '155px', 'content height should be 155px'); test(stage.getDOM().style.height === '155px', 'content height should be 155px');
test(layer.getCanvas().width === 333, 'layer canvas width should be 333'); test(layer.getCanvas().element.width === 333, 'layer canvas element width should be 333');
test(layer.getCanvas().height === 155, 'layer canvas width should be 155'); test(layer.getCanvas().element.height === 155, 'layer canvas element width should be 155');
}, },
'STAGE - add shape then stage then layer': function(containerId) { 'STAGE - add shape then stage then layer': function(containerId) {
var stage = new Kinetic.Stage({ var stage = new Kinetic.Stage({
@ -340,15 +340,14 @@ Test.prototype.tests = {
var layer = new Kinetic.Layer(); var layer = new Kinetic.Layer();
var group = new Kinetic.Group(); var group = new Kinetic.Group();
var drawTriangle = function() { var drawTriangle = function(context) {
var context = this.getContext();
context.beginPath(); context.beginPath();
context.moveTo(200, 50); context.moveTo(200, 50);
context.lineTo(420, 80); context.lineTo(420, 80);
context.quadraticCurveTo(300, 100, 260, 170); context.quadraticCurveTo(300, 100, 260, 170);
context.closePath(); context.closePath();
this.fill(); this.fill(context);
this.stroke(); this.stroke(context);
}; };
var triangle = new Kinetic.Shape({ var triangle = new Kinetic.Shape({
drawFunc: drawTriangle, drawFunc: drawTriangle,
@ -388,15 +387,14 @@ Test.prototype.tests = {
height: 200 height: 200
}); });
var drawTriangle = function() { var drawTriangle = function(context) {
var context = this.getContext();
context.beginPath(); context.beginPath();
context.moveTo(200, 50); context.moveTo(200, 50);
context.lineTo(420, 80); context.lineTo(420, 80);
context.quadraticCurveTo(300, 100, 260, 170); context.quadraticCurveTo(300, 100, 260, 170);
context.closePath(); context.closePath();
this.fill(); this.fill(context);
this.stroke(); this.stroke(context);
}; };
var json = '{"attrs":{"width":578,"height":200,"visible":true,"listen":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false},"nodeType":"Stage","children":[{"attrs":{"throttle":80,"clearBeforeDraw":true,"visible":true,"listening":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false,"listen":true},"nodeType":"Layer","children":[{"attrs":{"visible":true,"listening":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false,"listen":true},"nodeType":"Group","children":[{"attrs":{"detectionType":"path","visible":true,"listening":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false,"fill":"#00D2FF","stroke":"black","strokeWidth":4,"shadow":{"blur":10,"alpha":1,"offset":{"x":0,"y":0}},"listen":true,"id":"myTriangle"},"nodeType":"Shape"}]}]}]}'; var json = '{"attrs":{"width":578,"height":200,"visible":true,"listen":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false},"nodeType":"Stage","children":[{"attrs":{"throttle":80,"clearBeforeDraw":true,"visible":true,"listening":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false,"listen":true},"nodeType":"Layer","children":[{"attrs":{"visible":true,"listening":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false,"listen":true},"nodeType":"Group","children":[{"attrs":{"detectionType":"path","visible":true,"listening":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false,"fill":"#00D2FF","stroke":"black","strokeWidth":4,"shadow":{"blur":10,"alpha":1,"offset":{"x":0,"y":0}},"listen":true,"id":"myTriangle"},"nodeType":"Shape"}]}]}]}';
stage.load(json); stage.load(json);
@ -2167,7 +2165,7 @@ Test.prototype.tests = {
setTimeout(function() { setTimeout(function() {
sprite.setAnimation('kicking'); sprite.setAnimation('kicking');
sprite.afterFrame(0, function() { sprite.afterFrame(5, function() {
sprite.setAnimation('standing'); sprite.setAnimation('standing');
}); });
}, 2000); }, 2000);
@ -2720,15 +2718,14 @@ Test.prototype.tests = {
}); });
var layer = new Kinetic.Layer(); var layer = new Kinetic.Layer();
var shape = new Kinetic.Shape({ var shape = new Kinetic.Shape({
drawFunc: function() { drawFunc: function(context) {
var context = this.getContext();
context.beginPath(); context.beginPath();
context.moveTo(0, 0); context.moveTo(0, 0);
context.lineTo(100, 0); context.lineTo(100, 0);
context.lineTo(100, 100); context.lineTo(100, 100);
context.closePath(); context.closePath();
this.fill(); this.fill(context);
this.stroke(); this.stroke(context);
}, },
x: 200, x: 200,
y: 100, y: 100,
@ -2748,15 +2745,14 @@ Test.prototype.tests = {
}); });
var layer = new Kinetic.Layer(); var layer = new Kinetic.Layer();
var shape = new Kinetic.Shape({ var shape = new Kinetic.Shape({
drawFunc: function() { drawFunc: function(context) {
var context = this.getContext();
context.beginPath(); context.beginPath();
context.moveTo(0, 0); context.moveTo(0, 0);
context.lineTo(100, 0); context.lineTo(100, 0);
context.lineTo(100, 100); context.lineTo(100, 100);
context.closePath(); context.closePath();
this.fill(); this.fill(context);
this.stroke(); this.stroke(context);
}, },
x: 200, x: 200,
y: 100, y: 100,
@ -2765,15 +2761,14 @@ Test.prototype.tests = {
strokeWidth: 5 strokeWidth: 5
}); });
shape.setDrawFunc(function() { shape.setDrawFunc(function(context) {
var context = this.getContext();
context.beginPath(); context.beginPath();
context.moveTo(0, 0); context.moveTo(0, 0);
context.lineTo(200, 0); context.lineTo(200, 0);
context.lineTo(200, 100); context.lineTo(200, 100);
context.closePath(); context.closePath();
this.fill(); this.fill(context);
this.stroke(); this.stroke(context);
}); });
layer.add(shape); layer.add(shape);
@ -4024,6 +4019,8 @@ Test.prototype.tests = {
test(stage.get('.layerName')[0].attrs.id === 'layerId', 'problem with layer name selector'); test(stage.get('.layerName')[0].attrs.id === 'layerId', 'problem with layer name selector');
test(stage.get('#layerId')[0].attrs.id === 'layerId', 'problem with layer id selector'); test(stage.get('#layerId')[0].attrs.id === 'layerId', 'problem with layer id selector');
layer.draw();
}, },
'NODE - test drag and drop properties and methods': function(containerId) { 'NODE - test drag and drop properties and methods': function(containerId) {
var stage = new Kinetic.Stage({ var stage = new Kinetic.Stage({