From f8ac09d1aca0586d25c08679edb26d89789d3cf5 Mon Sep 17 00:00:00 2001 From: Vadim Date: Sat, 19 Sep 2015 18:20:03 -0400 Subject: [PATCH] testing updated version --- index.html | 9 -- js/CanvasTextWrapper.js | 292 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 291 insertions(+), 10 deletions(-) diff --git a/index.html b/index.html index a615c07..ce2eccf 100644 --- a/index.html +++ b/index.html @@ -9,14 +9,6 @@ CanvasTextWrapper - - - - - - - -
@@ -164,6 +156,5 @@ - diff --git a/js/CanvasTextWrapper.js b/js/CanvasTextWrapper.js index 973d85c..bbce110 100644 --- a/js/CanvasTextWrapper.js +++ b/js/CanvasTextWrapper.js @@ -1 +1,291 @@ -!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=this.font.match(/\d+(px|em|\%)/g)?+this.font.match(/\d+(px|em|\%)/g)[0].match(/\d+/g):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 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.'); + } + }; + + if ('module' in root && 'exports' in module) { + module.exports = CanvasTextWrapper; + } else { + root.CanvasTextWrapper = CanvasTextWrapper; + } +})(this); \ No newline at end of file