moved all rendering logic into the Canvas renderer modules. Shape draw funcs are now passed a renderer object, not a canvas context. The context is accessible via canvas.getContext()

This commit is contained in:
Eric Rowell
2012-12-09 09:52:33 -08:00
parent 9be03d6eab
commit 291583148b
23 changed files with 292 additions and 289 deletions

View File

@@ -1,19 +1,17 @@
(function() { (function() {
/** /**
* Canvas wrapper constructor * Canvas Renderer constructor
* @constructor * @constructor
* @param {Number} width * @param {Number} width
* @param {Number} height * @param {Number} height
*/ */
Kinetic.Canvas = function(width, height, isHit) { Kinetic.Canvas = function(width, height) {
this.element = document.createElement('canvas'); this.element = document.createElement('canvas');
this.context = this.element.getContext('2d'); this.context = this.element.getContext('2d');
// set dimensions // set dimensions
this.element.width = width || 0; this.element.width = width || 0;
this.element.height = height || 0; this.element.height = height || 0;
this.context.renderer = isHit ? new Kinetic.HitRenderer(this.context) : new Kinetic.SceneRenderer(this.context);
}; };
Kinetic.Canvas.prototype = { Kinetic.Canvas.prototype = {
@@ -102,14 +100,77 @@
return ''; return '';
} }
} }
},
/**
* fill current path
* @name fill
* @methodOf Kinetic.Canvas.prototype
*/
fill: function(shape) {
this._fill(shape);
},
/**
* stroke current path
* @name stroke
* @methodOf Kinetic.Canvas.prototype
*/
stroke: function(shape) {
this._stroke(shape);
},
/**
* fill and stroke current path.  Aside from being a convenience method
* which fills and strokes the current path with a single method, its main purpose is
* to ensure that the shadow object is not applied to both the fill and stroke.  A shadow
* will only be applied to either the fill or stroke.  Fill
* is given priority over stroke.
* @name fillStroke
* @param {CanvasContext} context
* @methodOf Kinetic.Canvas.prototype
*/
fillStroke: function(shape) {
this._fill(shape);
this._stroke(shape, shape.getShadow() && shape.getFill());
},
/**
* apply shadow
* @name applyShadow
* @param {CanvasContext} context
* @param {Function} func draw function
* @methodOf Kinetic.Canvas.prototype
*/
applyShadow: function(shape, func) {
var context = this.context;
context.save();
this._applyShadow(shape);
func();
context.restore();
func();
},
_applyLineCap: function(shape) {
var lineCap = shape.getLineCap();
if(lineCap) {
this.context.lineCap = lineCap;
}
},
_applyOpacity: function(shape) {
var absOpacity = shape.getAbsoluteOpacity();
if(absOpacity !== 1) {
this.context.globalAlpha = absOpacity;
}
},
_applyLineJoin: function(shape) {
var lineJoin = shape.getLineJoin();
if(lineJoin) {
this.context.lineJoin = lineJoin;
}
} }
}; };
Kinetic.SceneRenderer = function(context) { Kinetic.SceneCanvas = function(width, height) {
this.context = context; Kinetic.Canvas.call(this, width, height);
}; };
Kinetic.SceneRenderer.prototype = { Kinetic.SceneCanvas.prototype = {
_fill: function(shape, skipShadow) { _fill: function(shape, skipShadow) {
var context = this.context, fill = shape.getFill(), fillType = shape._getFillType(fill), shadow = shape.getShadow(); var context = this.context, fill = shape.getFill(), fillType = shape._getFillType(fill), shadow = shape.getShadow();
if(fill) { if(fill) {
@@ -228,20 +289,15 @@
context.shadowOffsetX = offset.x; context.shadowOffsetX = offset.x;
context.shadowOffsetY = offset.y; context.shadowOffsetY = offset.y;
} }
},
_applyLineCap: function(shape) {
var lineCap = shape.getLineCap();
if(lineCap) {
this.context.lineCap = lineCap;
}
} }
}; };
Kinetic.Global.extend(Kinetic.SceneCanvas, Kinetic.Canvas);
Kinetic.HitRenderer = function(context) { Kinetic.HitCanvas = function(width, height) {
this.context = context; Kinetic.Canvas.call(this, width, height);
}; };
Kinetic.HitRenderer.prototype = { Kinetic.HitCanvas.prototype = {
_fill: function(shape) { _fill: function(shape) {
var context = this.context; var context = this.context;
context.save(); context.save();
@@ -259,12 +315,7 @@
context.stroke(context); context.stroke(context);
context.restore(); context.restore();
} }
},
_applyLineCap: function(shape) {
var lineCap = shape.getLineCap();
if(lineCap) {
this.context.lineCap = lineCap;
}
} }
}; };
Kinetic.Global.extend(Kinetic.HitCanvas, Kinetic.Canvas);
})(); })();

View File

