mirror of
https://github.com/konvajs/konva.git
synced 2025-09-19 02:37:59 +08:00
preparation work for new Renderer inheritance pattern
This commit is contained in:
1
Thorfile
1
Thorfile
@@ -17,7 +17,6 @@ class Build < Thor
|
||||
"tests/js/unit/layerTests.js",
|
||||
"tests/js/unit/shapeTests.js",
|
||||
"tests/js/unit/ddTests.js",
|
||||
"tests/js/unit/customShapeTests.js",
|
||||
"tests/js/unit/animationTests.js",
|
||||
"tests/js/unit/transitionTests.js",
|
||||
"tests/js/unit/shapes/rectTests.js",
|
||||
|
136
src/Shape.js
136
src/Shape.js
@@ -64,7 +64,6 @@ Kinetic.Shape = (function() {
|
||||
Shape.prototype = {
|
||||
_initShape: function(config) {
|
||||
this.nodeType = 'Shape';
|
||||
this.appliedShadow = false;
|
||||
|
||||
// set colorKey
|
||||
var shapes = Kinetic.Global.shapes;
|
||||
@@ -104,36 +103,35 @@ Kinetic.Shape = (function() {
|
||||
* @name stroke
|
||||
* @methodOf Kinetic.Shape.prototype
|
||||
*/
|
||||
stroke: function(context) {
|
||||
stroke: function(context, stroke, strokeWidth, shadow) {
|
||||
if(context.type === 'scene') {
|
||||
this._strokeScene(context);
|
||||
return this._strokeScene(context, stroke, strokeWidth, shadow);
|
||||
}
|
||||
else if(context.type === 'hit') {
|
||||
this._strokeHit(context);
|
||||
return this._strokeHit(context, strokeWidth);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
_strokeScene: function(context) {
|
||||
var strokeWidth = this.getStrokeWidth(), stroke = this.getStroke();
|
||||
_strokeScene: function(context, stroke, strokeWidth, shadow) {
|
||||
if(stroke || strokeWidth) {
|
||||
var appliedShadow = false;
|
||||
|
||||
context.save();
|
||||
if(this.attrs.shadow && !this.appliedShadow) {
|
||||
appliedShadow = this._applyShadow(context);
|
||||
}
|
||||
|
||||
var appliedShadow = this._applyShadow(context, shadow);
|
||||
context.lineWidth = strokeWidth || 2;
|
||||
context.strokeStyle = stroke || 'black';
|
||||
context.stroke(context);
|
||||
context.restore();
|
||||
|
||||
if(appliedShadow) {
|
||||
this.stroke(context);
|
||||
if(shadow.opacity) {
|
||||
this._strokeScene(context, stroke);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
_strokeHit: function(context) {
|
||||
var strokeWidth = this.getStrokeWidth(), stroke = this.colorKey;
|
||||
_strokeHit: function(context, strokeWidth) {
|
||||
var stroke = this.colorKey;
|
||||
if(stroke || strokeWidth) {
|
||||
context.save();
|
||||
context.lineWidth = strokeWidth || 2;
|
||||
@@ -141,6 +139,7 @@ Kinetic.Shape = (function() {
|
||||
context.stroke(context);
|
||||
context.restore();
|
||||
}
|
||||
return false;
|
||||
},
|
||||
_getFillType: function(fill) {
|
||||
var type = Kinetic.Type;
|
||||
@@ -163,27 +162,42 @@ Kinetic.Shape = (function() {
|
||||
return 'UNKNOWN';
|
||||
}
|
||||
},
|
||||
/**
|
||||
* helper method to fill and stroke shape based on fill and stroke properties,
|
||||
* 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
|
||||
* @methodOf Kinetic.Shape.prototype
|
||||
* */
|
||||
fill: function(context) {
|
||||
*/
|
||||
fill: function(context, fill, shadow) {
|
||||
if(context.type === 'scene') {
|
||||
this._fillScene(context);
|
||||
return this._fillScene(context, fill, shadow);
|
||||
}
|
||||
else if(context.type === 'hit') {
|
||||
this._fillHit(context);
|
||||
return this._fillHit(context);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
_fillScene: function(context) {
|
||||
var appliedShadow = false, fill = this.getFill(), fillType = this._getFillType(fill);
|
||||
_fillScene: function(context, fill, shadow) {
|
||||
var fillType = this._getFillType(fill);
|
||||
if(fill) {
|
||||
context.save();
|
||||
if(this.attrs.shadow && !this.appliedShadow) {
|
||||
appliedShadow = this._applyShadow(context);
|
||||
}
|
||||
|
||||
var appliedShadow = this._applyShadow(context, shadow);
|
||||
var s = fill.start;
|
||||
var e = fill.end;
|
||||
|
||||
@@ -233,36 +247,36 @@ Kinetic.Shape = (function() {
|
||||
context.fill(context);
|
||||
break;
|
||||
}
|
||||
context.restore();
|
||||
}
|
||||
|
||||
if(appliedShadow) {
|
||||
this.fill(context);
|
||||
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 and apply
|
||||
* a shadow if needed
|
||||
* helper method to draw an image
|
||||
* @name drawImage
|
||||
* @methodOf Kinetic.Shape.prototype
|
||||
*/
|
||||
drawImage: function() {
|
||||
var appliedShadow = false;
|
||||
var context = arguments[0];
|
||||
context.save();
|
||||
var a = Array.prototype.slice.call(arguments);
|
||||
|
||||
if(a.length === 6 || a.length === 10) {
|
||||
if(this.attrs.shadow && !this.appliedShadow) {
|
||||
appliedShadow = this._applyShadow(context);
|
||||
}
|
||||
|
||||
if(a.length === 6) {
|
||||
context.drawImage(a[1], a[2], a[3], a[4], a[5]);
|
||||
}
|
||||
@@ -272,10 +286,6 @@ Kinetic.Shape = (function() {
|
||||
}
|
||||
|
||||
context.restore();
|
||||
|
||||
if(appliedShadow) {
|
||||
this.drawImage.apply(this, a);
|
||||
}
|
||||
},
|
||||
applyOpacity: function(context) {
|
||||
var absOpacity = this.getAbsoluteOpacity();
|
||||
@@ -288,9 +298,10 @@ Kinetic.Shape = (function() {
|
||||
* based on the applyLineJoin property
|
||||
* @name lineJoin
|
||||
* @methodOf Kinetic.Shape.prototype
|
||||
* @param {CanvasContext} context
|
||||
* @param {String} lineJoin
|
||||
*/
|
||||
applyLineJoin: function(context) {
|
||||
var lineJoin = this.attrs.lineJoin;
|
||||
applyLineJoin: function(context, lineJoin) {
|
||||
if(lineJoin) {
|
||||
context.lineJoin = lineJoin;
|
||||
}
|
||||
@@ -300,9 +311,10 @@ Kinetic.Shape = (function() {
|
||||
* based on the lineCap property
|
||||
* @name applyLineCap
|
||||
* @methodOf Kinetic.Shape.prototype
|
||||
* @param {CanvasContext} context
|
||||
* @param {String} lineCap
|
||||
*/
|
||||
applyLineCap: function(context) {
|
||||
var lineCap = this.attrs.lineCap;
|
||||
applyLineCap: function(context, lineCap) {
|
||||
if(lineCap) {
|
||||
context.lineCap = lineCap;
|
||||
}
|
||||
@@ -379,30 +391,24 @@ Kinetic.Shape = (function() {
|
||||
_get: function(selector) {
|
||||
return this.nodeType === selector || this.shapeType === selector ? [this] : [];
|
||||
},
|
||||
/**
|
||||
* apply shadow. return true if shadow was applied
|
||||
* and false if it was not
|
||||
*/
|
||||
_applyShadow: function(context) {
|
||||
var s = this.attrs.shadow;
|
||||
if(s) {
|
||||
_applyShadow: function(context, shadow) {
|
||||
if(shadow) {
|
||||
var aa = this.getAbsoluteOpacity();
|
||||
// defaults
|
||||
var color = s.color ? s.color : 'black';
|
||||
var blur = s.blur ? s.blur : 5;
|
||||
var offset = s.offset ? s.offset : {
|
||||
var color = shadow.color || 'black';
|
||||
var blur = shadow.blur || 5;
|
||||
var offset = shadow.offset || {
|
||||
x: 0,
|
||||
y: 0
|
||||
};
|
||||
|
||||
if(s.opacity) {
|
||||
context.globalAlpha = s.opacity * aa;
|
||||
if(shadow.opacity) {
|
||||
context.globalAlpha = shadow.opacity * aa;
|
||||
}
|
||||
context.shadowColor = color;
|
||||
context.shadowBlur = blur;
|
||||
context.shadowOffsetX = offset.x;
|
||||
context.shadowOffsetY = offset.y;
|
||||
this.appliedShadow = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -447,11 +453,6 @@ Kinetic.Shape = (function() {
|
||||
context.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
|
||||
}
|
||||
|
||||
this.applyOpacity(context);
|
||||
this.applyLineJoin(context);
|
||||
this.applyLineCap(context);
|
||||
this.appliedShadow = false;
|
||||
|
||||
drawFunc.call(this, context);
|
||||
context.restore();
|
||||
}
|
||||
@@ -474,12 +475,7 @@ Kinetic.Shape = (function() {
|
||||
var node = family[n], t = node.getTransform(), m = t.getMatrix();
|
||||
context.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
|
||||
}
|
||||
|
||||
this.applyOpacity(context);
|
||||
this.applyLineJoin(context);
|
||||
this.applyLineCap(context);
|
||||
this.appliedShadow = false;
|
||||
|
||||
|
||||
drawFunc.call(this, context);
|
||||
context.restore();
|
||||
}
|
||||
@@ -503,10 +499,6 @@ Kinetic.Shape = (function() {
|
||||
context.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
|
||||
}
|
||||
|
||||
// don't draw shadows on hit context
|
||||
this.applyLineJoin(context);
|
||||
this.applyLineCap(context);
|
||||
|
||||
drawFunc.call(this, context);
|
||||
context.restore();
|
||||
}
|
||||
@@ -523,7 +515,7 @@ Kinetic.Shape = (function() {
|
||||
Kinetic.Global.extend(Shape, Kinetic.Node);
|
||||
|
||||
// add getters and setters
|
||||
Kinetic.Node.addGettersSetters(Shape, ['stroke', 'lineJoin', 'strokeWidth', 'drawFunc', 'drawHitFunc', 'cornerRadius']);
|
||||
Kinetic.Node.addGettersSetters(Shape, ['stroke', 'lineJoin', 'lineCap', 'strokeWidth', 'drawFunc', 'drawHitFunc', 'cornerRadius']);
|
||||
Kinetic.Node.addGetters(Shape, ['shadow', 'fill']);
|
||||
|
||||
/**
|
||||
|
@@ -27,8 +27,7 @@ Kinetic.Circle.prototype = {
|
||||
context.beginPath();
|
||||
context.arc(0, 0, this.getRadius(), 0, Math.PI * 2, true);
|
||||
context.closePath();
|
||||
this.fill(context);
|
||||
this.stroke(context);
|
||||
this.render(context);
|
||||
},
|
||||
getWidth: function() {
|
||||
return this.getRadius() * 2;
|
||||
|
@@ -36,8 +36,7 @@ Kinetic.Ellipse.prototype = {
|
||||
context.arc(0, 0, r.x, 0, Math.PI * 2, true);
|
||||
context.restore();
|
||||
context.closePath();
|
||||
this.fill(context);
|
||||
this.stroke(context);
|
||||
this.render(context);
|
||||
},
|
||||
/**
|
||||
* set radius
|
||||
|
@@ -36,8 +36,7 @@ Kinetic.Image.prototype = {
|
||||
context.beginPath();
|
||||
context.rect(0, 0, width, height);
|
||||
context.closePath();
|
||||
this.fill(context);
|
||||
this.stroke(context);
|
||||
this.render(context);
|
||||
|
||||
if(this.attrs.image) {
|
||||
// if cropping
|
||||
@@ -55,19 +54,16 @@ Kinetic.Image.prototype = {
|
||||
}
|
||||
},
|
||||
drawHitFunc: function(context) {
|
||||
var width = this.getWidth(), height = this.getHeight(), imageBuffer = this.imageBuffer;
|
||||
var width = this.getWidth(), height = this.getHeight(), imageBuffer = this.imageBuffer, appliedShadow = false;
|
||||
|
||||
context.beginPath();
|
||||
context.rect(0, 0, width, height);
|
||||
context.closePath();
|
||||
this.render(context);
|
||||
|
||||
if(imageBuffer) {
|
||||
this.drawImage(context, this.imageBuffer, 0, 0, width, height);
|
||||
}
|
||||
else {
|
||||
this.fill(context);
|
||||
}
|
||||
this.stroke(context);
|
||||
},
|
||||
/**
|
||||
* apply filter
|
||||
|
@@ -47,7 +47,7 @@ Kinetic.Line.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
this.stroke(context);
|
||||
this.stroke(context, this.getStroke(), this.getStrokeWidth(), this.getShadow());
|
||||
},
|
||||
/**
|
||||
* set points array
|
||||
|
@@ -68,8 +68,7 @@ Kinetic.Path.prototype = {
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.fill(context);
|
||||
this.stroke(context);
|
||||
this.render(context);
|
||||
}
|
||||
};
|
||||
Kinetic.Global.extend(Kinetic.Path, Kinetic.Shape);
|
||||
|
@@ -30,8 +30,7 @@ Kinetic.Polygon.prototype = {
|
||||
context.lineTo(this.attrs.points[n].x, this.attrs.points[n].y);
|
||||
}
|
||||
context.closePath();
|
||||
this.fill(context);
|
||||
this.stroke(context);
|
||||
this.render(context);
|
||||
},
|
||||
/**
|
||||
* set points array
|
||||
|
@@ -42,8 +42,7 @@ Kinetic.Rect.prototype = {
|
||||
}
|
||||
context.closePath();
|
||||
|
||||
this.fill(context);
|
||||
this.stroke(context);
|
||||
this.render(context);
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -34,8 +34,7 @@ Kinetic.RegularPolygon.prototype = {
|
||||
context.lineTo(x, y);
|
||||
}
|
||||
context.closePath();
|
||||
this.fill(context);
|
||||
this.stroke(context);
|
||||
this.render(context);
|
||||
}
|
||||
};
|
||||
Kinetic.Global.extend(Kinetic.RegularPolygon, Kinetic.Shape);
|
||||
|
@@ -38,8 +38,7 @@ Kinetic.Sprite.prototype = {
|
||||
context.beginPath();
|
||||
context.rect(0, 0, f.width, f.height);
|
||||
context.closePath();
|
||||
this.fill(context);
|
||||
this.stroke(context);
|
||||
this.render(context);
|
||||
|
||||
if(this.attrs.image) {
|
||||
|
||||
@@ -58,8 +57,8 @@ Kinetic.Sprite.prototype = {
|
||||
context.beginPath();
|
||||
context.rect(0, 0, f.width, f.height);
|
||||
context.closePath();
|
||||
this.fill(context);
|
||||
this.stroke(context);
|
||||
this.fill(context, this.getFill(), null);
|
||||
this.stroke(context, this.getStroke(), this.getStrokeWidth(), null);
|
||||
},
|
||||
/**
|
||||
* start sprite animation
|
||||
|
@@ -37,8 +37,7 @@ Kinetic.Star.prototype = {
|
||||
}
|
||||
context.closePath();
|
||||
|
||||
this.fill(context);
|
||||
this.stroke(context);
|
||||
this.render(context);
|
||||
}
|
||||
};
|
||||
Kinetic.Global.extend(Kinetic.Star, Kinetic.Shape);
|
||||
|
@@ -68,8 +68,7 @@ Kinetic.Text.prototype = {
|
||||
}
|
||||
context.closePath();
|
||||
|
||||
this.fill(context);
|
||||
this.stroke(context);
|
||||
this.render(context);
|
||||
/*
|
||||
* draw text
|
||||
*/
|
||||
@@ -85,14 +84,8 @@ Kinetic.Text.prototype = {
|
||||
context.translate(0, p + this.getTextHeight() / 2);
|
||||
|
||||
// draw text lines
|
||||
var appliedShadow = this.appliedShadow;
|
||||
for(var n = 0; n < textArr.length; n++) {
|
||||
var text = textArr[n];
|
||||
/*
|
||||
* need to reset appliedShadow flag so that shadows
|
||||
* are appropriately applied to each line of text
|
||||
*/
|
||||
this.appliedShadow = appliedShadow;
|
||||
|
||||
// horizontal alignment
|
||||
context.save();
|
||||
@@ -103,24 +96,50 @@ Kinetic.Text.prototype = {
|
||||
context.translate((this.getWidth() - this._getTextSize(text).width - p * 2) / 2, 0);
|
||||
}
|
||||
|
||||
this.fillText(context, text);
|
||||
this.strokeText(context, text);
|
||||
var appliedShadow = this.fillText(context, text, this.getTextFill(), this.getShadow());
|
||||
this.strokeText(context, text, this.getTextStroke(), this.getTextStrokeWidth(), appliedShadow ? null : this.getShadow());
|
||||
context.restore();
|
||||
|
||||
context.translate(0, lineHeightPx);
|
||||
}
|
||||
context.restore();
|
||||
},
|
||||
drawHitFunc: function(context) {
|
||||
// draw rect
|
||||
context.beginPath();
|
||||
var boxWidth = this.getWidth();
|
||||
var boxHeight = this.getHeight();
|
||||
|
||||
if(this.attrs.cornerRadius === 0) {
|
||||
// simple rect - don't bother doing all that complicated maths stuff.
|
||||
context.rect(0, 0, boxWidth, boxHeight);
|
||||
}
|
||||
else {
|
||||
// arcTo would be nicer, but browser support is patchy (Opera)
|
||||
context.moveTo(this.attrs.cornerRadius, 0);
|
||||
context.lineTo(boxWidth - this.attrs.cornerRadius, 0);
|
||||
context.arc(boxWidth - this.attrs.cornerRadius, this.attrs.cornerRadius, this.attrs.cornerRadius, Math.PI * 3 / 2, 0, false);
|
||||
context.lineTo(boxWidth, boxHeight - this.attrs.cornerRadius);
|
||||
context.arc(boxWidth - this.attrs.cornerRadius, boxHeight - this.attrs.cornerRadius, this.attrs.cornerRadius, 0, Math.PI / 2, false);
|
||||
context.lineTo(this.attrs.cornerRadius, boxHeight);
|
||||
context.arc(this.attrs.cornerRadius, boxHeight - this.attrs.cornerRadius, this.attrs.cornerRadius, Math.PI / 2, Math.PI, false);
|
||||
context.lineTo(0, this.attrs.cornerRadius);
|
||||
context.arc(this.attrs.cornerRadius, this.attrs.cornerRadius, this.attrs.cornerRadius, Math.PI, Math.PI * 3 / 2, false);
|
||||
}
|
||||
context.closePath();
|
||||
|
||||
this.render(context);
|
||||
},
|
||||
/**
|
||||
* set text
|
||||
* @name setText
|
||||
* @methodOf Kinetic.Text.prototype
|
||||
* @param {String} text
|
||||
*/
|
||||
setText: function(text) {
|
||||
var str = Kinetic.Type._isString(text) ? text : text.toString();
|
||||
this.setAttr('text', str);
|
||||
},
|
||||
* set text
|
||||
* @name setText
|
||||
* @methodOf Kinetic.Text.prototype
|
||||
* @param {String} text
|
||||
*/
|
||||
setText: function(text) {
|
||||
var str = Kinetic.Type._isString(text) ? text : text.toString();
|
||||
this.setAttr('text', str);
|
||||
},
|
||||
/**
|
||||
* get width
|
||||
* @name getWidth
|
||||
@@ -172,36 +191,38 @@ Kinetic.Text.prototype = {
|
||||
* @name fillText
|
||||
* @methodOf Kinetic.Text.prototype
|
||||
*/
|
||||
fillText: function(context, text) {
|
||||
fillText: function(context, text, textFill, shadow) {
|
||||
if(context.type === 'scene') {
|
||||
this._fillTextScene(context, text);
|
||||
return this._fillTextScene(context, text, textFill, shadow);
|
||||
}
|
||||
else if(context.type === 'buffer') {
|
||||
this._fillTextBuffer(context, text);
|
||||
else if(context.type === 'hit') {
|
||||
return this._fillTextHit(context, text);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
_fillTextScene: function(context, text) {
|
||||
var appliedShadow = false;
|
||||
if(this.attrs.textFill) {
|
||||
_fillTextScene: function(context, text, textFill, shadow) {
|
||||
if(textFill) {
|
||||
context.save();
|
||||
if(this.attrs.shadow && !this.appliedShadow) {
|
||||
appliedShadow = this._applyShadow(context);
|
||||
var appliedShadow = this._applyShadow(context, shadow);
|
||||
context.fillStyle = textFill;
|
||||
context.fillText(text, 0, 0);
|
||||
context.restore();
|
||||
|
||||
if(appliedShadow) {
|
||||
if(shadow.opacity) {
|
||||
this._fillTextScene(context, text, textFill);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
context.fillStyle = this.attrs.textFill;
|
||||
context.fillText(text, 0, 0);
|
||||
context.restore();
|
||||
}
|
||||
if(appliedShadow) {
|
||||
this.fillText(context, text, 0, 0);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
_fillTextBuffer: function(context, text) {
|
||||
if(this.attrs.textFill) {
|
||||
context.save();
|
||||
context.fillStyle = this.colorKey;
|
||||
context.fillText(text, 0, 0);
|
||||
context.restore();
|
||||
}
|
||||
_fillTextHit: function(context, text) {
|
||||
context.save();
|
||||
context.fillStyle = this.colorKey;
|
||||
context.fillText(text, 0, 0);
|
||||
context.restore();
|
||||
return false;
|
||||
},
|
||||
/**
|
||||
* helper method to stroke text
|
||||
@@ -210,46 +231,46 @@ Kinetic.Text.prototype = {
|
||||
* @methodOf Kinetic.Shape.prototype
|
||||
* @param {String} text
|
||||
*/
|
||||
strokeText: function(context, text) {
|
||||
strokeText: function(context, text, textStroke, textStrokeWidth, shadow) {
|
||||
if(context.type === 'scene') {
|
||||
this._strokeTextScene(context, text);
|
||||
this._strokeTextScene(context, text, textStroke, textStrokeWidth, shadow);
|
||||
}
|
||||
else if(context.type === 'buffer') {
|
||||
this._strokeTextBuffer(context, text);
|
||||
else if(context.type === 'hit') {
|
||||
this._strokeTextHit(context, text, textStrokeWidth);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
_strokeTextScene: function(context, text) {
|
||||
var appliedShadow = false;
|
||||
|
||||
if(this.attrs.textStroke || this.attrs.textStrokeWidth) {
|
||||
_strokeTextScene: function(context, text, textStroke, textStrokeWidth, shadow) {
|
||||
if(textStroke || textStrokeWidth) {
|
||||
context.save();
|
||||
if(this.attrs.shadow && !this.appliedShadow) {
|
||||
appliedShadow = this._applyShadow(context);
|
||||
var appliedShadow = this._applyShadow(context, shadow);
|
||||
// defaults
|
||||
textStroke = textStroke || 'black';
|
||||
textStrokeWidth = textStrokeWidth || 2;
|
||||
context.lineWidth = textStrokeWidth;
|
||||
context.strokeStyle = textStroke;
|
||||
context.strokeText(text, 0, 0);
|
||||
context.restore();
|
||||
|
||||
if(appliedShadow) {
|
||||
if(shadow.opacity) {
|
||||
this._strokeTextScene(context, text, textStroke, textStrokeWidth);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// defaults
|
||||
var textStroke = this.attrs.textStroke ? this.attrs.textStroke : 'black';
|
||||
var textStrokeWidth = this.attrs.textStrokeWidth ? this.attrs.textStrokeWidth : 2;
|
||||
context.lineWidth = textStrokeWidth;
|
||||
context.strokeStyle = textStroke;
|
||||
context.strokeText(text, 0, 0);
|
||||
context.restore();
|
||||
}
|
||||
|
||||
if(appliedShadow) {
|
||||
this.strokeText(context, text, 0, 0);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
_strokeTextBuffer: function(context, text) {
|
||||
if(this.attrs.textStroke || this.attrs.textStrokeWidth) {
|
||||
context.save();
|
||||
// defaults
|
||||
var textStroke = this.colorKey ? this.colorKey : 'black';
|
||||
var textStrokeWidth = this.attrs.textStrokeWidth ? this.attrs.textStrokeWidth : 2;
|
||||
context.lineWidth = textStrokeWidth;
|
||||
context.strokeStyle = textStroke;
|
||||
context.strokeText(text, 0, 0);
|
||||
context.restore();
|
||||
}
|
||||
_strokeTextHit: function(context, text, textStrokeWidth) {
|
||||
context.save();
|
||||
// defaults
|
||||
var textStroke = this.colorKey ? this.colorKey : 'black';
|
||||
var textStrokeWidth = textStrokeWidth || 2;
|
||||
context.lineWidth = textStrokeWidth;
|
||||
context.strokeStyle = textStroke;
|
||||
context.strokeText(text, 0, 0);
|
||||
context.restore();
|
||||
return false;
|
||||
},
|
||||
/**
|
||||
* set text data. wrap logic and width and height setting occurs
|
||||
|
@@ -68,11 +68,9 @@ Kinetic.TextPath.prototype = {
|
||||
var ht = parseFloat(this.attrs.fontSize);
|
||||
|
||||
context.translate(p0.x, p0.y);
|
||||
|
||||
context.rotate(glyphInfo[i].rotation);
|
||||
|
||||
this.fillText(context, glyphInfo[i].text);
|
||||
this.strokeText(context, glyphInfo[i].text);
|
||||
this.render(context);
|
||||
|
||||
context.restore();
|
||||
|
||||
@@ -310,10 +308,10 @@ Kinetic.Node.addGetters(Kinetic.TextPath, ['text']);
|
||||
// reference Text methods
|
||||
Kinetic.TextPath.prototype.fillText = Kinetic.Text.prototype.fillText;
|
||||
Kinetic.TextPath.prototype._fillTextScene = Kinetic.Text.prototype._fillTextScene;
|
||||
Kinetic.TextPath.prototype._fillTextBuffer = Kinetic.Text.prototype._fillTextBuffer;
|
||||
Kinetic.TextPath.prototype._fillTextHit = Kinetic.Text.prototype._fillTextHit;
|
||||
Kinetic.TextPath.prototype.strokeText = Kinetic.Text.prototype.strokeText;
|
||||
Kinetic.TextPath.prototype._strokeTextScene = Kinetic.Text.prototype._strokeTextScene;
|
||||
Kinetic.TextPath.prototype._strokeTextBuffer = Kinetic.Text.prototype._strokeTextBuffer;
|
||||
Kinetic.TextPath.prototype._strokeTextHit = Kinetic.Text.prototype._strokeTextHit;
|
||||
/**
|
||||
* set font family
|
||||
* @name setFontFamily
|
||||
|
1
tests/dataUrls/cloneGroup.js
Normal file
1
tests/dataUrls/cloneGroup.js
Normal file
File diff suppressed because one or more lines are too long
1
tests/dataUrls/customShapeTwoFills.js
Normal file
1
tests/dataUrls/customShapeTwoFills.js
Normal file
File diff suppressed because one or more lines are too long
@@ -10,6 +10,8 @@
|
||||
|
||||
<!-- data urls -->
|
||||
<script src="../dataUrls/groupToImage.js"></script>
|
||||
<script src="../dataUrls/customShapeTwoFills.js"></script>
|
||||
<script src="../dataUrls/cloneGroup.js"></script>
|
||||
|
||||
|
||||
<script src="../js/Test.js"></script>
|
||||
|
@@ -1,91 +0,0 @@
|
||||
Test.Modules['CUSTOM SHAPE'] = {
|
||||
'custom shape with fill, stroke, and strokeWidth': function(containerId) {
|
||||
var stage = new Kinetic.Stage({
|
||||
container: containerId,
|
||||
width: 578,
|
||||
height: 200
|
||||
});
|
||||
var layer = new Kinetic.Layer();
|
||||
var shape = new Kinetic.Shape({
|
||||
drawFunc: function(context) {
|
||||
context.beginPath();
|
||||
context.moveTo(0, 0);
|
||||
context.lineTo(100, 0);
|
||||
context.lineTo(100, 100);
|
||||
context.closePath();
|
||||
this.fill(context);
|
||||
this.stroke(context);
|
||||
},
|
||||
x: 200,
|
||||
y: 100,
|
||||
fill: 'green',
|
||||
stroke: 'blue',
|
||||
strokeWidth: 5
|
||||
});
|
||||
|
||||
layer.add(shape);
|
||||
stage.add(layer);
|
||||
},
|
||||
'change custom shape draw func': function(containerId) {
|
||||
var stage = new Kinetic.Stage({
|
||||
container: containerId,
|
||||
width: 578,
|
||||
height: 200
|
||||
});
|
||||
var layer = new Kinetic.Layer();
|
||||
var shape = new Kinetic.Shape({
|
||||
drawFunc: function(context) {
|
||||
context.beginPath();
|
||||
context.moveTo(0, 0);
|
||||
context.lineTo(100, 0);
|
||||
context.lineTo(100, 100);
|
||||
context.closePath();
|
||||
this.fill(context);
|
||||
this.stroke(context);
|
||||
},
|
||||
x: 200,
|
||||
y: 100,
|
||||
fill: 'green',
|
||||
stroke: 'blue',
|
||||
strokeWidth: 5
|
||||
});
|
||||
|
||||
shape.setDrawFunc(function(context) {
|
||||
context.beginPath();
|
||||
context.moveTo(0, 0);
|
||||
context.lineTo(200, 0);
|
||||
context.lineTo(200, 100);
|
||||
context.closePath();
|
||||
this.fill(context);
|
||||
this.stroke(context);
|
||||
});
|
||||
var rect = new Kinetic.Rect({
|
||||
x: 10,
|
||||
y: 10,
|
||||
width: 100,
|
||||
height: 50,
|
||||
fill: 'green',
|
||||
stroke: 'black',
|
||||
strokeWidth: 4,
|
||||
draggable: true
|
||||
});
|
||||
|
||||
rect.setDrawFunc(function(context) {
|
||||
context.beginPath();
|
||||
context.moveTo(0, 0);
|
||||
context.lineTo(200, 0);
|
||||
context.lineTo(200, 100);
|
||||
context.closePath();
|
||||
this.fill(context);
|
||||
this.stroke(context);
|
||||
});
|
||||
|
||||
layer.add(shape);
|
||||
layer.add(rect);
|
||||
stage.add(layer);
|
||||
|
||||
var dataUrl = layer.toDataURL();
|
||||
|
||||
test(dataUrls['SHAPE - change custom shape draw func'] === dataUrl, 'problem with setDrawFunc');
|
||||
}
|
||||
};
|
@@ -388,6 +388,8 @@ Test.Modules.NODE = {
|
||||
|
||||
stage.draw();
|
||||
|
||||
warn(layer.toDataURL() === cloneGroup, 'problem cloning group');
|
||||
|
||||
|
||||
},
|
||||
'test on attr change': function(containerId) {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
Test.Modules.SHAPE = {
|
||||
'SHAPE - test intersects()': function(containerId) {
|
||||
'test intersects()': function(containerId) {
|
||||
var stage = new Kinetic.Stage({
|
||||
container: containerId,
|
||||
width: 578,
|
||||
@@ -44,5 +44,146 @@ Test.Modules.SHAPE = {
|
||||
y: 153
|
||||
}) === false, '(303, 153) should not intersect the shape');
|
||||
|
||||
},
|
||||
'custom shape with two fills and two strokes': function(containerId) {
|
||||
var stage = new Kinetic.Stage({
|
||||
container: containerId,
|
||||
width: 578,
|
||||
height: 200
|
||||
});
|
||||
var layer = new Kinetic.Layer();
|
||||
|
||||
var drawTriangle = function(context) {
|
||||
context.beginPath();
|
||||
context.moveTo(200, 50);
|
||||
context.lineTo(420, 80);
|
||||
context.quadraticCurveTo(300, 100, 260, 170);
|
||||
context.closePath();
|
||||
this.fill(context, 'red');
|
||||
this.stroke(context, 'black', this.getStrokeWidth(), {
|
||||
color: 'black',
|
||||
offset: {
|
||||
x: 20,
|
||||
y: 20
|
||||
},
|
||||
opacity: 0.5
|
||||
});
|
||||
|
||||
context.beginPath();
|
||||
context.moveTo(300, 150);
|
||||
context.lineTo(520, 180);
|
||||
context.quadraticCurveTo(400, 200, 360, 270);
|
||||
context.closePath();
|
||||
|
||||
this.fill(context, 'green', {
|
||||
color: 'black',
|
||||
offset: {
|
||||
x: 20,
|
||||
y: 20
|
||||
},
|
||||
opacity: 0.5
|
||||
});
|
||||
|
||||
this.stroke(context, 'yellow', this.getStrokeWidth());
|
||||
};
|
||||
var triangle = new Kinetic.Shape({
|
||||
drawFunc: drawTriangle,
|
||||
fill: "#00D2FF",
|
||||
stroke: "black",
|
||||
strokeWidth: 4,
|
||||
id: 'myTriangle',
|
||||
draggable: true
|
||||
});
|
||||
|
||||
stage.add(layer.add(triangle));
|
||||
|
||||
warn(layer.toDataURL() === customShapeTwoFills, 'problem with custom shape with two fills');
|
||||
|
||||
},
|
||||
'custom shape with fill, stroke, and strokeWidth': function(containerId) {
|
||||
var stage = new Kinetic.Stage({
|
||||
container: containerId,
|
||||
width: 578,
|
||||
height: 200
|
||||
});
|
||||
var layer = new Kinetic.Layer();
|
||||
var shape = new Kinetic.Shape({
|
||||
drawFunc: function(context) {
|
||||
context.beginPath();
|
||||
context.moveTo(0, 0);
|
||||
context.lineTo(100, 0);
|
||||
context.lineTo(100, 100);
|
||||
context.closePath();
|
||||
this.fill(context);
|
||||
this.stroke(context);
|
||||
},
|
||||
x: 200,
|
||||
y: 100,
|
||||
fill: 'green',
|
||||
stroke: 'blue',
|
||||
strokeWidth: 5
|
||||
});
|
||||
|
||||
layer.add(shape);
|
||||
stage.add(layer);
|
||||
},
|
||||
'change custom shape draw func': function(containerId) {
|
||||
var stage = new Kinetic.Stage({
|
||||
container: containerId,
|
||||
width: 578,
|
||||
height: 200
|
||||
});
|
||||
var layer = new Kinetic.Layer();
|
||||
var shape = new Kinetic.Shape({
|
||||
drawFunc: function(context) {
|
||||
context.beginPath();
|
||||
context.moveTo(0, 0);
|
||||
context.lineTo(100, 0);
|
||||
context.lineTo(100, 100);
|
||||
context.closePath();
|
||||
this.render(context);
|
||||
},
|
||||
x: 200,
|
||||
y: 100,
|
||||
fill: 'green',
|
||||
stroke: 'blue',
|
||||
strokeWidth: 5
|
||||
});
|
||||
|
||||
shape.setDrawFunc(function(context) {
|
||||
context.beginPath();
|
||||
context.moveTo(0, 0);
|
||||
context.lineTo(200, 0);
|
||||
context.lineTo(200, 100);
|
||||
context.closePath();
|
||||
this.render(context);
|
||||
});
|
||||
var rect = new Kinetic.Rect({
|
||||
x: 10,
|
||||
y: 10,
|
||||
width: 100,
|
||||
height: 50,
|
||||
fill: 'green',
|
||||
stroke: 'black',
|
||||
strokeWidth: 4,
|
||||
draggable: true
|
||||
});
|
||||
|
||||
rect.setDrawFunc(function(context) {
|
||||
context.beginPath();
|
||||
context.moveTo(0, 0);
|
||||
context.lineTo(200, 0);
|
||||
context.lineTo(200, 100);
|
||||
context.closePath();
|
||||
this.render(context);
|
||||
});
|
||||
|
||||
layer.add(shape);
|
||||
layer.add(rect);
|
||||
stage.add(layer);
|
||||
|
||||
var dataUrl = layer.toDataURL();
|
||||
|
||||
test(dataUrls['SHAPE - change custom shape draw func'] === dataUrl, 'problem with setDrawFunc');
|
||||
}
|
||||
};
|
||||
|
Reference in New Issue
Block a user