java小程序画板流程图,小程序 画布 文本绘制

情景:有很多文本,有的是一行,有的是多行的段落,这么多文本,需要一个方法来处理。

代码:

onload () {

......

// CanvasContext.setTextAlign() 是根据坐标来展示文字的,具体用法去官网

this.drawText(ctx, {

textAlign: 'right',

fontColor: '#f00',

fontSize: 30,

text: 'Hello',

x: 300,

y: 30

});

this.drawText(ctx, {

textAlign: 'left',

text: 'Hello 中国!Hello word! Hello Everyone!',

x: 20,

y: 80,

maxWidth: 100

});

this.drawText(ctx, {

textAlign: 'center',

text: 'Hello 中国! Hello word! Hello Everyone! ',

x: 20 + 50,

y: 150,

maxWidth: 100,

isWrap: true,

charDistace: 2,

wrapLineHeight: 40

});

......

},

......

// charDistace 这个属性的设置,主要是为了换行的时候,减少循环的次数

// 换行的原理:一个一个文字叠加,然后测量它们的宽度,然后和最大的宽度值进行对比

// 于是设置了charDistace 属性,自定义一次叠加的字数,默认一个,也可以设置为多个

drawText (ctx, options) {

// textAlign type: string

if (options.textAlign) {

ctx.setTextAlign(options.textAlign)

}

//fontColor type: string

if (options.fontColor) {

ctx.setFillStyle(options.fontColor)

}

// fontSize type: number

if (options.fontSize) {

ctx.setFontSize(options.fontSize)

}

if (!options.isWrap) {

ctx.fillText(options.text, options.x, options.y, options.maxWidth);

} else {

// options.isWrap 是否换行

// options.charDistace 默认1,表示一次循环一个字符, 这个值在isWrap为true时才有效

// options.wrapLineHeight 行的高度,这个值在isWrap为true时才有效

let charArr = options.text.split('');

let index = 0;

let end = 0;

let tempStr = '';

let metrics = null;

let d = options.charDistace || 1;

let i = d;

let tempI = 0;

let gap1 = 2; // 表示 maxw -xw <= 2 都可以当做相等

let gap2 = 2; // 如果xw - maxw < = 2 ,那么也当做相等

let isTextBigger = false;

let textBiggerIndex = 0;

let wrapNum = 0;

// 一次循环5个字符,并将循环的字符叠加,比如 i = 15, 测量它们的宽度xw15

// 如果xw15比最大的maxw大,则退回到 i = 11的状态,即11个字符长度 xw11

// 如果xw11 > maxw, 那么可以确定这行最多只能放10个字符,

// 因为xw10的时候,发生的下一次循环,说明xw10 < maxw

// 如果xw < maxw, 则开始一个一个字符循环,不再是5个5个字符循环

while (i < charArr.length) {

end = i;

// 不包含end

tempStr = charArr.slice(index, end).join('');

metrics = ctx.measureText(tempStr);

if ((options.maxWidth > metrics.width && options.maxWidth - metrics.width <= gap1) ||

(metrics.width > options.maxWidth && metrics.width - options.maxWidth <= gap2) ||

(metrics.width < options.maxWidth && isTextBigger && textBiggerIndex - i === 1 ) ||

(metrics.width < options.maxWidth && i === (charArr.length - 1))) {

// 字符宽度刚好符合最大宽度要求

// 另一种情况:加一个字符又太宽 > gap2; 减一个字符又太小 < gap1

// 另一种情况:最后一行

wrapNum++;

ctx.fillText(tempStr, options.x, options.y + (options.wrapLineHeight * wrapNum -1), options.maxWidth);

tempI = end;

index = end;

i = i + d;

isTextBigger = false;

} else {

// 字符宽度不符合最大宽度

if (metrics.width < options.maxWidth) {

// 字符宽度太小

tempI = i;

if (isTextBigger) {

i++

} else {

if ((i + d) > charArr.length) {

i++

} else {

i += d

}

}

} else {

// 字符宽度太大

isTextBigger = true;

textBiggerIndex = i;

i = tempI;

}

}

// console.log(tempStr, metrics)

}

}

},

aae9e36ffd42

image.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值