@@ -38,9 +38,9 @@
this.nodeType = 'Layer'; this.nodeType = 'Layer';
this.beforeDrawFunc = undefined; this.beforeDrawFunc = undefined;
this.afterDrawFunc = undefined; this.afterDrawFunc = undefined;
this.canvas = new Kinetic.Canvas(); this.canvas = new Kinetic.SceneCanvas();
this.canvas.getElement().style.position = 'absolute'; this.canvas.getElement().style.position = 'absolute';
this.hitCanvas = new Kinetic.Canvas(0, 0, true); this.hitCanvas = new Kinetic.HitCanvas(0, 0);
// call super constructor // call super constructor
Kinetic.Container.call(this, config); Kinetic.Container.call(this, config);
@@ -231,10 +231,10 @@
*/ */
if(!this.isVisible()) { if(!this.isVisible()) {
var stage = this.getStage(); var stage = this.getStage();
canvas = new Kinetic.Canvas(stage.getWidth(), stage.getHeight()); canvas = new Kinetic.SceneCanvas(stage.getWidth(), stage.getHeight());
} }
else if(config && config.width && config.height) { else if(config && config.width && config.height) {
canvas = new Kinetic.Canvas(config.width, config.height); canvas = new Kinetic.SceneCanvas(config.width, config.height);
this.draw(canvas); this.draw(canvas);
} }
else { else {

View File

@@ -744,7 +744,7 @@
//if width and height are defined, create new canvas to draw on, else reuse stage hit canvas //if width and height are defined, create new canvas to draw on, else reuse stage hit canvas
if(config && config.width && config.height) { if(config && config.width && config.height) {
canvas = new Kinetic.Canvas(config.width, config.height); canvas = new Kinetic.SceneCanvas(config.width, config.height);
} }
else { else {
canvas = this.getStage().bufferCanvas; canvas = this.getStage().bufferCanvas;

View File

@@ -119,82 +119,6 @@
return 'UNKNOWN'; return 'UNKNOWN';
} }
}, },
/**
* fill current path
* @name fill
* @methodOf Kinetic.Shape.prototype
*/
fill: function(context) {
context.renderer._fill(this);
},
/**
* stroke current path
* @name stroke
* @methodOf Kinetic.Shape.prototype
*/
stroke: function(context) {
context.renderer._stroke(this);
},
/**
* fill and stroke current path.  Aside from being a convenience method
* which fills and strokes the current path with a single method, its main purpose is
* to ensure that the shadow object is not applied to both the fill and stroke.  A shadow
* will only be applied to either the fill or stroke.  Fill
* is given priority over stroke.
* @name fillStroke
* @param {CanvasContext} context
* @methodOf Kinetic.Shape.prototype
*/
fillStroke: function(context) {
context.renderer._fill(this);
context.renderer._stroke(this, this.getShadow() && this.getFill());
},
/**
* apply shadow
* @name applyShadow
* @param {CanvasContext} context
* @param {Function} func draw function
* @methodOf Kinetic.Shape.prototype
*/
applyShadow: function(context, func) {
context.save();
context.renderer._applyShadow(this);
func();
context.restore();
func();
},
/**
* draw an image
* @name drawImage
* @methodOf Kinetic.Shape.prototype
* @param {CanvasContext} context
*/
drawImage: function() {
var context = arguments[0];
context.save();
var a = Array.prototype.slice.call(arguments);
if(a.length === 6) {
context.drawImage(a[1], a[2], a[3], a[4], a[5]);
}
else if(a.length === 10) {
context.drawImage(a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]);
}
context.restore();
},
_applyOpacity: function(context) {
var absOpacity = this.getAbsoluteOpacity();
if(absOpacity !== 1) {
context.globalAlpha = absOpacity;
}
},
_applyLineJoin: function(context) {
var lineJoin = this.getLineJoin();
if(lineJoin) {
context.lineJoin = lineJoin;
}
},
/** /**
* set shadow object * set shadow object
* @name setShadow * @name setShadow
@@ -306,20 +230,20 @@
} }
context.save(); context.save();
this._applyOpacity(context); canvas._applyOpacity(this);
this._applyLineJoin(context); canvas._applyLineJoin(this);
var len = family.length; var len = family.length;
for(var n = 0; n < len; n++) { for(var n = 0; n < len; n++) {
var node = family[n], t = node.getTransform(), m = t.getMatrix(); var node = family[n], t = node.getTransform(), m = t.getMatrix();
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]);
} }
drawFunc.call(this, context); drawFunc.call(this, canvas);
context.restore(); context.restore();
} }
}, },
drawScene: function() { drawScene: function() {
var attrs = this.attrs, drawFunc = attrs.drawFunc, context = this.getLayer().getCanvas().getContext(); var attrs = this.attrs, drawFunc = attrs.drawFunc, canvas = this.getLayer().getCanvas(), context = canvas.getContext();
if(drawFunc && this.isVisible()) { if(drawFunc && this.isVisible()) {
var stage = this.getStage(), family = [], parent = this.parent; var stage = this.getStage(), family = [], parent = this.parent;
@@ -331,20 +255,20 @@
} }
context.save(); context.save();
this._applyOpacity(context); canvas._applyOpacity(this);
this._applyLineJoin(context); canvas._applyLineJoin(this);
var len = family.length; var len = family.length;
for(var n = 0; n < len; n++) { for(var n = 0; n < len; n++) {
var node = family[n], t = node.getTransform(), m = t.getMatrix(); var node = family[n], t = node.getTransform(), m = t.getMatrix();
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]);
} }
drawFunc.call(this, context); drawFunc.call(this, canvas);
context.restore(); context.restore();
} }
}, },
drawHit: function() { drawHit: function() {
var attrs = this.attrs, drawFunc = attrs.drawHitFunc || attrs.drawFunc, context = this.getLayer().hitCanvas.getContext(); var attrs = this.attrs, drawFunc = attrs.drawHitFunc || attrs.drawFunc, canvas = this.getLayer().hitCanvas, context = canvas.getContext();
if(drawFunc && this.isVisible() && this.isListening()) { if(drawFunc && this.isVisible() && this.isListening()) {
var stage = this.getStage(), family = [], parent = this.parent; var stage = this.getStage(), family = [], parent = this.parent;
@@ -356,14 +280,14 @@
} }
context.save(); context.save();
this._applyLineJoin(context); canvas._applyLineJoin(this);
var len = family.length; var len = family.length;
for(var n = 0; n < len; n++) { for(var n = 0; n < len; n++) {
var node = family[n], t = node.getTransform(), m = t.getMatrix(); var node = family[n], t = node.getTransform(), m = t.getMatrix();
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]);
} }
drawFunc.call(this, context); drawFunc.call(this, canvas);
context.restore(); context.restore();
} }
}, },

View File

@@ -191,7 +191,7 @@
*/ */
var width = config && config.width ? config.width : this.attrs.width; var width = config && config.width ? config.width : this.attrs.width;
var height = config && config.height ? config.height : this.attrs.height; var height = config && config.height ? config.height : this.attrs.height;
var canvas = new Kinetic.Canvas(width, height); var canvas = new Kinetic.SceneCanvas(width, height);
var context = canvas.getContext(); var context = canvas.getContext();
var layers = this.children; var layers = this.children;
@@ -569,8 +569,8 @@
this.content.className = 'kineticjs-content'; this.content.className = 'kineticjs-content';
this.attrs.container.appendChild(this.content); this.attrs.container.appendChild(this.content);
this.bufferCanvas = new Kinetic.Canvas(); this.bufferCanvas = new Kinetic.SceneCanvas();
this.hitCanvas = new Kinetic.Canvas(0, 0, true); this.hitCanvas = new Kinetic.HitCanvas(0, 0);
this._resizeDOM(); this._resizeDOM();
}, },

