finished up new Scene and Hit Renderers. added new textShadow attrs for more flexibility. Added new fillStroke() method which encapsulates shadow application logic

This commit is contained in:
Eric Rowell
2012-11-23 14:54:32 -08:00
parent 144e95ad42
commit 318d03feb7
16 changed files with 308 additions and 291 deletions

View File

@@ -98,49 +98,6 @@ Kinetic.Shape = (function() {
getCanvas: function() { getCanvas: function() {
return this.getLayer().getCanvas(); return this.getLayer().getCanvas();
}, },
/**
* helper method to stroke the shape
* @name stroke
* @methodOf Kinetic.Shape.prototype
*/
stroke: function(context, stroke, strokeWidth, shadow) {
if(context.type === 'scene') {
return this._strokeScene(context, stroke, strokeWidth, shadow);
}
else if(context.type === 'hit') {
return this._strokeHit(context, strokeWidth);
}
return false;
},
_strokeScene: function(context, stroke, strokeWidth, shadow) {
if(stroke || strokeWidth) {
context.save();
var appliedShadow = this._applyShadow(context, shadow);
context.lineWidth = strokeWidth || 2;
context.strokeStyle = stroke || 'black';
context.stroke(context);
context.restore();
if(appliedShadow) {
if(shadow.opacity) {
this._strokeScene(context, stroke);
}
return true;
}
}
return false;
},
_strokeHit: function(context, strokeWidth) {
var stroke = this.colorKey;
if(stroke || strokeWidth) {
context.save();
context.lineWidth = strokeWidth || 2;
context.strokeStyle = stroke || 'black';
context.stroke(context);
context.restore();
}
return false;
},
_getFillType: function(fill) { _getFillType: function(fill) {
var type = Kinetic.Type; var type = Kinetic.Type;
if(!fill) { if(!fill) {
@@ -163,111 +120,36 @@ Kinetic.Shape = (function() {
} }
}, },
/** /**
* helper method to fill and stroke shape based on fill and stroke properties, * fill current path
* and also automatically handle shadows, line joins, and line caps
* @name render
* @methodOf Kinetic.Shape.prototype
*/
render: function(context) {
this.applyLineJoin(context, this.getLineJoin());
this.applyLineCap(context, this.getLineCap());
if(context.type === 'scene') {
this.applyOpacity(context);
}
var appliedShadow = this.fill(context, this.getFill(), this.getShadow());
this.stroke(context, this.getStroke(), this.getStrokeWidth(), appliedShadow ? null : this.getShadow());
},
/**
* helper method to fill the shape
* @name fill * @name fill
* @methodOf Kinetic.Shape.prototype * @methodOf Kinetic.Shape.prototype
*/ */
fill: function(context, fill, shadow) { fill: function(context) {
if(context.type === 'scene') { context.renderer._fill(this);
return this._fillScene(context, fill, shadow);
}
else if(context.type === 'hit') {
return this._fillHit(context);
}
return false;
},
_fillScene: function(context, fill, shadow) {
var fillType = this._getFillType(fill);
if(fill) {
context.save();
var appliedShadow = this._applyShadow(context, shadow);
var s = fill.start;
var e = fill.end;
// color fill
switch(fillType) {
case 'COLOR':
context.fillStyle = fill;
context.fill(context);
break;
case 'PATTERN':
var repeat = !fill.repeat ? 'repeat' : fill.repeat;
if(fill.scale) {
context.scale(fill.scale.x, fill.scale.y);
}
if(fill.offset) {
context.translate(fill.offset.x, fill.offset.y);
}
context.fillStyle = context.createPattern(fill.image, repeat);
context.fill(context);
break;
case 'LINEAR_GRADIENT':
var grd = context.createLinearGradient(s.x, s.y, e.x, e.y);
var colorStops = fill.colorStops;
// build color stops
for(var n = 0; n < colorStops.length; n += 2) {
grd.addColorStop(colorStops[n], colorStops[n + 1]);
}
context.fillStyle = grd;
context.fill(context);
break;
case 'RADIAL_GRADIENT':
var grd = context.createRadialGradient(s.x, s.y, s.radius, e.x, e.y, e.radius);
var colorStops = fill.colorStops;
// build color stops
for(var n = 0; n < colorStops.length; n += 2) {
grd.addColorStop(colorStops[n], colorStops[n + 1]);
}
context.fillStyle = grd;
context.fill(context);
break;
default:
context.fillStyle = 'black';
context.fill(context);
break;
}
context.restore();
if(appliedShadow) {
if(shadow.opacity) {
this._fillScene(context, fill);
}
return true;
}
}
return false;
},
_fillHit: function(context) {
context.save();
context.fillStyle = this.colorKey;
context.fill(context);
context.restore();
return false;
}, },
/** /**
* helper method to draw an image * stroke current path
* @name stroke
* @methodOf Kinetic.Shape.prototype
*/
stroke: function(context) {
context.renderer._stroke(this);
},
/**
* fill and stroke current path.&nbsp; 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.&nbsp; A shadow
* will only be applied to either the fill or stroke.&nbsp; Fill
* is given priority over stroke.
* @name fillStroke
* @methodOf Kinetic.Shape.prototype
*/
fillStroke: function(context) {
context.renderer._fill(this);
context.renderer._stroke(this, this.getShadow() && this.getFill());
},
/**
* draw an image
* @name drawImage * @name drawImage
* @methodOf Kinetic.Shape.prototype * @methodOf Kinetic.Shape.prototype
*/ */
@@ -287,34 +169,20 @@ Kinetic.Shape = (function() {
context.restore(); context.restore();
}, },
applyOpacity: function(context) { _applyOpacity: function(context) {
var absOpacity = this.getAbsoluteOpacity(); var absOpacity = this.getAbsoluteOpacity();
if(absOpacity !== 1) { if(absOpacity !== 1) {
context.globalAlpha = absOpacity; context.globalAlpha = absOpacity;
} }
}, },
/** _applyLineJoin: function(context) {
* helper method to set the line join of a shape var lineJoin = this.getLineJoin();
* based on the applyLineJoin property
* @name lineJoin
* @methodOf Kinetic.Shape.prototype
* @param {CanvasContext} context
* @param {String} lineJoin
*/
applyLineJoin: function(context, lineJoin) {
if(lineJoin) { if(lineJoin) {
context.lineJoin = lineJoin; context.lineJoin = lineJoin;
} }
}, },
/** _applyLineCap: function(context) {
* helper method to set the line cap of a path var lineCap = this.getLineCap();
* based on the lineCap property
* @name applyLineCap
* @methodOf Kinetic.Shape.prototype
* @param {CanvasContext} context
* @param {String} lineCap
*/
applyLineCap: function(context, lineCap) {
if(lineCap) { if(lineCap) {
context.lineCap = lineCap; context.lineCap = lineCap;
} }
@@ -391,29 +259,6 @@ Kinetic.Shape = (function() {
_get: function(selector) { _get: function(selector) {
return this.nodeType === selector || this.shapeType === selector ? [this] : []; return this.nodeType === selector || this.shapeType === selector ? [this] : [];
}, },
_applyShadow: function(context, shadow) {
if(shadow) {
var aa = this.getAbsoluteOpacity();
// defaults
var color = shadow.color || 'black';
var blur = shadow.blur || 5;
var offset = shadow.offset || {
x: 0,
y: 0
};
if(shadow.opacity) {
context.globalAlpha = shadow.opacity * aa;
}
context.shadowColor = color;
context.shadowBlur = blur;
context.shadowOffsetX = offset.x;
context.shadowOffsetY = offset.y;
return true;
}
return false;
},
/** /**
* determines if point is in the shape * determines if point is in the shape
* @param {Object|Array} point point can be an object containing * @param {Object|Array} point point can be an object containing
@@ -447,6 +292,9 @@ Kinetic.Shape = (function() {
} }
context.save(); context.save();
this._applyOpacity(context);
this._applyLineJoin(context);
this._applyLineCap(context);
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();
@@ -470,6 +318,9 @@ Kinetic.Shape = (function() {
} }
context.save(); context.save();
this._applyOpacity(context);
this._applyLineJoin(context);
this._applyLineCap(context);
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();
@@ -493,6 +344,8 @@ Kinetic.Shape = (function() {
} }
context.save(); context.save();
this._applyLineJoin(context);
this._applyLineCap(context);
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();

View File

@@ -27,7 +27,7 @@ Kinetic.Circle.prototype = {
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.render(context); this.fillStroke(context);
}, },
getWidth: function() { getWidth: function() {
return this.getRadius() * 2; return this.getRadius() * 2;

View File

@@ -36,7 +36,7 @@ Kinetic.Ellipse.prototype = {
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.render(context); this.fillStroke(context);
}, },
/** /**
* set radius * set radius

View File

@@ -36,7 +36,7 @@ Kinetic.Image.prototype = {
context.beginPath(); context.beginPath();
context.rect(0, 0, width, height); context.rect(0, 0, width, height);
context.closePath(); context.closePath();
this.render(context); this.fillStroke(context);
if(this.attrs.image) { if(this.attrs.image) {
// if cropping // if cropping
@@ -59,7 +59,7 @@ Kinetic.Image.prototype = {
context.beginPath(); context.beginPath();
context.rect(0, 0, width, height); context.rect(0, 0, width, height);
context.closePath(); context.closePath();
this.render(context); this.fillStroke(context);
if(imageBuffer) { if(imageBuffer) {
this.drawImage(context, this.imageBuffer, 0, 0, width, height); this.drawImage(context, this.imageBuffer, 0, 0, width, height);

View File

@@ -47,7 +47,7 @@ Kinetic.Line.prototype = {
} }
} }
this.stroke(context, this.getStroke(), this.getStrokeWidth(), this.getShadow()); this.stroke(context);
}, },
/** /**
* set points array * set points array

View File

@@ -68,7 +68,7 @@ Kinetic.Path.prototype = {
break; break;
} }
} }
this.render(context); this.fillStroke(context);
} }
}; };
Kinetic.Global.extend(Kinetic.Path, Kinetic.Shape); Kinetic.Global.extend(Kinetic.Path, Kinetic.Shape);

View File

@@ -30,7 +30,7 @@ Kinetic.Polygon.prototype = {
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.render(context); this.fillStroke(context);
}, },
/** /**
* set points array * set points array

View File

@@ -42,7 +42,7 @@ Kinetic.Rect.prototype = {
} }
context.closePath(); context.closePath();
this.render(context); this.fillStroke(context);
} }
}; };

View File

@@ -34,7 +34,7 @@ Kinetic.RegularPolygon.prototype = {
context.lineTo(x, y); context.lineTo(x, y);
} }
context.closePath(); context.closePath();
this.render(context); this.fillStroke(context);
} }
}; };
Kinetic.Global.extend(Kinetic.RegularPolygon, Kinetic.Shape); Kinetic.Global.extend(Kinetic.RegularPolygon, Kinetic.Shape);

View File

@@ -35,11 +35,6 @@ Kinetic.Sprite.prototype = {
var index = this.attrs.index; var index = this.attrs.index;
var f = this.attrs.animations[anim][index]; var f = this.attrs.animations[anim][index];
context.beginPath();
context.rect(0, 0, f.width, f.height);
context.closePath();
this.render(context);
if(this.attrs.image) { if(this.attrs.image) {
context.beginPath(); context.beginPath();
@@ -57,8 +52,7 @@ Kinetic.Sprite.prototype = {
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, this.getFill(), null); this.fillStroke(context);
this.stroke(context, this.getStroke(), this.getStrokeWidth(), null);
}, },
/** /**
* start sprite animation * start sprite animation

View File

@@ -37,7 +37,7 @@ Kinetic.Star.prototype = {
} }
context.closePath(); context.closePath();
this.render(context); this.fillStroke(context);
} }
}; };
Kinetic.Global.extend(Kinetic.Star, Kinetic.Shape); Kinetic.Global.extend(Kinetic.Star, Kinetic.Shape);

View File

@@ -68,7 +68,7 @@ Kinetic.Text.prototype = {
} }
context.closePath(); context.closePath();
this.render(context); this.fillStroke(context);
/* /*
* draw text * draw text
*/ */
@@ -96,10 +96,8 @@ Kinetic.Text.prototype = {
context.translate((this.getWidth() - this._getTextSize(text).width - p * 2) / 2, 0); context.translate((this.getWidth() - this._getTextSize(text).width - p * 2) / 2, 0);
} }
var appliedShadow = this.fillText(context, text, this.getTextFill(), this.getShadow()); this.fillStrokeText(context, text);
this.strokeText(context, text, this.getTextStroke(), this.getTextStrokeWidth(), appliedShadow ? null : this.getShadow());
context.restore(); context.restore();
context.translate(0, lineHeightPx); context.translate(0, lineHeightPx);
} }
context.restore(); context.restore();
@@ -128,7 +126,7 @@ Kinetic.Text.prototype = {
} }
context.closePath(); context.closePath();
this.render(context); this.fillStroke(context);
}, },
/** /**
* set text * set text
@@ -185,92 +183,60 @@ Kinetic.Text.prototype = {
height: parseInt(this.attrs.fontSize, 10) height: parseInt(this.attrs.fontSize, 10)
}; };
}, },
/** fillText: function(context, text, skipShadow) {
* helper method to fill text var textFill = this.getTextFill(), shadow = this.getShadow();
* @param {String} text
* @name fillText
* @methodOf Kinetic.Text.prototype
*/
fillText: function(context, text, textFill, shadow) {
if(context.type === 'scene') {
return this._fillTextScene(context, text, textFill, shadow);
}
else if(context.type === 'hit') {
return this._fillTextHit(context, text);
}
return false;
},
_fillTextScene: function(context, text, textFill, shadow) {
if(textFill) { if(textFill) {
context.save(); context.save();
var appliedShadow = this._applyShadow(context, shadow); if(!skipShadow && shadow) {
this._applyTextShadow(context);
}
context.fillStyle = textFill; context.fillStyle = textFill;
context.fillText(text, 0, 0); context.fillText(text, 0, 0);
context.restore(); context.restore();
if(appliedShadow) { if(!skipShadow && shadow && shadow.opacity) {
if(shadow.opacity) { this.fillText(context, text, true);
this._fillTextScene(context, text, textFill);
return true;
} }
} }
}
return false;
}, },
_fillTextHit: function(context, text) { strokeText: function(context, text, skipShadow) {
context.save(); var textStroke = this.getTextStroke(), textStrokeWidth = this.getTextStrokeWidth(), shadow = this.getShadow();
context.fillStyle = this.colorKey;
context.fillText(text, 0, 0);
context.restore();
return false;
},
/**
* helper method to stroke text
* if needed
* @name strokeText
* @methodOf Kinetic.Shape.prototype
* @param {String} text
*/
strokeText: function(context, text, textStroke, textStrokeWidth, shadow) {
if(context.type === 'scene') {
this._strokeTextScene(context, text, textStroke, textStrokeWidth, shadow);
}
else if(context.type === 'hit') {
this._strokeTextHit(context, text, textStrokeWidth);
}
return false;
},
_strokeTextScene: function(context, text, textStroke, textStrokeWidth, shadow) {
if(textStroke || textStrokeWidth) { if(textStroke || textStrokeWidth) {
context.save(); context.save();
var appliedShadow = this._applyShadow(context, shadow); if(!skipShadow && shadow) {
// defaults this._applyTextShadow(context);
textStroke = textStroke || 'black'; }
textStrokeWidth = textStrokeWidth || 2;
context.lineWidth = textStrokeWidth; context.lineWidth = textStrokeWidth || 2;
context.strokeStyle = textStroke; context.strokeStyle = textStroke || 'black';
context.strokeText(text, 0, 0); context.strokeText(text, 0, 0);
context.restore(); context.restore();
if(appliedShadow) { if(!skipShadow && shadow && shadow.opacity) {
if(shadow.opacity) { this.strokeText(context, text, true);
this._strokeTextScene(context, text, textStroke, textStrokeWidth);
return true;
} }
} }
}
return false;
}, },
_strokeTextHit: function(context, text, textStrokeWidth) { fillStrokeText: function(context, text) {
context.save(); this.fillText(context, text);
// defaults this.strokeText(context, text, this.getTextShadow() && this.getTextFill());
var textStroke = this.colorKey ? this.colorKey : 'black'; },
var textStrokeWidth = textStrokeWidth || 2; /**
context.lineWidth = textStrokeWidth; * set text shadow object
context.strokeStyle = textStroke; * @name setTextShadow
context.strokeText(text, 0, 0); * @methodOf Kinetic.Text.prototype
context.restore(); * @param {Object} config
return false; * @param {String} config.color
* @param {Number} config.blur
* @param {Array|Object|Number} config.offset
* @param {Number} config.opacity
*/
setTextShadow: function(config) {
var type = Kinetic.Type;
if(config.offset !== undefined) {
config.offset = type._getXY(config.offset);
}
this.setAttr('textShadow', type._merge(config, this.getTextShadow()));
}, },
/** /**
* set text data. wrap logic and width and height setting occurs * set text data. wrap logic and width and height setting occurs
@@ -337,13 +303,34 @@ Kinetic.Text.prototype = {
row++; row++;
} }
this.textArr = arr; this.textArr = arr;
},
_applyTextShadow: function(context) {
var textShadow = this.getTextShadow();
if(textShadow) {
var aa = this.getAbsoluteOpacity();
// defaults
var color = textShadow.color || 'black';
var blur = textShadow.blur || 5;
var offset = textShadow.offset || {
x: 0,
y: 0
};
if(textShadow.opacity) {
context.globalAlpha = textShadow.opacity * aa;
}
context.shadowColor = color;
context.shadowBlur = blur;
context.shadowOffsetX = offset.x;
context.shadowOffsetY = offset.y;
}
} }
}; };
Kinetic.Global.extend(Kinetic.Text, Kinetic.Shape); Kinetic.Global.extend(Kinetic.Text, Kinetic.Shape);
// 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']);
Kinetic.Node.addGetters(Kinetic.Text, ['text']); Kinetic.Node.addGetters(Kinetic.Text, ['text', 'textShadow']);
/** /**
* set font family * set font family
* @name setFontFamily * @name setFontFamily

View File

@@ -70,7 +70,7 @@ Kinetic.TextPath.prototype = {
context.translate(p0.x, p0.y); context.translate(p0.x, p0.y);
context.rotate(glyphInfo[i].rotation); context.rotate(glyphInfo[i].rotation);
this.render(context); this.fillStrokeText(context);
context.restore(); context.restore();
@@ -307,11 +307,9 @@ Kinetic.Node.addGetters(Kinetic.TextPath, ['text']);
// reference Text methods // reference Text methods
Kinetic.TextPath.prototype.fillText = Kinetic.Text.prototype.fillText; Kinetic.TextPath.prototype.fillText = Kinetic.Text.prototype.fillText;
Kinetic.TextPath.prototype._fillTextScene = Kinetic.Text.prototype._fillTextScene;
Kinetic.TextPath.prototype._fillTextHit = Kinetic.Text.prototype._fillTextHit;
Kinetic.TextPath.prototype.strokeText = Kinetic.Text.prototype.strokeText; Kinetic.TextPath.prototype.strokeText = Kinetic.Text.prototype.strokeText;
Kinetic.TextPath.prototype._strokeTextScene = Kinetic.Text.prototype._strokeTextScene; Kinetic.TextPath.prototype.fillStrokeText = Kinetic.Text.prototype.strokeText;
Kinetic.TextPath.prototype._strokeTextHit = Kinetic.Text.prototype._strokeTextHit;
/** /**
* set font family * set font family
* @name setFontFamily * @name setFontFamily

View File

@@ -12,8 +12,7 @@ Kinetic.Canvas = function(width, height, isHit) {
this.element.width = width || 0; this.element.width = width || 0;
this.element.height = height || 0; this.element.height = height || 0;
// set type this.context.renderer = isHit ? new Kinetic.HitRenderer(this.context) : new Kinetic.SceneRenderer(this.context);
this.context.type = isHit ? 'hit' : 'scene';
}; };
Kinetic.Canvas.prototype = { Kinetic.Canvas.prototype = {
@@ -98,3 +97,137 @@ Kinetic.Canvas.prototype = {
} }
} }
}; };
Kinetic.SceneRenderer = function(context) {
this.context = context;
};
Kinetic.SceneRenderer.prototype = {
_fill: function(shape, skipShadow) {
var context = this.context, fill = shape.getFill(), fillType = shape._getFillType(fill), shadow = shape.getShadow();
if(fill) {
context.save();
if(!skipShadow && shadow) {
this._applyShadow(shape);
}
var s = fill.start;
var e = fill.end;
// color fill
switch(fillType) {
case 'COLOR':
context.fillStyle = fill;
context.fill(context);
break;
case 'PATTERN':
var repeat = !fill.repeat ? 'repeat' : fill.repeat;
if(fill.scale) {
context.scale(fill.scale.x, fill.scale.y);
}
if(fill.offset) {
context.translate(fill.offset.x, fill.offset.y);
} file:///C:/Users/Eric/Documents/Eric/workspaces/KineticJS/dist/kinetic-current.js
context.fillStyle = context.createPattern(fill.image, repeat);
context.fill(context);
break;
case 'LINEAR_GRADIENT':
var grd = context.createLinearGradient(s.x, s.y, e.x, e.y);
var colorStops = fill.colorStops;
// build color stops
for(var n = 0; n < colorStops.length; n += 2) {
grd.addColorStop(colorStops[n], colorStops[n + 1]);
}
context.fillStyle = grd;
context.fill(context);
break;
case 'RADIAL_GRADIENT':
var grd = context.createRadialGradient(s.x, s.y, s.radius, e.x, e.y, e.radius);
var colorStops = fill.colorStops;
// build color stops
for(var n = 0; n < colorStops.length; n += 2) {
grd.addColorStop(colorStops[n], colorStops[n + 1]);
}
context.fillStyle = grd;
context.fill(context);
break;
default:
context.fillStyle = 'black';
context.fill(context);
break;
}
context.restore();
if(!skipShadow && shadow && shadow.opacity) {
this._fill(shape, true);
}
}
},
_stroke: function(shape, skipShadow) {
var context = this.context, stroke = shape.getStroke(), strokeWidth = shape.getStrokeWidth(), shadow = shape.getShadow();
if(stroke || strokeWidth) {
context.save();
if(!skipShadow && shadow) {
this._applyShadow(shape);
}
context.lineWidth = strokeWidth || 2;
context.strokeStyle = stroke || 'black';
context.stroke(context);
context.restore();
if(!skipShadow && shadow && shadow.opacity) {
this._stroke(shape, true);
}
}
},
_applyShadow: function(shape) {
var context = this.context, shadow = shape.getShadow();
if(shadow) {
var aa = shape.getAbsoluteOpacity();
// defaults
var color = shadow.color || 'black';
var blur = shadow.blur || 5;
var offset = shadow.offset || {
x: 0,
y: 0
};
if(shadow.opacity) {
context.globalAlpha = shadow.opacity * aa;
}
context.shadowColor = color;
context.shadowBlur = blur;
context.shadowOffsetX = offset.x;
context.shadowOffsetY = offset.y;
}
}
};
Kinetic.HitRenderer = function(context) {
this.context = context;
};
Kinetic.HitRenderer.prototype = {
_fill: function(shape) {
var context = this.context;
context.save();
context.fillStyle = shape.colorKey;
context.fill(context);
context.restore();
},
_stroke: function(shape) {
var context = this.context, stroke = shape.colorKey, strokeWidth = shape.getStrokeWidth();
if(stroke || strokeWidth) {
context.save();
context.lineWidth = strokeWidth || 2;
context.strokeStyle = stroke || 'black';
context.stroke(context);
context.restore();
}
}
};

View File

@@ -141,7 +141,8 @@ Test.Modules.SHAPE = {
context.lineTo(100, 0); context.lineTo(100, 0);
context.lineTo(100, 100); context.lineTo(100, 100);
context.closePath(); context.closePath();
this.render(context); this.fill(context);
this.stroke(context);
}, },
x: 200, x: 200,
y: 100, y: 100,
@@ -156,7 +157,8 @@ Test.Modules.SHAPE = {
context.lineTo(200, 0); context.lineTo(200, 0);
context.lineTo(200, 100); context.lineTo(200, 100);
context.closePath(); context.closePath();
this.render(context); this.fill(context);
this.stroke(context);
}); });
var rect = new Kinetic.Rect({ var rect = new Kinetic.Rect({
x: 10, x: 10,
@@ -175,7 +177,8 @@ Test.Modules.SHAPE = {
context.lineTo(200, 0); context.lineTo(200, 0);
context.lineTo(200, 100); context.lineTo(200, 100);
context.closePath(); context.closePath();
this.render(context); this.fill(context);
this.stroke(context);
}); });
layer.add(shape); layer.add(shape);

View File

@@ -1,4 +1,53 @@
Test.Modules.Text = { Test.Modules.Text = {
'add text with shadows': function(containerId) {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
var text = new Kinetic.Text({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
stroke: '#555',
strokeWidth: 5,
fill: '#ddd',
text: 'Hello World!',
fontSize: 50,
fontFamily: 'Calibri',
fontStyle: 'normal',
textFill: '#888',
textStroke: '#333',
align: 'right',
lineHeight: 1.2,
width: 400,
height: 100,
padding: 10,
shadow: {
color: 'black',
blur: 1,
offset: [10, 10],
opacity: 0.2
},
textShadow: {
color: 'red',
blur: 1,
offset: [10, 10],
opacity: 0.2
},
cornerRadius: 10,
draggable: true
});
// center text box
text.setOffset(text.getWidth() / 2, text.getHeight() / 2);
layer.add(text);
stage.add(layer);
},
'text getters and setters': function(containerId) { 'text getters and setters': function(containerId) {
var stage = new Kinetic.Stage({ var stage = new Kinetic.Stage({
container: containerId, container: containerId,