diff --git a/index.html b/index.html index b0a31ae..9ebecab 100644 --- a/index.html +++ b/index.html @@ -54,7 +54,7 @@
NOTE: if a single word is too long to fit the width with specified font size, it will break on any letter @@ -120,14 +121,16 @@ lineBreak: "auto", sizeToFill: false, allowNewLine: true, - justifyLines: false + justifyLines: false, + strokeText: false }
- Use context settings such as "fillStyle", "lineWidth" or "strokeStyle" before using CanvasTextWrapper like so: + Configure context settings properties such as "fillStyle", "lineWidth" or "strokeStyle" before using + CanvasTextWrapper like so:
diff --git a/js/CanvasTextWrapper.js b/js/CanvasTextWrapper.js
index fe07340..90f0db8 100644
--- a/js/CanvasTextWrapper.js
+++ b/js/CanvasTextWrapper.js
@@ -4,280 +4,4 @@
* MIT License (http://www.opensource.org/licenses/mit-license.html)
* Copyright (c) 2014 Vadim Namniak
*/
-
-(function() {
- 'use strict';
-
- var EL_WIDTH,EL_HEIGHT,MAX_TXT_WIDTH,MAX_TXT_HEIGHT;
-
- var defaults = {
- font: '18px Arial, sans-serif',
- sizeToFill: false, // text is resized to fill the container (given font size is ignored)
- lineHeight: 1, // default line height equivalent of '100%'
- allowNewLine: true, // breaks text on every new line character '\n'
- lineBreak: 'auto', // text fills the element's (canvas or parent) width going to a new line on a whole word
- textAlign: 'left', // each line of text is aligned left
- verticalAlign: 'top', // text lines block is aligned top
- justifyLines: false, // lines are not justified
- paddingX: 0, // 0px left & right text padding relatively to canvas or its container
- paddingY: 0, // 0px top & bottom text padding relatively to canvas or its container
- fitParent: false, // text is set to fit canvas width
- strokeText: false // text is stroked according to context configuration
- };
-
- var CanvasTextWrapper = function(canvas,text,options) {
- if (!(this instanceof CanvasTextWrapper)) {
- return new CanvasTextWrapper(canvas,text,options);
- }
-
- this.canvas = canvas;
- this.text = text;
- this.context = this.canvas.getContext('2d');
- this.context.font = this.font;
- this.context.textBaseline = 'bottom';
-
- for (var property in defaults) {
- if (defaults.hasOwnProperty(property)) {
- this[property] = (options && options[property]) ? options[property] : defaults[property];
- }
- }
-
- EL_WIDTH = (this.fitParent === false) ? this.canvas.width : this.canvas.parentNode.clientWidth;
- EL_HEIGHT = (this.fitParent === false) ? this.canvas.height : this.canvas.parentNode.clientHeight;
- MAX_TXT_WIDTH = EL_WIDTH - (this.paddingX * 2);
- MAX_TXT_HEIGHT = EL_HEIGHT - (this.paddingY * 2);
-
- this._init();
- };
-
- CanvasTextWrapper.prototype = {
- _init: function() {
- this.fontSize = parseInt(this.font.replace(/^\D+/g,''),10) || 18;
- this.textBlockHeight = 0;
- this.lines = [];
- this.newLineIndexes = [];
- this.textPos = {x: 0,y: 0};
-
- this._setFont(this.fontSize);
- this._setLineHeight();
- this._validate();
- this._render();
- },
-
- _render: function() {
- if (this.sizeToFill) {
- var numWords = this.text.trim().split(/\s+/).length;
- var fontSize = 0;
-
- do {
- this._setFont(++fontSize);
- this.lineHeight = this.fontSize;
- this._wrap();
- } while (this.textBlockHeight < MAX_TXT_HEIGHT && (this.lines.join(' ').split(/\s+/).length == numWords));
-
- this._setFont(--fontSize);
- this.lineHeight = this.fontSize;
- } else {
- this._wrap();
- }
-
- if (this.justifyLines && this.lineBreak === 'auto') {
- this._justify();
- }
-
- this._setAlignY();
- this._drawText();
- },
-
- _setFont: function(fontSize) {
- var fontParts = (!this.sizeToFill) ? this.font.split(/\b\d+px\b/i) : this.context.font.split(/\b\d+px\b/i);
- this.context.font = fontParts[0] + fontSize + 'px' + fontParts[1];
- this.fontSize = fontSize;
- },
-
- _setLineHeight: function() {
- if (!isNaN(this.lineHeight)) {
- this.lineHeight = this.fontSize * this.lineHeight;
- } else if (this.lineHeight.toString().indexOf('px') !== -1) {
- this.lineHeight = parseInt(this.lineHeight);
- } else if (this.lineHeight.toString().indexOf('%') !== -1) {
- this.lineHeight = (parseInt(this.lineHeight) / 100) * this.fontSize;
- }
- },
-
- _wrap: function() {
- if (this.allowNewLine) {
- var newLines = this.text.trim().split('\n');
- for (var i = 0,idx = 0; i < newLines.length - 1; i++) {
- idx += newLines[i].trim().split(/\s+/).length;
- this.newLineIndexes.push(idx)
- }
- }
-
- var words = this.text.trim().split(/\s+/);
- this._checkLength(words);
- this._breakText(words);
-
- this.textBlockHeight = this.lines.length * this.lineHeight;
- },
-
- _checkLength: function(words) {
- var testString,tokenLen,sliced,leftover;
-
- for (var i = 0; i < words.length; i++) {
- testString = '';
- tokenLen = this.context.measureText(words[i]).width;
-
- if (tokenLen > MAX_TXT_WIDTH) {
- for (var k = 0; (this.context.measureText(testString + words[i][k]).width <= MAX_TXT_WIDTH) && (k < words[i].length); k++) {
- testString += words[i][k];
- }
-
- sliced = words[i].slice(0,k);
- leftover = words[i].slice(k);
- words.splice(i,1,sliced,leftover);
- }
- }
- },
-
- _breakText: function(words) {
- for (var i = 0,j = 0; i < words.length; j++) {
- this.lines[j] = '';
-
- if (this.lineBreak === 'auto') {
- while ((this.context.measureText(this.lines[j] + words[i]).width <= MAX_TXT_WIDTH) && (i < words.length)) {
-
- this.lines[j] += words[i] + ' ';
- i++;
-
- if (this.allowNewLine) {
- for (var k = 0; k < this.newLineIndexes.length; k++) {
- if (this.newLineIndexes[k] === i) {
- j++;
- this.lines[j] = '';
- break;
- }
- }
- }
- }
- this.lines[j] = this.lines[j].trim();
- } else {
- this.lines[j] = words[i];
- i++;
- }
- }
- },
-
- _justify: function() {
- var maxLen,longestLineIndex,tokenLen;
- for (var i = 0; i < this.lines.length; i++) {
- tokenLen = this.context.measureText(this.lines[i]).width;
-
- if (!maxLen || tokenLen > maxLen) {
- maxLen = tokenLen;
- longestLineIndex = i;
- }
- }
-
- // fill lines with extra spaces
- var numWords,spaceLength,numOfSpaces,num,filler;
- var delimiter = '\u200A';
- for (i = 0; i < this.lines.length; i++) {
- if (i === longestLineIndex) continue;
-
- numWords = this.lines[i].trim().split(/\s+/).length;
- if (numWords <= 1) continue;
-
- this.lines[i] = this.lines[i].trim().split(/\s+/).join(delimiter);
-
- spaceLength = this.context.measureText(delimiter).width;
- numOfSpaces = (maxLen - this.context.measureText(this.lines[i]).width) / spaceLength;
- num = numOfSpaces / (numWords - 1);
-
- filler = '';
- for (var j = 0; j < num; j++) {
- filler += delimiter;
- }
-
- this.lines[i] = this.lines[i].trim().split(delimiter).join(filler);
- //console.log('numWords:', numWords, 'numOfSpaces:', numOfSpaces, 'num:', num);
- }
- },
-
- _drawText: function() {
- for (var i = 0; i < this.lines.length; i++) {
- this._setAlignX(this.lines[i]);
-
- this.textPos.y = parseInt(this.textPos.y) + this.lineHeight;
- this.context.fillText(this.lines[i],this.textPos.x,this.textPos.y);
-
- if (this.strokeText) {
- this.context.strokeText(this.lines[i],this.textPos.x,this.textPos.y);
- }
- }
- },
-
- _setAlignX: function(line) {
- if (this.textAlign == 'center') {
- this.textPos.x = (EL_WIDTH - this.context.measureText(line).width) / 2;
- } else if (this.textAlign == 'right') {
- this.textPos.x = EL_WIDTH - this.context.measureText(line).width - this.paddingX;
- } else {
- this.textPos.x = this.paddingX;
- }
- },
-
- _setAlignY: function() {
- if (this.verticalAlign == 'middle') {
- this.textPos.y = (EL_HEIGHT - this.textBlockHeight) / 2;
- } else if (this.verticalAlign == 'bottom') {
- this.textPos.y = EL_HEIGHT - this.textBlockHeight - this.paddingY;
- } else {
- this.textPos.y = this.paddingY;
- }
- },
-
- _validate: function() {
- if (!(this.canvas instanceof HTMLCanvasElement))
- throw new TypeError('The first parameter must be an instance of HTMLCanvasElement.');
-
- if (typeof this.text !== 'string')
- throw new TypeError('The second parameter must be a string.');
-
- if (isNaN(this.fontSize))
- throw new TypeError('Cannot parse "font".');
-
- if (isNaN(this.lineHeight))
- throw new TypeError('Cannot parse "lineHeight".');
-
- if (this.textAlign.toLocaleLowerCase() !== 'left' && this.textAlign.toLocaleLowerCase() !== 'center' && this.textAlign.toLocaleLowerCase() !== 'right')
- throw new TypeError('Property "textAlign" must be set to either "left", "center", or "right".');
-
- if (this.verticalAlign.toLocaleLowerCase() !== 'top' && this.verticalAlign.toLocaleLowerCase() !== 'middle' && this.verticalAlign.toLocaleLowerCase() !== 'bottom')
- throw new TypeError('Property "verticalAlign" must be set to either "top", "middle", or "bottom".');
-
- if (typeof this.justifyLines !== 'boolean')
- throw new TypeError('Property "justifyLines" must be set to a Boolean.');
-
- if (isNaN(this.paddingX))
- throw new TypeError('Property "paddingX" must be set to a Number.');
-
- if (isNaN(this.paddingY))
- throw new TypeError('Property "paddingY" must be set to a Number.');
-
- if (typeof this.fitParent !== 'boolean')
- throw new TypeError('Property "fitParent" must be set to a Boolean.');
-
- if (this.lineBreak.toLocaleLowerCase() !== 'auto' && this.lineBreak.toLocaleLowerCase() !== 'word')
- throw new TypeError('Property "lineBreak" must be set to either "auto" or "word".');
-
- if (typeof this.sizeToFill !== 'boolean')
- throw new TypeError('Property "sizeToFill" must be set to a Boolean.');
-
- if (typeof this.strokeText !== 'boolean')
- throw new TypeError('Property "strokeText" must be set to a Boolean.');
- }
- };
-
- window.CanvasTextWrapper = CanvasTextWrapper;
-})();
\ No newline at end of file
+!function(){"use strict";var a,b,c,d,e={font:"18px Arial, sans-serif",sizeToFill:!1,lineHeight:1,allowNewLine:!0,lineBreak:"auto",textAlign:"left",verticalAlign:"top",justifyLines:!1,paddingX:0,paddingY:0,fitParent:!1,strokeText:!1},f=function(g,h,i){if(!(this instanceof f))return new f(g,h,i);this.canvas=g,this.text=h,this.context=this.canvas.getContext("2d"),this.context.font=this.font,this.context.textBaseline="bottom";for(var j in e)e.hasOwnProperty(j)&&(this[j]=i&&i[j]?i[j]:e[j]);a=this.fitParent===!1?this.canvas.width:this.canvas.parentNode.clientWidth,b=this.fitParent===!1?this.canvas.height:this.canvas.parentNode.clientHeight,c=a-2*this.paddingX,d=b-2*this.paddingY,this._init()};f.prototype={_init:function(){this.fontSize=parseInt(this.font.replace(/^\D+/g,""),10)||18,this.textBlockHeight=0,this.lines=[],this.newLineIndexes=[],this.textPos={x:0,y:0},this._setFont(this.fontSize),this._setLineHeight(),this._validate(),this._render()},_render:function(){if(this.sizeToFill){var a=this.text.trim().split(/\s+/).length,b=0;do this._setFont(++b),this.lineHeight=this.fontSize,this._wrap();while(this.textBlockHeightc){for(var h=0;this.context.measureText(b+a[g][h]).width<=c&&ha)&&(a=c,b=d);var e,f,g,h,i,j=" ";for(d=0;d=e))){this.lines[d]=this.lines[d].trim().split(/\s+/).join(j),f=this.context.measureText(j).width,g=(a-this.context.measureText(this.lines[d]).width)/f,h=g/(e-1),i="";for(var k=0;h>k;k++)i+=j;this.lines[d]=this.lines[d].trim().split(j).join(i)}},_drawText:function(){for(var a=0;a