一盐碱、canvas繪制文字的方法和屬性
????1.?fillText(text, x, y [, maxWidth])
? ? ????text:繪制文本把兔;x:文本起點(diǎn)的 x 軸坐標(biāo);y:文本起點(diǎn)的 y 軸坐標(biāo)瓮顽;
? ????? maxWidth:可選县好,繪制的最大寬度。如果指定了值暖混,計(jì)算字符串的值比最大寬度還要寬缕贡,字體為了適應(yīng)會(huì)水平縮放。
? ? 2.?measureText()
????????將返回一個(gè)?TextMetrics對(duì)象的寬度拣播、所在像素晾咪,這些體現(xiàn)文本特性的屬性。
? ? 3.??font?
? ? ????符合CSS?font?語(yǔ)法的DOMString?字符串贮配。默認(rèn)字體是 10px sans-serif
????????屬性:
????????<font-size>?<font-family>?必選
????????<font-style>?<font-variant>?<font-weight>?<font-stretch>?<line-height>?可選
????? ? 形如:italic small-caps bold 16px/2 cursive;
????????line-height必須緊跟font-size谍倦,在“/”之前,比如:“16px/3”泪勒,(注:node-canvas下昼蛀,無(wú)效)
? ? 4.?textAlign
? ??????文本對(duì)齊選項(xiàng). 可選的值包括:start,?end,?left,?right?or?center. 默認(rèn)值是?start
? ? 5.?textBaseline
? ??????基線對(duì)齊選項(xiàng). 可選的值包括:top,?hanging,?middle,?alphabetic,?ideographic,?bottom宴猾。默認(rèn)值是?alphabetic
? ? 6.?direction
????????文本方向。值包括:ltr,?rtl,?inherit叼旋。默認(rèn)值是?inherit仇哆;? ??
? ? 7.?fillStyle
? ??????使用?fillStyle?屬性設(shè)置填充顏色
? ? ????fillStyle有三種屬性值:color(顏色),gradient(漸變)夫植,pattern(非透明對(duì)象)?
二讹剔、繪制有行高和寬度的單行文字
? ? 1. 首先繪制一個(gè)矩形裁切區(qū)域
? ??????ctx.rect(x,? y, width, lineHeight);
????????ctx.clip();
????2. 繪制文字
????????ctx.textBaseline ='middle';
????????ctx.fillText(text, x, y +?lineHeight / 2);
? ? 3. 讓文字水平對(duì)齊
? ? ? ? (1) 左對(duì)齊
? ? ? ? ? ? ? ?ctx.textAlign = ‘left’;
???????????????ctx.fillText(text, x, y +?lineHeight?/ 2);? ??????????????
? ? ? ? (2) 居中對(duì)齊
? ? ? ? ? ? ? ctx.textAlign = ‘center’;
? ? ? ? ? ? ? ctx.fillText(text, x + width / 2, y +?lineHeight?/ 2);? ??????????????
? ? ? ? (3) 右對(duì)齊
? ? ? ? ? ? ?ctx.textAlign = ‘right’;
? ? ? ? ? ? ?ctx.fillText(text, x + width, y +?lineHeight?/ 2);? ??????????????
三、繪制多行文本
????1. 根據(jù)文字寬度和字體大小將長(zhǎng)文字分割為多段文字
? ??????/**
? ??????* 將一段文字拆成多段
? ??????* @params ctx CanvasRenderingContext2D
? ??????* @param text 文字內(nèi)容
? ??????* @param fontSize 文字大小
? ??????* @param width 文字限定的寬度? ??
? ??????* @param maxLine 文字最多顯示多少行
? ??????* @return 多段文字
? ??????*/
? ??????const splitText = (
? ??????ctx: CanvasRenderingContext2D,? ??????
? ??????text:string,
? ??????fontSize:number,
? ??????width:number,
? ??????maxLine:number,
? ??????): Array<{text:string, width:number}> => {
? ??????const arr: Array<{text:string, width:number}> = [];
? ??????// 記錄剩余文字? ??
????? ??let remainText = text;
? ??????while (arr.length < maxLine -1 && ctx.measureText(remainText).width > width) {
? ??????// 估算一行能容納多少文字
??? ??????let assumTextNum = Math.floor(width / fontSize);
??? ??????// 計(jì)算假定文字的寬度
??? ??????let {width:assumTextWidth} = ctx.measureText(remainText.substr(0, assumTextNum));
?? ???????if (assumTextWidth > width) {
? ??????while (assumTextWidth > width) {
? ??????assumTextWidth = ctx.measureText(remainText.substr(0, --assumTextNum)).width;
??? ???????}
? ??????}else {
? ??????while (assumTextWidth <= width) {
? ??????assumTextWidth = ctx.measureText(remainText.substr(0, ++assumTextNum)).width;
??? ???????}
? ??????assumTextWidth = ctx.measureText(remainText.substr(0, --assumTextNum)).width;
??? ??????}
? ??????arr.push({
? ??????text: remainText.substr(0, assumTextNum),
? ??????? width:assumTextWidth,
??? ??????});
? ??????? remainText = remainText.substr(assumTextNum);
? ??????}
? ??????arr.push({
? ??????text: remainText,
??? ??????width: ctx.measureText(remainText).width,
? ??????});
? ??????return arr;
? ??????};
? ? 2. 將分割后的多段文字详民,按照單行文字的繪制方式一一繪制延欠,代碼如下
????????const texts =splitText(ctx, text, fontSize, width, maxLine);
????????for (let i =0; i < texts.length; i++) {
????????????const txtObj = texts[i];
? ? ? ? ? ? const offsetY = i *?lineHeight;
????????????// 繪制單行文字
????????????drawSingleLineText(ctx, txtObj.text, fontSize, x, y + offsetY, width, lineHeight);????
????????}