返回顶部
首页 > 资讯 > 精选 >小程序 canvas 绘制文本实现换行,设置字距
  • 313
分享到

小程序 canvas 绘制文本实现换行,设置字距

小程序前端 2023-12-22 21:12:23 313人浏览 八月长安
摘要

小程序 canvas 绘制文本实现换行,设置字距 在使用 canvas 绘制文本的过程中,对于很长的文本,canvas 不能自动的进行换行处理,另外小程序无法像 WEB 端那样很方便的使用 svg,所以在此做一个简单的记录。 浅析 在实现之

小程序 canvas 绘制文本实现换行,设置字距

在使用 canvas 绘制文本的过程中,对于很长的文本,canvas 不能自动的进行换行处理,另外小程序无法像 WEB 端那样很方便的使用 svg,所以在此做一个简单的记录。

浅析

在实现之前简单的分析一下,要实现文本换行功能,在 canvas 中我们使用的是 fillText(text, x, y, maxWidth) 方法,
假设我们绘制的文本有最大的宽度,在超出这个宽度之后就进行换行,所以我们得知道绘制文本的宽度。

设置字距,如果是 CSS 那么就简单,直接使用 letter-spacing 即可,当然可以给 canvas 直接设置,
但是对于部分场景下可能操作起来不是那么方便,所以还在在绘制上面下文章,既然不直接设置,
那么就只有绘制一个字符就隔开一定间距再绘制另外一个字符,也就是逐字绘制。

实现

<template><view class="content"><view class="ele-container"><canvas canvas-id="nnCanvas">canvas><viewclass="test-text":style="{width: width + 'px',fontSize: fontSize + 'px',lineHeight: fontSize + lineHeight + 'px',letterSpacing: letterSpacing + 'px'}"><text>{{ testText }}text>view><view><button @click="handleFontSize">字号button><button @click="handleLineHeight">行高button><button @click="handleLetterSpacing">字距button>view>view>view>template><script>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 2dthis.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  } = thislet textLen = tempText.lengththis.ctx.font = `${fontSize}px YaHei`// 如果绘制的文本总宽度并没有超过最大宽度,那么直接绘制if (this.ctx.measureText(tempText).width +textLen * letterSpacing < this.width) {this.ctx.fillText(tempText, 0, fontSize)} else {let strArray = []let tempStr = ''for (let i = 0; i < textLen; i++) {let currStr = tempText[i]// 判断当前字符是否是换行符,如果是,那么新增下一行let isWrap = !/\r?\n/.test(currStr)if (isWrap &&(this.ctx.measureText(tempStr + currStr).width +(tempStr.length + 1) * letterSpacing) < this.width) {// 如果不是换行符且当前绘制的文本宽度加字距小于最大宽度,直接当前行字符串直接拼接tempStr += currStr} else {// 否则就是当前行的宽度已经达到极限,进行换行strArray.push(tempStr)if (isWrap) {// 如果不是换行符,直接新的一行开头就是这个字符tempStr = currStr} else {// 否则,新的一行开头将换行符替换为空字符串tempStr = ''}}}// 如果还有剩余结尾的字符串,直接就算作一行if (tempStr != '') {strArray.push(tempStr)tempStr = ''}strArray.forEach((str, index) => {// 逐行绘制,绘制的 y 坐标当前行行数加上字体大小加上行高近似的模拟this.handleDrawOneLineText(str, (index + 1) * (fontSize + this.lineHeight))})// 微信不使用 canvas 2dthis.ctx.draw()}},handleDrawOneLineText(str, y) {let tempStr = ''for (let i = 0, len = str.length; i < len; i++) {// 逐字绘制,每行的y不变,单个字符的x是前面绘制文本的宽度加上每个字符的间距和this.ctx.fillText(str[i],i * this.letterSpacing + (this.ctx.measureText(tempStr).width),y)tempStr += str[i]}},// 测试变化,方便查看效果handleFontSize() {if (this.fontSize < 20) {this.fontSize += 1} else {this.fontSize -= 1}this.handleDrawText()},handleLineHeight() {if (this.lineHeight < 5) {this.lineHeight += 1} else {this.lineHeight -= 1}this.handleDrawText()},handleLetterSpacing() {if (this.letterSpacing < 10) {this.letterSpacing += 1} else {this.letterSpacing -= 1}this.handleDrawText()}}}script><style lang="scss" scoped>.test-text {// 为了让效果看上去一致,所以使用这个属性,// 不然单词和连续数字截断效果就不一样了Word-break: break-all}style>

效果

在这里插入图片描述

可以看到上面 canvas 绘制的效果和下面标签渲染的效果差不到很多。

最后

实现始终都是按照自己项目的需求来的,不同的项目,近似的一个需求可能实现的方式就稍微不同。

来源地址:https://blog.csdn.net/asdf11111_____/article/details/133794314

--结束END--

本文标题: 小程序 canvas 绘制文本实现换行,设置字距

本文链接: https://lsjlt.com/news/551515.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作