Created
April 2, 2012 07:00
-
-
Save richtaur/2281329 to your computer and use it in GitHub Desktop.
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
// TODO: support \n | |
// TODO: pagination (use height) | |
// TODO: typewriter effect? | |
var Canface = (function() { | |
var Canface = function(conf) { | |
this._drawData = []; | |
this._imageData = {}; | |
for (var key in conf) { | |
this[key] = conf[key]; | |
} | |
}; | |
// Render methods | |
Canface.FILL_TEXT = 0; | |
Canface.CANVAS_BUFFER = 1; | |
// Defaults | |
Canface.font = "16px Helvetica"; | |
Canface.fillStyle = "rgb(255, 255, 255)"; | |
Canface.renderMethod = Canface.FILL_TEXT; | |
Canface.textAlign = "left"; | |
Canface.textBaseline = "top"; | |
// Getters/setters | |
Canface.prototype.__defineSetter__("font", function(font) { | |
this._font = font; | |
this._recalculate(); | |
}); | |
Canface.prototype.__defineGetter__("lineHeight", function() { | |
if (this._lineHeight) { | |
return this._lineHeight; | |
} else { | |
// Get it from the font configuration | |
var font = this._font || Canface.font; | |
return Number(font.replace(/px(.+)/, '')); | |
} | |
}); | |
Canface.prototype.__defineSetter__("lineHeight", function(lineHeight) { | |
this._lineHeight = lineHeight; | |
}); | |
Canface.prototype.__defineSetter__("text", function(text) { | |
this._text = text; | |
this._recalculate(); | |
}); | |
Canface.prototype.__defineGetter__("width", function() { | |
return this._width | |
}); | |
Canface.prototype.__defineSetter__("width", function(width) { | |
this._width = width; | |
this._recalculate(); | |
}); | |
// Public method | |
Canface.prototype.draw = function(context) { | |
var ctx = context || this.context || Canface.context; | |
if (this._imageData && (this._get("renderMethod") == Canface.CANVAS_BUFFER)) { | |
this._drawImage(ctx); | |
} else { | |
this._fillText(ctx); | |
} | |
}; | |
// Faux-private methods | |
Canface.prototype._applyContextConf = function() { | |
var ctx = this.context || Canface.context; | |
ctx.font = this._font || Canface.font; | |
ctx.textAlign = this.textAlign || Canface.textAlign; | |
ctx.textBaseline = this.textBaseline || Canface.textBaseline; | |
}; | |
Canface.prototype._drawImage = function(ctx) { | |
ctx.drawImage(this._imageData, this.x, this.y); | |
}; | |
Canface.prototype._drawTextShadow = function(ctx) { | |
var textShadow = this.textShadow || Canface.textShadow; | |
if (!textShadow) { | |
return; | |
} | |
// TODO: support for blur, eg. h-shadow v-shadow blur color | |
// http://www.quasimondo.com/BoxBlurForCanvas/FastBlurDemo.html | |
var rules = textShadow.split(" "); | |
var x = (this.x + Number(rules[0].replace(/px/, ''))); | |
var y = (this.y + Number(rules[1].replace(/px/, ''))); | |
ctx.fillStyle = rules[2]; | |
for (var i = 0, length = this._drawData.length; i < length; ++i) { | |
var data = this._drawData[i]; | |
ctx.fillText(data.text, x + data.x, y + data.y); | |
} | |
}; | |
Canface.prototype._fillText = function(ctx) { | |
ctx.save(); | |
this._applyContextConf(); | |
this._drawTextShadow(ctx); | |
ctx.fillStyle = this.fillStyle || Canface.fillStyle; | |
for (var i = 0, length = this._drawData.length; i < length; ++i) { | |
var data = this._drawData[i]; | |
ctx.fillText(data.text, this.x + data.x, this.y + data.y); | |
} | |
ctx.restore(); | |
}; | |
Canface.prototype._get = function(key, fallback) { | |
return this[key] || Canface[key] || fallback; | |
}; | |
Canface.prototype._recalculate = function() { | |
if (this._width === undefined) { | |
return; | |
} | |
// Calculate the draw data | |
var ctx = this.context || Canface.context; | |
ctx.save(); | |
this._applyContextConf(); | |
var spaceWidth = ctx.measureText(" ").width; | |
var x = 0; | |
var y = 0; | |
var text = this._text; | |
var width = ctx.measureText(this._text).width; | |
var words = text.split(" "); | |
this._drawData = []; | |
for (var i = 0, length = words.length; i < length; ++i) { | |
var word = words[i]; | |
var width = ctx.measureText(word).width; | |
if ((x + width) > this._width) { | |
x = 0; | |
y += this.lineHeight; | |
} | |
this._drawData.push({ | |
text: word, | |
x: x, | |
y: y, | |
}); | |
x += (width + spaceWidth); | |
} | |
ctx.restore(); | |
// If necessary, regenerate the buffer | |
this._imageData = null; | |
if (this._get("renderMethod") == Canface.CANVAS_BUFFER) { | |
var buffer = document.createElement("canvas"); | |
var bufferContext = buffer.getContext("2d"); | |
buffer.width = this._width; | |
buffer.height = this.height; | |
this.draw(bufferContext); | |
this._imageData = bufferContext.getImageData(); | |
console.log('imageData:', this._imageData); | |
} | |
}; | |
return Canface; | |
}()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment