irpas技术客

微信小程序---canvas_闲人马大姐11_canvas 小程序

网络 5329

canvas官网:CanvasRenderingContext2D.canvas - Web APIs | MDN

小程序-canvas组件:canvas | 微信开放文档

1、两种cavnas获取上下文方式

老版本 createCanvasContext 方式

createCanvasContext是微信提供的获取 canvas实例的老得接口,使用方式如下。

wxml

<canvas style="width: 300px; height: 200px;" canvas-id="firstCanvas"></canvas>

美好的一天从写一个hello,world开始。

js中这么写

onReady(){ /* 使用 wx.createContext 获取绘图上下文 context , firstCanvas 与 canvas 属性中的canvas-id一一对应 */ const context = wx.createCanvasContext('firstCanvas') /* 设置字体大小 */ context.setFontSize(20) /* 设置字体颜色 */ context.setFillStyle('pink') /* 设置文本内容,位置 */ context.fillText('hello,world', 0, 0) context.draw() }

老版本是使用createCanvasContext传入 canvas标签中的 canvas-id属性,来获取canvas实例,老版本的使用起来说实话,不够灵活,很多对canvas线条,颜色的设置,都封装成方法了,每次改变需要调用方法。

新版本 getContext 上下文方式(2.9.0)

新的方式,则是先通过 createSelectorQuery 获取 canvas 元素节点, 然后通过 getContext 获取上下文。

wxml

<canvas type="2d" id="myCanvas"></canvas>

js

const query = wx.createSelectorQuery() query.select('#myCanvas') .fields({ node: true, size: true }) .exec((res)=>{ const { node } = res[0] if (!node) return /* 获取 canvas 实例 */ const context = node.getContext('2d') context.fillStyle = 'pink' /* 设置字体样式 大小 字体类别 */ context.font = 'normal 400 12px PingFangSC-Regular', context.fillText('hello,world', 0, 0) })

这种方式和第一种 createSelectorQuery 方式,在api使用方式上会有微妙的差别,这种写法更像原生的DOM写法,设置颜色,样式,直接改变context属性,而不再需要调用对应的api。

1、关于canvas 宽高以及缩放比问题,绘制的元素变形,画布的高度真得等于cavans标签设置的宽高么?

容器宽高: 我们给canvas标签设置的宽高,就是如上代码中的?canvasStyle,是canvas容器的宽高。?

画布宽高: 而我们画布的宽高,在新版本api中,是通过获取node节点,动态设置的node.width?和?node.height的值。

容器宽高≠画布宽度

?小程序的canvas画布有一个原始的画布宽高,以及缩放比,而且是按照一倍像素来的,当我们给canvas容器设定容器宽高之后,如果没有对应设置canvas画布的画布宽高以及scale,画出的画布就会严重的变形。如果我们期望将整个屏幕作为画布,对于不同手机,屏幕尺寸都会有差别,所以要动态获取设备的宽高。

2、canvas绘制图片

?api-drawImage:CanvasContext.drawImage(string imageResource, number sx, number sy, number sWidth, number sHeight, number dx, number dy, number dWidth, number dHeight) | 微信开放文档

网络图片: 首先需要通过getImageInfo来获取图片的临时路径。用getImageInfo绘制网络资源的时候请注意配置一下合法的下载域名,要不然我们是无法成功获取图片信息的。我们首先需要在小程序后台配置downloadFile合法域名。

api-getImageInfp:wx.getImageInfo(Object object) | 微信开放文档

/* backGroundImageUrl 是我们要画的网络图片的地址 */ this.getImageInfo(backGroundImageUrl).then(res=>{ const { width, /* 宽度 */ height, path /* 临时路径 */ } = res1 /* 第二步: 绘图 */ this.drawImage(context, node, path, 0, 0, width, height, 0, 0, 0, 0) })

本地图片: 直接通过canvas提供的drawImage进行绘制。

const image = node.createImage(); image.src = url image.onload = () => { context.drawImage(image,x,y,width,height,dx,dy,dwidth,dheight) }

canvas怎么绘制叠在一起的两张图片,并控制层级?

首先想到的是层级问题,我们期望背景图片放在下面,但是在画布中没有控制zIndex层级的属性。实际在canvas中,绘制的先后顺序 就是画布层级顺序,后画的在先画的上层,那么对于这种层级问题呢,我们只要保证层级高的元素后画,层级低的元素先画就可以完美解决。

3、如何用canvas绘制,多行文本?

一个一个字的绘制到canvas中,然后把每个字的宽度相加,如果总宽度大于容器宽度,就另取一行从新绘制

/** 画多行文本 * @param ctx canvas 上下文 * @param str 多行文本 * @param initHeight 容器初始 top值 * @param initWidth 容器初始 left值 * @param canvasWidth 容器宽度 */ drawRanksTexts(ctx, str, initHeight, initWidth, canvasWidth) { let lineWidth = 0; let lastSubStrIndex = 0; /* 设置文字样式 */ ctx.fillStyle = "#303133" ctx.font = 'normal 400 15px PingFangSC-Regular' for (let i = 0; i < str.length; i++) { lineWidth += ctx.measureText(str[i]).width if (lineWidth > canvasWidth) { /* 换行 */ ctx.fillText(str.substring(lastSubStrIndex, i), initWidth, initHeight) initHeight += 20 lineWidth = 0 lastSubStrIndex = i } if (i == str.length - 1) { /* 无需换行 */ ctx.fillText(str.substring(lastSubStrIndex, i + 1), initWidth, initHeight) } } },

调用

/* TODO: 复制多行文本 */ const rowsText = await this.geDomPostion('#context', true) this.drawRanksTexts(context, this.skuName, rowsText.top, rowsText.left, rowsText.width)

4、保存海报

把当前画布指定区域的内容导出生成指定大小的图片

api-canvasToTempFilePath:wx.canvasToTempFilePath(Object object, Object this) | 微信开放文档

保存图片到系统相册

?api-saveImageToPhotosAlbum:wx.saveImageToPhotosAlbum(Object object) | 微信开放文档

作者:我不是外星人 链接:https://juejin.cn/post/6930404573043490830 来源:稀土掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #canvas #小程序 #Web #APIs