View File

@@ -21,11 +21,12 @@
Kinetic.Shape.call(this, config); Kinetic.Shape.call(this, config);
this._setDrawFuncs(); this._setDrawFuncs();
}, },
drawFunc: function(context) { drawFunc: function(canvas) {
var context = canvas.getContext();
context.beginPath(); context.beginPath();
context.arc(0, 0, this.getRadius(), 0, Math.PI * 2, true); context.arc(0, 0, this.getRadius(), 0, Math.PI * 2, true);
context.closePath(); context.closePath();
this.fillStroke(context); canvas.fillStroke(this);
}, },
getWidth: function() { getWidth: function() {
return this.getRadius() * 2; return this.getRadius() * 2;

View File

@@ -24,8 +24,8 @@
Kinetic.Shape.call(this, config); Kinetic.Shape.call(this, config);
this._setDrawFuncs(); this._setDrawFuncs();
}, },
drawFunc: function(context) { drawFunc: function(canvas) {
var r = this.getRadius(); var context = canvas.getContext(), r = this.getRadius();
context.beginPath(); context.beginPath();
context.save(); context.save();
if(r.x !== r.y) { if(r.x !== r.y) {
@@ -34,7 +34,7 @@
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.fillStroke(context); canvas.fillStroke(this);
}, },
/** /**
* set radius * set radius

View File

@@ -28,13 +28,13 @@
this._syncSize(); this._syncSize();
}, },
drawFunc: function(context) { drawFunc: function(canvas) {
var width = this.getWidth(), height = this.getHeight(), params, that = this; var width = this.getWidth(), height = this.getHeight(), params, that = this, context = canvas.getContext();
context.beginPath(); context.beginPath();
context.rect(0, 0, width, height); context.rect(0, 0, width, height);
context.closePath(); context.closePath();
this.fillStroke(context); canvas.fillStroke(this);
if(this.attrs.image) { if(this.attrs.image) {
// if cropping // if cropping
@@ -43,41 +43,40 @@
var cropY = this.attrs.crop.y || 0; var cropY = 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;
params = [context, this.attrs.image, cropX, cropY, cropWidth, cropHeight, 0, 0, width, height]; params = [this.attrs.image, cropX, cropY, cropWidth, cropHeight, 0, 0, width, height];
} }
// no cropping // no cropping
else { else {
params = [context, this.attrs.image, 0, 0, width, height]; params = [this.attrs.image, 0, 0, width, height];
} }
if(this.getShadow()) { if(this.getShadow()) {
this.applyShadow(context, function() { canvas.applyShadow(this, function() {
that.drawImage.apply(that, params); that._drawImage(context, params);
}); });
} }
else { else {
this.drawImage.apply(this, params); this._drawImage(context, params);
} }
} }
}, },
drawHitFunc: function(context) { drawHitFunc: function(canvas) {
var width = this.getWidth(), height = this.getHeight(), imageHitRegion = this.imageHitRegion, appliedShadow = false; var width = this.getWidth(), height = this.getHeight(), imageHitRegion = this.imageHitRegion, appliedShadow = false, context = canvas.getContext();
if(imageHitRegion) { if(imageHitRegion) {
this.drawImage(context, imageHitRegion, 0, 0, width, height); context.drawImage(imageHitRegion, 0, 0, width, height);
context.beginPath(); context.beginPath();
context.rect(0, 0, width, height); context.rect(0, 0, width, height);
context.closePath(); context.closePath();
this.stroke(context); canvas.stroke(this);
} }
else { else {
context.beginPath(); context.beginPath();
context.rect(0, 0, width, height); context.rect(0, 0, width, height);
context.closePath(); context.closePath();
this.fillStroke(context); canvas.fillStroke(this);
} }
}, },
/** /**
@@ -180,6 +179,14 @@
this.setHeight(this.attrs.image.height); this.setHeight(this.attrs.image.height);
} }
} }
},
_drawImage: function(context, a) {
if(a.length === 5) {
context.drawImage(a[0], a[1], a[2], a[3], a[4]);
}
else if(a.length === 9) {
context.drawImage(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]);
}
} }
}; };
Kinetic.Global.extend(Kinetic.Image, Kinetic.Shape); Kinetic.Global.extend(Kinetic.Image, Kinetic.Shape);

View File

@@ -24,8 +24,8 @@
Kinetic.Shape.call(this, config); Kinetic.Shape.call(this, config);
this._setDrawFuncs(); this._setDrawFuncs();
}, },
drawFunc: function(context) { drawFunc: function(canvas) {
var lastPos = {}, points = this.getPoints(), length = points.length, dashArray = this.getDashArray(), dashLength = dashArray.length; var lastPos = {}, points = this.getPoints(), length = points.length, dashArray = this.getDashArray(), dashLength = dashArray.length, context = canvas.getContext();
context.beginPath(); context.beginPath();
context.moveTo(points[0].x, points[0].y); context.moveTo(points[0].x, points[0].y);
@@ -34,7 +34,7 @@
context.lineTo(point.x, point.y); context.lineTo(point.x, point.y);
} }
this.stroke(context); canvas.stroke(this);
}, },
/** /**
* set points array * set points array

View File

@@ -25,8 +25,8 @@
that.dataArray = Kinetic.Path.parsePathData(that.attrs.data); that.dataArray = Kinetic.Path.parsePathData(that.attrs.data);
}); });
}, },
drawFunc: function(context) { drawFunc: function(canvas) {
var ca = this.dataArray; var ca = this.dataArray, context = canvas.getContext();
// context position // context position
context.beginPath(); context.beginPath();
for(var n = 0; n < ca.length; n++) { for(var n = 0; n < ca.length; n++) {
@@ -66,7 +66,7 @@
break; break;
} }
} }
this.fillStroke(context); canvas.fillStroke(this);
} }
}; };
Kinetic.Global.extend(Kinetic.Path, Kinetic.Shape); Kinetic.Global.extend(Kinetic.Path, Kinetic.Shape);

View File

@@ -21,14 +21,15 @@
Kinetic.Shape.call(this, config); Kinetic.Shape.call(this, config);
this._setDrawFuncs(); this._setDrawFuncs();
}, },
drawFunc: function(context) { drawFunc: function(canvas) {
var context = canvas.getContext(), points = this.getPoints(), length = points.length;
context.beginPath(); context.beginPath();
context.moveTo(this.attrs.points[0].x, this.attrs.points[0].y); context.moveTo(points[0].x, points[0].y);
for(var n = 1; n < this.attrs.points.length; n++) { for(var n = 1; n < length; n++) {
context.lineTo(this.attrs.points[n].x, this.attrs.points[n].y); context.lineTo(points[n].x, points[n].y);
} }
context.closePath(); context.closePath();
this.fillStroke(context); canvas.fillStroke(this);
}, },
/** /**
* set points array * set points array

View File

@@ -20,7 +20,8 @@
Kinetic.Shape.call(this, config); Kinetic.Shape.call(this, config);
this._setDrawFuncs(); this._setDrawFuncs();
}, },
drawFunc: function(context) { drawFunc: function(canvas) {
var context = canvas.getContext();
context.beginPath(); context.beginPath();
var cornerRadius = this.getCornerRadius(), width = this.getWidth(), height = this.getHeight(); var cornerRadius = this.getCornerRadius(), width = this.getWidth(), height = this.getHeight();
if(cornerRadius === 0) { if(cornerRadius === 0) {
@@ -40,7 +41,7 @@
context.arc(cornerRadius, cornerRadius, cornerRadius, Math.PI, Math.PI * 3 / 2, false); context.arc(cornerRadius, cornerRadius, cornerRadius, Math.PI, Math.PI * 3 / 2, false);
} }
context.closePath(); context.closePath();
this.fillStroke(context); canvas.fillStroke(this);
} }
}; };

View File

@@ -22,17 +22,18 @@
Kinetic.Shape.call(this, config); Kinetic.Shape.call(this, config);
this._setDrawFuncs(); this._setDrawFuncs();
}, },
drawFunc: function(context) { drawFunc: function(canvas) {
var context = canvas.getContext(), sides = this.attrs.sides, radius = this.attrs.radius;
context.beginPath(); context.beginPath();
context.moveTo(0, 0 - this.attrs.radius); context.moveTo(0, 0 - radius);
for(var n = 1; n < this.attrs.sides; n++) { for(var n = 1; n < sides; n++) {
var x = this.attrs.radius * Math.sin(n * 2 * Math.PI / this.attrs.sides); var x = radius * Math.sin(n * 2 * Math.PI / sides);
var y = -1 * this.attrs.radius * Math.cos(n * 2 * Math.PI / this.attrs.sides); var y = -1 * radius * Math.cos(n * 2 * Math.PI / sides);
context.lineTo(x, y); context.lineTo(x, y);
} }
context.closePath(); context.closePath();
this.fillStroke(context); canvas.fillStroke(this);
} }
}; };
Kinetic.Global.extend(Kinetic.RegularPolygon, Kinetic.Shape); Kinetic.Global.extend(Kinetic.RegularPolygon, Kinetic.Shape);

View File

@@ -28,24 +28,20 @@
that.setIndex(0); that.setIndex(0);
}); });
}, },
drawFunc: function(context) { drawFunc: function(canvas) {
var anim = this.attrs.animation; var anim = this.attrs.animation, index = this.attrs.index, f = this.attrs.animations[anim][index], context = canvas.getContext(), image = this.attrs.image;
var index = this.attrs.index;
var f = this.attrs.animations[anim][index];
if(this.attrs.image) { if(image) {
this.drawImage(context, this.attrs.image, f.x, f.y, f.width, f.height, 0, 0, f.width, f.height); context.drawImage(image, f.x, f.y, f.width, f.height, 0, 0, f.width, f.height);
} }
}, },
drawHitFunc: function(context) { drawHitFunc: function(canvas) {
var anim = this.attrs.animation; var anim = this.attrs.animation, index = this.attrs.index, f = this.attrs.animations[anim][index], context = canvas.getContext();
var index = this.attrs.index;
var f = this.attrs.animations[anim][index];
context.beginPath(); context.beginPath();
context.rect(0, 0, f.width, f.height); context.rect(0, 0, f.width, f.height);
context.closePath(); context.closePath();
this.fill(context); canvas.fill(this);
}, },
/** /**
* start sprite animation * start sprite animation

View File

@@ -23,19 +23,21 @@
Kinetic.Shape.call(this, config); Kinetic.Shape.call(this, config);
this._setDrawFuncs(); this._setDrawFuncs();
}, },
drawFunc: function(context) { drawFunc: function(canvas) {
var context = canvas.getContext(), innerRadius = this.attrs.innerRadius, outerRadius = this.attrs.outerRadius, numPoints = this.attrs.numPoints;
context.beginPath(); context.beginPath();
context.moveTo(0, 0 - this.attrs.outerRadius); context.moveTo(0, 0 - this.attrs.outerRadius);
for(var n = 1; n < this.attrs.numPoints * 2; n++) { for(var n = 1; n < numPoints * 2; n++) {
var radius = n % 2 === 0 ? this.attrs.outerRadius : this.attrs.innerRadius; var radius = n % 2 === 0 ? outerRadius : innerRadius;
var x = radius * Math.sin(n * Math.PI / this.attrs.numPoints); var x = radius * Math.sin(n * Math.PI / numPoints);
var y = -1 * radius * Math.cos(n * Math.PI / this.attrs.numPoints); var y = -1 * radius * Math.cos(n * Math.PI / numPoints);
context.lineTo(x, y); context.lineTo(x, y);
} }
context.closePath(); context.closePath();
this.fillStroke(context); canvas.fillStroke(this);
} }
}; };
Kinetic.Global.extend(Kinetic.Star, Kinetic.Shape); Kinetic.Global.extend(Kinetic.Star, Kinetic.Shape);

View File

@@ -42,9 +42,10 @@
} }
that._setTextData(); that._setTextData();
}, },
drawFunc: function(context) { drawFunc: function(canvas) {
var context = canvas.getContext();
// draw rect // draw rect
Kinetic.Rect.prototype.drawFunc.call(this, context); Kinetic.Rect.prototype.drawFunc.call(this, canvas);
// draw text // draw text
var p = this.attrs.padding; var p = this.attrs.padding;
@@ -71,7 +72,7 @@
context.translate((this.getWidth() - this._getTextSize(text).width - p * 2) / 2, 0); context.translate((this.getWidth() - this._getTextSize(text).width - p * 2) / 2, 0);
} }
this.fillStrokeText(context, text); canvas.fillStrokeText(this, text);
context.restore(); context.restore();
context.translate(0, lineHeightPx); context.translate(0, lineHeightPx);
} }
@@ -133,44 +134,6 @@
height: parseInt(this.attrs.fontSize, 10) height: parseInt(this.attrs.fontSize, 10)
}; };
}, },
fillText: function(context, text, skipShadow) {
var textFill = this.getTextFill(), textShadow = this.getTextShadow();
if(textFill) {
context.save();
if(!skipShadow && textShadow) {
this._applyTextShadow(context);
}
context.fillStyle = textFill;
context.fillText(text, 0, 0);
context.restore();
if(!skipShadow && textShadow && textShadow.opacity) {
this.fillText(context, text, true);
}
}
},
strokeText: function(context, text, skipShadow) {
var textStroke = this.getTextStroke(), textStrokeWidth = this.getTextStrokeWidth(), textShadow = this.getTextShadow();
if(textStroke || textStrokeWidth) {
context.save();
if(!skipShadow && textShadow) {
this._applyTextShadow(context);
}
context.lineWidth = textStrokeWidth || 2;
context.strokeStyle = textStroke || 'black';
context.strokeText(text, 0, 0);
context.restore();
if(!skipShadow && textShadow && textShadow.opacity) {
this.strokeText(context, text, true);
}
}
},
fillStrokeText: function(context, text) {
this.fillText(context, text);
this.strokeText(context, text, this.getTextShadow() && this.getTextFill());
},
/** /**
* set text shadow object * set text shadow object
* @name setTextShadow * @name setTextShadow
@@ -253,11 +216,55 @@
row++; row++;
} }
this.textArr = arr; this.textArr = arr;
}, }
_applyTextShadow: function(context) { };
var textShadow = this.getTextShadow(); Kinetic.Global.extend(Kinetic.Text, Kinetic.Shape);
/*
* extend canvas renderers
*/
var fillText = function(shape, text, skipShadow) {
var textFill = shape.getTextFill(), textShadow = shape.getTextShadow(), context = this.context;
if(textFill) {
context.save();
if(!skipShadow && textShadow) {
this._applyTextShadow(shape);
}
context.fillStyle = textFill;
context.fillText(text, 0, 0);
context.restore();
if(!skipShadow && textShadow && textShadow.opacity) {
this.fillText(shape, text, true);
}
}
};
var strokeText = function(shape, text, skipShadow) {
var textStroke = shape.getTextStroke(), textStrokeWidth = shape.getTextStrokeWidth(), textShadow = shape.getTextShadow(), context = this.context;
if(textStroke || textStrokeWidth) {
context.save();
if(!skipShadow && textShadow) {
this._applyTextShadow(shape);
}
context.lineWidth = textStrokeWidth || 2;
context.strokeStyle = textStroke || 'black';
context.strokeText(text, 0, 0);
context.restore();
if(!skipShadow && textShadow && textShadow.opacity) {
this.strokeText(shape, text, true);
}
}
};
var fillStrokeText = function(shape, text) {
this.fillText(shape, text);
this.strokeText(shape, text, shape.getTextShadow() && shape.getTextFill());
};
var _applyTextShadow = function(shape) {
var textShadow = shape.getTextShadow(), context = this.context;
if(textShadow) { if(textShadow) {
var aa = this.getAbsoluteOpacity(); var aa = shape.getAbsoluteOpacity();
// defaults // defaults
var color = textShadow.color || 'black'; var color = textShadow.color || 'black';
var blur = textShadow.blur || 5; var blur = textShadow.blur || 5;
@@ -274,9 +281,18 @@
context.shadowOffsetX = offset.x; context.shadowOffsetX = offset.x;
context.shadowOffsetY = offset.y; context.shadowOffsetY = offset.y;
} }
}
}; };
Kinetic.Global.extend(Kinetic.Text, Kinetic.Shape); // scene canvases
Kinetic.SceneCanvas.prototype.fillText = fillText;
Kinetic.SceneCanvas.prototype.strokeText = strokeText;
Kinetic.SceneCanvas.prototype.fillStrokeText = fillStrokeText;
Kinetic.SceneCanvas.prototype._applyTextShadow = _applyTextShadow;
// hit canvases
Kinetic.HitCanvas.prototype.fillText = fillText;
Kinetic.HitCanvas.prototype.strokeText = strokeText;
Kinetic.HitCanvas.prototype.fillStrokeText = fillStrokeText;
Kinetic.HitCanvas.prototype._applyTextShadow = _applyTextShadow;
// add getters setters // add getters setters
Kinetic.Node.addGettersSetters(Kinetic.Text, ['fontFamily', 'fontSize', 'fontStyle', 'textFill', 'textStroke', 'textStrokeWidth', 'padding', 'align', 'lineHeight']); Kinetic.Node.addGettersSetters(Kinetic.Text, ['fontFamily', 'fontSize', 'fontStyle', 'textFill', 'textStroke', 'textStrokeWidth', 'padding', 'align', 'lineHeight']);

View File

@@ -41,8 +41,8 @@
} }
that._setTextData(); that._setTextData();
}, },
drawFunc: function(context) { drawFunc: function(canvas) {
var charArr = this.charArr; var charArr = this.charArr, context = canvas.getContext();
context.font = this.attrs.fontStyle + ' ' + this.attrs.fontSize + 'pt ' + this.attrs.fontFamily; context.font = this.attrs.fontStyle + ' ' + this.attrs.fontSize + 'pt ' + this.attrs.fontFamily;
context.textBaseline = 'middle'; context.textBaseline = 'middle';
@@ -50,15 +50,7 @@
context.save(); context.save();
var glyphInfo = this.glyphInfo; var glyphInfo = this.glyphInfo;
var appliedShadow = this.appliedShadow;
for(var i = 0; i < glyphInfo.length; i++) { for(var i = 0; i < glyphInfo.length; i++) {
/*
* need to reset appliedShadow flag so that shadows
* are appropriately applied to each line of text
*/
this.appliedShadow = appliedShadow;
context.save(); context.save();
var p0 = glyphInfo[i].p0; var p0 = glyphInfo[i].p0;
@@ -68,7 +60,7 @@
context.translate(p0.x, p0.y); context.translate(p0.x, p0.y);
context.rotate(glyphInfo[i].rotation); context.rotate(glyphInfo[i].rotation);
this.fillStrokeText(context, glyphInfo[i].text); canvas.fillStrokeText(this, glyphInfo[i].text);
context.restore(); context.restore();

View File

@@ -23,12 +23,13 @@
Kinetic.Shape.call(this, config); Kinetic.Shape.call(this, config);
this._setDrawFuncs(); this._setDrawFuncs();
}, },
drawFunc: function(context) { drawFunc: function(canvas) {
var context = canvas.getContext();
context.beginPath(); context.beginPath();
context.arc(0, 0, this.getRadius(), 0, this.getAngle(), this.getClockwise()); context.arc(0, 0, this.getRadius(), 0, this.getAngle(), this.getClockwise());
context.lineTo(0, 0); context.lineTo(0, 0);
context.closePath(); context.closePath();
this.fillStroke(context); canvas.fillStroke(this);
}, },
setAngleDeg: function(deg) { setAngleDeg: function(deg) {
this.setAngle(Kinetic.Type._degToRad(deg)); this.setAngle(Kinetic.Type._degToRad(deg));

File diff suppressed because one or more lines are too long

View File

@@ -38,7 +38,6 @@ Test.Modules.DD = {
circle.on('dragend', function() { circle.on('dragend', function() {
dragEnd = true; dragEnd = true;
}); });
warn(layer.toDataURL() === dataUrls['drag circle before'], 'start data url is incorrect'); warn(layer.toDataURL() === dataUrls['drag circle before'], 'start data url is incorrect');
/* /*
* simulate drag and drop * simulate drag and drop
@@ -869,12 +868,13 @@ Test.Modules['HIT FUNCS'] = {
strokeWidth: 4, strokeWidth: 4,
fill: 'red', fill: 'red',
stroke: 'black', stroke: 'black',
drawHitFunc: function(context) { drawHitFunc: function(canvas) {
var context = canvas.getContext()
context.beginPath(); context.beginPath();
context.arc(0, 0, this.getRadius() + 100, 0, Math.PI * 2, true); context.arc(0, 0, this.getRadius() + 100, 0, Math.PI * 2, true);
context.closePath(); context.closePath();
this.fill(context); canvas.fill(this);
this.stroke(context); canvas.stroke(this);
} }
}); });
@@ -895,7 +895,6 @@ Test.Modules['HIT FUNCS'] = {
circle.on('mouseout', function() { circle.on('mouseout', function() {
mouseouts++; mouseouts++;
}); });
// move mouse far outside circle // move mouse far outside circle
stage._mousemove({ stage._mousemove({
clientX: 113, clientX: 113,
@@ -923,12 +922,13 @@ Test.Modules['HIT FUNCS'] = {
// set drawBufferFunc with setter // set drawBufferFunc with setter
circle.setDrawHitFunc(function(context) { circle.setDrawHitFunc(function(canvas) {
var context = canvas.getContext();
context.beginPath(); context.beginPath();
context.arc(0, 0, this.getRadius() - 50, 0, Math.PI * 2, true); context.arc(0, 0, this.getRadius() - 50, 0, Math.PI * 2, true);
context.closePath(); context.closePath();
this.fill(context); canvas.fill(this);
this.stroke(context); canvas.stroke(this);
}); });
layer.drawHit(); layer.drawHit();

View File

@@ -625,8 +625,11 @@ Test.Modules.CONTAINER = {
test(group.get('Rect').length === 1, 'group should have 1 rects'); test(group.get('Rect').length === 1, 'group should have 1 rects');
test(group.get('Circle').length === 1, 'gropu should have 1 circles'); test(group.get('Circle').length === 1, 'gropu should have 1 circles');
//console.log(dataUrls['node shape type selector']);
stage.toDataURL({ stage.toDataURL({
callback: function(dataUrl) { callback: function(dataUrl) {
//console.log(dataUrl)
warn(dataUrl === dataUrls['node shape type selector'], 'problem with node and shape type selector render.'); warn(dataUrl === dataUrls['node shape type selector'], 'problem with node and shape type selector render.');
} }
}); });

View File

@@ -278,6 +278,7 @@ Test.Modules.NODE = {
draggable: true, draggable: true,
name: 'myGroup' name: 'myGroup'
}); });
var rect = new Kinetic.Rect({ var rect = new Kinetic.Rect({
x: 0, x: 0,
y: 50, y: 50,
@@ -741,7 +742,6 @@ Test.Modules.NODE = {
width: 500, width: 500,
height: 300, height: 300,
callback: function(imageObj) { callback: function(imageObj) {
//document.body.appendChild(imageObj) //document.body.appendChild(imageObj)
test(Kinetic.Type._isElement(imageObj), 'shape toImage() should be an image object'); test(Kinetic.Type._isElement(imageObj), 'shape toImage() should be an image object');
@@ -2008,14 +2008,15 @@ Test.Modules.NODE = {
var layer = new Kinetic.Layer(); var layer = new Kinetic.Layer();
var group = new Kinetic.Group(); var group = new Kinetic.Group();
var drawTriangle = function(context) { var drawTriangle = function(canvas) {
var context = canvas.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(context); canvas.fill(this);
this.stroke(context); canvas.stroke(this);
}; };
var triangle = new Kinetic.Shape({ var triangle = new Kinetic.Shape({
drawFunc: drawTriangle, drawFunc: drawTriangle,
@@ -2051,14 +2052,15 @@ Test.Modules.NODE = {
}, },
'load stage with custom shape using json': function(containerId) { 'load stage with custom shape using json': function(containerId) {
var drawTriangle = function(context) { var drawTriangle = function(canvas) {
var context = canvas.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(context); canvas.fill(this);
this.stroke(context); canvas.stroke(this);
}; };
var json = '{"attrs":{"width":578,"height":200,"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false},"nodeType":"Stage","children":[{"attrs":{"clearBeforeDraw":true,"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false},"nodeType":"Layer","children":[{"attrs":{"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false},"nodeType":"Group","children":[{"attrs":{"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false,"fill":"#00D2FF","stroke":"black","strokeWidth":4,"id":"myTriangle"},"nodeType":"Shape"}]}]}]}'; var json = '{"attrs":{"width":578,"height":200,"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false},"nodeType":"Stage","children":[{"attrs":{"clearBeforeDraw":true,"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false},"nodeType":"Layer","children":[{"attrs":{"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false},"nodeType":"Group","children":[{"attrs":{"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false,"fill":"#00D2FF","stroke":"black","strokeWidth":4,"id":"myTriangle"},"nodeType":"Shape"}]}]}]}';

View File

@@ -53,20 +53,21 @@ Test.Modules.SHAPE = {
}); });
var layer = new Kinetic.Layer(); var layer = new Kinetic.Layer();
var drawTriangle = function(context) { var drawTriangle = function(canvas) {
var context = canvas.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.fillStroke(context); canvas.fillStroke(this);
context.beginPath(); context.beginPath();
context.moveTo(300, 150); context.moveTo(300, 150);
context.lineTo(520, 180); context.lineTo(520, 180);
context.quadraticCurveTo(400, 200, 360, 270); context.quadraticCurveTo(400, 200, 360, 270);
context.closePath(); context.closePath();
this.fillStroke(context); canvas.fillStroke(this);
}; };
var triangle = new Kinetic.Shape({ var triangle = new Kinetic.Shape({
drawFunc: drawTriangle, drawFunc: drawTriangle,
@@ -98,14 +99,15 @@ Test.Modules.SHAPE = {
}); });
var layer = new Kinetic.Layer(); var layer = new Kinetic.Layer();
var shape = new Kinetic.Shape({ var shape = new Kinetic.Shape({
drawFunc: function(context) { drawFunc: function(canvas) {
var context = canvas.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(context); canvas.fill(this);
this.stroke(context); canvas.stroke(this);
}, },
x: 200, x: 200,
y: 100, y: 100,
@@ -125,14 +127,15 @@ Test.Modules.SHAPE = {
}); });
var layer = new Kinetic.Layer(); var layer = new Kinetic.Layer();
var shape = new Kinetic.Shape({ var shape = new Kinetic.Shape({
drawFunc: function(context) { drawFunc: function(canvas) {
var context = canvas.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(context); canvas.fill(this);
this.stroke(context); canvas.stroke(this);
}, },
x: 200, x: 200,
y: 100, y: 100,
@@ -141,14 +144,15 @@ Test.Modules.SHAPE = {
strokeWidth: 5 strokeWidth: 5
}); });
shape.setDrawFunc(function(context) { shape.setDrawFunc(function(canvas) {
var context = canvas.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(context); canvas.fill(this);
this.stroke(context); canvas.stroke(this);
}); });
var rect = new Kinetic.Rect({ var rect = new Kinetic.Rect({
x: 10, x: 10,
@@ -161,14 +165,15 @@ Test.Modules.SHAPE = {
draggable: true draggable: true
}); });
rect.setDrawFunc(function(context) { rect.setDrawFunc(function(canvas) {
var context = canvas.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(context); canvas.fill(this);
this.stroke(context); canvas.stroke(this);
}); });
layer.add(shape); layer.add(shape);