Skip to content

Instantly share code, notes, and snippets.

@richtaur
Created April 2, 2012 07:00
Show Gist options
  • Save richtaur/2281329 to your computer and use it in GitHub Desktop.
Save richtaur/2281329 to your computer and use it in GitHub Desktop.
// 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