mirror of
https://github.com/wassname/CanvasTextWrapper.git
synced 2026-06-27 23:36:32 +08:00
7 lines
5.7 KiB
JavaScript
7 lines
5.7 KiB
JavaScript
/*! CanvasTextWrapper
|
||
* https://github.com/namniak/CanvasTextWrapper
|
||
* Version: 0.3.0
|
||
* MIT License (http://www.opensource.org/licenses/mit-license.html)
|
||
* Copyright (c) 2014 Vadim Namniak
|
||
*/
|
||
!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.textBlockHeight<d&&this.lines.join(" ").split(/\s+/).length==a);this._setFont(--b),this.lineHeight=this.fontSize}else this._wrap();this.justifyLines&&"auto"===this.lineBreak&&this._justify(),this._setAlignY(),this._drawText()},_setFont:function(a){var b=this.sizeToFill?this.context.font.split(/\b\d+px\b/i):this.font.split(/\b\d+px\b/i);this.context.font=b[0]+a+"px"+b[1],this.fontSize=a},_setLineHeight:function(){isNaN(this.lineHeight)?-1!==this.lineHeight.toString().indexOf("px")?this.lineHeight=parseInt(this.lineHeight):-1!==this.lineHeight.toString().indexOf("%")&&(this.lineHeight=parseInt(this.lineHeight)/100*this.fontSize):this.lineHeight=this.fontSize*this.lineHeight},_wrap:function(){if(this.allowNewLine)for(var a=this.text.trim().split("\n"),b=0,c=0;b<a.length-1;b++)c+=a[b].trim().split(/\s+/).length,this.newLineIndexes.push(c);var d=this.text.trim().split(/\s+/);this._checkLength(d),this._breakText(d),this.textBlockHeight=this.lines.length*this.lineHeight},_checkLength:function(a){for(var b,d,e,f,g=0;g<a.length;g++)if(b="",d=this.context.measureText(a[g]).width,d>c){for(var h=0;this.context.measureText(b+a[g][h]).width<=c&&h<a[g].length;h++)b+=a[g][h];e=a[g].slice(0,h),f=a[g].slice(h),a.splice(g,1,e,f)}},_breakText:function(a){for(var b=0,d=0;b<a.length;d++)if(this.lines[d]="","auto"===this.lineBreak){for(;this.context.measureText(this.lines[d]+a[b]).width<=c&&b<a.length;)if(this.lines[d]+=a[b]+" ",b++,this.allowNewLine)for(var e=0;e<this.newLineIndexes.length;e++)if(this.newLineIndexes[e]===b){d++,this.lines[d]="";break}this.lines[d]=this.lines[d].trim()}else this.lines[d]=a[b],b++},_justify:function(){for(var a,b,c,d=0;d<this.lines.length;d++)c=this.context.measureText(this.lines[d]).width,(!a||c>a)&&(a=c,b=d);var e,f,g,h,i,j=" ";for(d=0;d<this.lines.length;d++)if(d!==b&&(e=this.lines[d].trim().split(/\s+/).length,!(1>=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<this.lines.length;a++)this._setAlignX(this.lines[a]),this.textPos.y=parseInt(this.textPos.y)+this.lineHeight,this.context.fillText(this.lines[a],this.textPos.x,this.textPos.y),this.strokeText&&this.context.strokeText(this.lines[a],this.textPos.x,this.textPos.y)},_setAlignX:function(b){this.textPos.x="center"==this.textAlign?(a-this.context.measureText(b).width)/2:"right"==this.textAlign?a-this.context.measureText(b).width-this.paddingX:this.paddingX},_setAlignY:function(){this.textPos.y="middle"==this.verticalAlign?(b-this.textBlockHeight)/2:"bottom"==this.verticalAlign?b-this.textBlockHeight-this.paddingY:this.paddingY},_validate:function(){if(!(this.canvas instanceof HTMLCanvasElement))throw new TypeError("The first parameter must be an instance of HTMLCanvasElement.");if("string"!=typeof this.text)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("left"!==this.textAlign.toLocaleLowerCase()&&"center"!==this.textAlign.toLocaleLowerCase()&&"right"!==this.textAlign.toLocaleLowerCase())throw new TypeError('Property "textAlign" must be set to either "left", "center", or "right".');if("top"!==this.verticalAlign.toLocaleLowerCase()&&"middle"!==this.verticalAlign.toLocaleLowerCase()&&"bottom"!==this.verticalAlign.toLocaleLowerCase())throw new TypeError('Property "verticalAlign" must be set to either "top", "middle", or "bottom".');if("boolean"!=typeof this.justifyLines)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("boolean"!=typeof this.fitParent)throw new TypeError('Property "fitParent" must be set to a Boolean.');if("auto"!==this.lineBreak.toLocaleLowerCase()&&"word"!==this.lineBreak.toLocaleLowerCase())throw new TypeError('Property "lineBreak" must be set to either "auto" or "word".');if("boolean"!=typeof this.sizeToFill)throw new TypeError('Property "sizeToFill" must be set to a Boolean.');if("boolean"!=typeof this.strokeText)throw new TypeError('Property "strokeText" must be set to a Boolean.')}},window.CanvasTextWrapper=f}(); |