文字的多行處理在(zai)dom元素(su)中(zhong)(zhong)很(hen)好辦。但是canvas中(zhong)(zhong)沒有(you)提供方法,只有(you)通(tong)過截取指(zhi)定(ding)字符串來達到目(mu)的。
那么下面就介(jie)紹我(wo)自己(ji)處理(li)的辦法:
wxml:
<canvas canvas-id='word' id='test'></canvas>
canvas肯定(ding)要(yao)一(yi)個(ge)畫板容器(qi)啦,記得設置寬高哦,小程序中默認寬高是300px和150px
js:在(zai)page中

//處理文字多出省略號顯示
dealWords: function (options) {
options.ctx.setFontSize(options.fontSize);//設置字體大小
var allRow = Math.ceil(options.ctx.measureText(options.word).width / options.maxWidth);//實際總共能分多少行
var count = allRow >= options.maxLine ? options.maxLine : allRow;//實際能分多少行與設置的最大顯示行數比,誰小就用誰做循環次數
var endPos = 0;//當前字符串的截斷點
for (var j = 0; j < count; j++) {
var nowStr = options.word.slice(endPos);//當前剩余的字符串
var rowWid = 0;//每一行當前寬度
if (options.ctx.measureText(nowStr).width > options.maxWidth) {//如果當前的字符串寬度大于最大寬度,然后開始截取
for (var m = 0; m < nowStr.length; m++) {
rowWid += options.ctx.measureText(nowStr[m]).width;//當前字符串總寬度
if (rowWid > options.maxWidth) {
if (j === options.maxLine - 1) { //如果是最后一行
options.ctx.fillText(nowStr.slice(0, m - 1) + '...', options.x, options.y + (j + 1) * 18); //(j+1)*18這是每一行的高度
} else {
options.ctx.fillText(nowStr.slice(0, m), options.x, options.y + (j + 1) * 18);
}
endPos += m;//下次截斷點
break;
}
}
} else {//如果當前的字符串寬度小于最大寬度就直接輸出
options.ctx.fillText(nowStr.slice(0), options.x, options.y + (j + 1) * 18);
}
}
},
|

(1) measureText().width 這是小程序 測量文(wen)(wen)本(ben)尺(chi)寸信息的方法(fa),目(mu)前僅返回文(wen)(wen)本(ben)寬度。這里是官方說明
(2) (j + 1) * 18 中(zhong)18表(biao)示(shi)每一行行高是18,這是我自己(ji)定(ding)義的(de)行高如果(guo)這個數值小于定(ding)義的(de)字(zi)體(ti)大小,多(duo)半會(hui)出(chu)現兩行文字(zi)重疊的(de)現象,前面的(de) j+1 表(biao)示(shi)當(dang)前是多(duo)少行。整體(ti)表(biao)示(shi)當(dang)前行與上一行相比需要(yao)加多(duo)少距離
(3) 在 j===options.maxLine-1 這(zhe)(zhe)個表示最后一行的(de)處理(li)情況里(li)面(mian) 有slice(0,endPos-1),為什么這(zhe)(zhe)里(li)要(yao)減(jian)(jian)(jian)一,是因(yin)為省略號也(ye)要(yao)占寬度(du),大概是11.5的(de)樣子(zi),所(suo)以(yi)要(yao)減(jian)(jian)(jian)掉這(zhe)(zhe)個省略號的(de)寬度(du)。因(yin)為一般中文(wen)字符寬度(du)都和設置(zhi)的(de)字體大小(xiao)差不多。如果是英文(wen)就要(yao)小(xiao)一點,這(zhe)(zhe)里(li)就沒有考慮這(zhe)(zhe)么精細了。反正減(jian)(jian)(jian)一就是精確度(du)的(de)意思。。。可以(yi)自(zi)行多減(jian)(jian)(jian)或者少減(jian)(jian)(jian)
(4) endPos += m 表示下(xia)一(yi)(yi)次截(jie)(jie)斷(duan)(duan)的(de)(de)(de)時候是(shi)從哪里開始。因為每次去截(jie)(jie)字符串(chuan)都是(shi)最初的(de)(de)(de)字符串(chuan),并沒(mei)有真正意義(yi)上的(de)(de)(de)截(jie)(jie)斷(duan)(duan)一(yi)(yi)次之后就是(shi)剩(sheng)下(xia)的(de)(de)(de)字符串(chuan)了,所以(yi)要把每次截(jie)(jie)斷(duan)(duan)的(de)(de)(de)點和上一(yi)(yi)次截(jie)(jie)斷(duan)(duan)的(de)(de)(de)點加上,才是(shi)最新一(yi)(yi)次字符串(chuan)截(jie)(jie)斷(duan)(duan)的(de)(de)(de)位置。
(5) 循環和(he)判斷使用的有(you)點多,不知道對(dui)性能有(you)沒有(you)影響(xiang)。。。。。。
調用的時候:

var ctx = wx.createCanvasContext('word');
var name='窗前明月光,疑是地上霜,舉頭望明月,低頭思故鄉。';
this.dealWords({
ctx: ctx,//畫布上下文
fontSize: 16,//字體大小
word: name,//需要處理的文字
maxWidth: 100,//一行文字最大寬度
x: 0,//文字在x軸要顯示的位置
y: 0,//文字在y軸要顯示的位置
maxLine: 3//文字最多顯示的行數
})
ctx.draw();
|

(1) 這個方法能夠處理一(yi)行或(huo)者(zhe)(zhe)多(duo)行的(de)情況,就看maxLine設(she)(she)置(zhi)的(de)大小了(le)。當然如果設(she)(she)置(zhi)maxLine為0或(huo)者(zhe)(zhe)-1,就會(hui)不顯示的(de)。。。
看一下效果:


(1) canvas我設(she)置(zhi)的(de)(de)是200 * 200的(de)(de)大小(xiao),其它的(de)(de)設(she)置(zhi)就是上面調用的(de)(de)時候設(she)置(zhi)的(de)(de)


(1) 這(zhe)是當maxWidth設置為200px的時(shi)候(hou)的顯(xian)示情況。
完成 (^-^)V