Created
September 25, 2014 05:55
-
-
Save mflux/1de266f9596122e3d2c9 to your computer and use it in GitHub Desktop.
TWO.js text hack
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Goes after | |
Polygon.MakeObservable(Polygon.prototype); | |
//... | |
*/ | |
var Text = Two.Text = function( text ) { | |
Two.Shape.call(this); | |
this._renderer.type = 'text'; | |
this._text = text; | |
this._fontFamily = 'Arial'; | |
this._fontSize = 12; | |
// Style properties | |
this.fill = '#fff'; | |
this.stroke = '#000'; | |
this.opacity = 1.0; | |
this.visible = true; | |
}; | |
_.extend(Text, { | |
Properties: [ | |
'fill', | |
'stroke', | |
'opacity', | |
'visible', | |
'text', | |
'fontFamily', | |
'fontSize', | |
], | |
MakeObservable: function(object) { | |
Two.Shape.MakeObservable(object); | |
// Only the first 4 properties are flagged like this. The subsequent | |
// properties behave differently and need to be hand written. | |
_.each(Text.Properties.slice(0, 4), function(property) { | |
var secret = '_' + property; | |
var flag = '_flag' + property.charAt(0).toUpperCase() + property.slice(1); | |
Object.defineProperty(object, property, { | |
get: function() { | |
return this[secret]; | |
}, | |
set: function(v) { | |
this[secret] = v; | |
this[flag] = true; | |
} | |
}); | |
}); | |
Object.defineProperty(object, 'text', { | |
get: function() { | |
if (this._flagText) { | |
this._updateText(); | |
} | |
return this._length; | |
} | |
}); | |
Object.defineProperty(object, 'fontFamily', { | |
get: function() { | |
if (this._flagFontFamily) { | |
this._updateText(); | |
} | |
return this._length; | |
} | |
}); | |
Object.defineProperty(object, 'fontSize', { | |
get: function() { | |
if (this._flagFontSize) { | |
this._updateText(); | |
} | |
return this._length; | |
} | |
}); | |
} | |
}); | |
_.extend(Text.prototype, Two.Shape.prototype, { | |
// Flags | |
// http://en.wikipedia.org/wiki/Flag | |
_flagText: true, | |
_flagFontFamily: true, | |
_flagFontSize: true, | |
_flagFill: true, | |
_flagStroke: true, | |
_flagOpacity: true, | |
_flagVisible: true, | |
_fill: '#fff', | |
_stroke: '#000', | |
_opacity: 1.0, | |
_visible: true, | |
clone: function(parent) { | |
parent = parent || this.parent; | |
clone.translation.copy(this.translation); | |
clone.rotation = this.rotation; | |
clone.scale = this.scale; | |
parent.add(clone); | |
return clone; | |
}, | |
toObject: function() { | |
var result = { | |
vertices: _.map(this.vertices, function(v) { | |
return v.toObject(); | |
}) | |
}; | |
_.each(Two.Shape.Properties, function(k) { | |
result[k] = this[k]; | |
}, this); | |
result.translation = this.translation.toObject; | |
result.rotation = this.rotation; | |
result.scale = this.scale; | |
return result; | |
}, | |
noFill: function() { | |
this.fill = 'transparent'; | |
return this; | |
}, | |
noStroke: function() { | |
this.stroke = 'transparent'; | |
return this; | |
}, | |
/** | |
* Orient the vertices of the shape to the upper lefthand | |
* corner of the Text. | |
*/ | |
corner: function() { | |
return this; | |
}, | |
/** | |
* Orient the vertices of the shape to the center of the | |
* Text. | |
*/ | |
center: function() { | |
return this; | |
}, | |
/** | |
* Remove self from the scene / parent. | |
*/ | |
remove: function() { | |
if (!this.parent) { | |
return this; | |
} | |
this.parent.remove(this); | |
return this; | |
}, | |
/** | |
* Return an object with top, left, right, bottom, width, and height | |
* parameters of the group. | |
*/ | |
getBoundingClientRect: function(shallow) { | |
// TODO: Update this to not __always__ update. Just when it needs to. | |
this._update(true); | |
return { | |
top: 0, | |
left: 0, | |
right: 0, | |
bottom: 0, | |
width: 0, | |
height: 0 | |
}; | |
}, | |
_updateText: function(limit) { | |
//TODO: DRYness (function above) | |
this._update(); | |
return this; | |
}, | |
_update: function() { | |
Two.Shape.prototype._update.call(this); | |
return this; | |
}, | |
flagReset: function() { | |
this._flagText = this._flagFontFamily = this._flagFontSize = | |
this._flagFill = this._flagStroke = | |
this._flagOpacity = this._flagVisible = false; | |
Two.Shape.prototype.flagReset.call(this); | |
return this; | |
} | |
}); | |
Text.MakeObservable(Text.prototype); | |
/* | |
goes within | |
read: { | |
ellipse ... | |
... | |
text: function( node ){ | |
// etc | |
} | |
*/ | |
text: function( node ){ | |
var fontFamily = node.getAttribute( 'font-family' ); | |
var fontSize = node.getAttribute( 'font-size' ); | |
var text = node.textContent; | |
var text = new Two.Text( text, fontFamily, fontSize ); | |
return Two.Utils.applySvgAttributes(node, text); | |
}, | |
/* | |
goes under | |
var canvas = { | |
group: { ... | |
}, | |
// put here | |
text: ... | |
*/ | |
text: { | |
render: function(ctx, forced, parentClipped) { | |
var matrix, stroke, fill, opacity, visible, text, fontFamily, fontSize, | |
closed, commands, length, last, next, prev, a, c, d, ux, uy, vx, vy, | |
ar, bl, br, cl, x, y, mask, clip; | |
// TODO: Add a check here to only invoke _update if need be. | |
this._update(); | |
matrix = this._matrix.elements; | |
stroke = this._stroke; | |
fill = this._fill; | |
opacity = this._opacity * this.parent._renderer.opacity; | |
visible = this._visible; | |
text = this._text; | |
fontFamily = this._fontFamily; | |
fontSize = this._fontSize; | |
// Transform | |
ctx.save(); | |
if (matrix) { | |
ctx.transform( | |
matrix[0], matrix[3], matrix[1], matrix[4], matrix[2], matrix[5]); | |
} | |
// Styles | |
if (fill) { | |
ctx.fillStyle = fill; | |
} | |
if (stroke) { | |
ctx.strokeStyle = stroke; | |
} | |
if (_.isNumber(opacity)) { | |
ctx.globalAlpha = opacity; | |
} | |
ctx.font = fontSize +'px ' + fontFamily; | |
ctx.fillText( text, 0, 0 ); | |
ctx.restore(); | |
return this.flagReset(); | |
} | |
}, |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment