小程序 canvas 绘制文本实现换行,设置字距
小程序 canvas 绘制文本实现换行,设置字距
在使用 canvas 绘制文本的过程中,对于很长的文本,canvas 不能自动的进行换行处理,另外小程序无法像 web 端那样很方便的使用 svg,所以在此做一个简单的记录。
浅析
在实现之前简单的分析一下,要实现文本换行功能,在 canvas 中我们使用的是 fillText(text, x, y, maxWidth) 方法,
假设我们绘制的文本有最大的宽度,在超出这个宽度之后就进行换行,所以我们得知道绘制文本的宽度。
设置字距,如果是 css 那么就简单,直接使用 letter-spacing 即可,当然可以给 canvas 直接设置,
但是对于部分场景下可能操作起来不是那么方便,所以还在在绘制上面下文章,既然不直接设置,
那么就只有绘制一个字符就隔开一定间距再绘制另外一个字符,也就是逐字绘制。
实现
{{ testText }} 字号 行高 字距 export default { data() { return { ctx: null, width: 200, fontSize: 14, lineHeight: 0, letterSpacing: 0, testText: ' 这是一段\n很长很长很长\r\n很长很长很\n\n长很长很长很长的 12314223asjedhweihdf hello world xxx文本 ' } }, mounted() { // // 微信使用 canvas 2d // const _this = this // const query = wx.createSelectorQuery() // query.select('#nnCanvas') // .fields({ node: true, size: true }) // .exec((res) => { // let canvas = res[0].node // _this.ctx = canvas.getContext('2d') // _this.handleDrawText() // }) // 微信不使用 canvas 2d this.ctx = uni.createCanvasContext('nnCanvas') this.handleDrawText() }, methods: { handleDrawText() { // // 微信使用 canvas 2d // this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height) // 多个连续空格只保留一个 let tempText = this.testText.replace(/(^\s*)|(\s*$)/g, ' ').replace(/ +/g, ' ') let { fontSize, letterSpacing } = this let textLen = tempText.length this.ctx.font = `${fontSize}px YaHei` // 如果绘制的文本总宽度并没有超过最大宽度,那么直接绘制 if ( this.ctx.measureText(tempText).width + textLen * letterSpacing { // 逐行绘制,绘制的 y 坐标当前行行数加上字体大小加上行高近似的模拟 this.handleDrawOneLineText(str, (index + 1) * (fontSize + this.lineHeight)) }) // 微信不使用 canvas 2d this.ctx.draw() } }, handleDrawOneLineText(str, y) { let tempStr = '' for (let i = 0, len = str.length; i效果
可以看到上面 canvas 绘制的效果和下面标签渲染的效果差不到很多。
最后
实现始终都是按照自己项目的需求来的,不同的项目,近似的一个需求可能实现的方式就稍微不同。
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。