小程序将页面转为图片--Wxml2Canvas
如果需要实现将小程序的页面转为图片,第一步是要先把页面转为canvas,再将canvas转为图片。本人使用的是Wxml2Canvas这个插件。其实最开始使用的是wxml-to-canvas这个官方自带的组件。由于这个组件坑太多,本地调试一切正常,但是到了真机调试就会出现创建画布失败的情况,寻找了很久,最多的方法方法就是添加延时器,或者画布的高度设置在1000px以内。但是都没有什么鬼用,最终无可奈
如果需要实现将小程序的页面转为图片,第一步是要先把页面转为canvas,再将canvas转为图片。本人使用的是Wxml2Canvas这个插件。其实最开始使用的是wxml-to-canvas这个官方自带的组件。由于这个组件坑太多,本地调试一切正常,但是到了真机调试就会出现创建画布失败的情况,寻找了很久,最多的方法方法就是添加延时器,或者画布的高度设置在1000px以内。但是都没有什么鬼用,最终无可奈何,只能换个插件,重新写。好惨一男的😥
那我们废话不多说,准备开始搞事情!!
第一步 安装插件
注意 安装之后别忘了构建npm
npm install wxml2canvas
第二步 引入
import Wxml2Canvas from 'wxml2canvas';
第三步 使用
首先需要在页面上创建一个canvas以及需要生成图片的结构
<canvas canvas-id="share"></canvas>
<view class="share__canvas share__canvas1">
<view class="share__canvas1-text draw_canvas"
data-type="text" data-text="这是一段无边距文字">
这是一段无边距文字
</view>
</view>
如果需要使用到图片,其中data-url是图片在canvas显示的地址,即:
<image class="draw_canvas" data-type="image"
data-url="/static/share/friend_logo.png"
data-delay="1" mode="aspectFit" src="/static/share/friend_logo.png"></image>
其中,还有text标签可以使用,必填属性为data-type,声明此标签的在canvas中展示类型,每个标签都有data-top和data-left的属性,分别代表元素参照与自身位置的偏移值。 需要注意的是,data-text是生成的canvas中显示的文字,可以理解为标签的自定义属性,也可以接受变量等。
写入事件,用于获取id为wxml-canvas的宽高,这里的获取的元素的宽高就是将来生成canvas的父元素,获取之后触发draw函数。
//动态获取画制作元素的宽高
drawCanvas: function () {
const query = wx.createSelectorQuery().in(this);
query.select('#wxml-canvas').fields({
size: true,
scrollOffset: true
}, data => {
let width = data.width;
let height = data.height;
this.width = width;
this.height = height;
setTimeout(() => {
this.draw()
}, 1500);
}).exec();
draw函数:
draw() {
let that = this
//创建wxml2canvas对象
let drawImage = new Wxml2Canvas({
element: 'share', // canvas节点的id,
obj: that, // 在组件中使用时,需要传入当前组件的this
width: this.width * 2, // 宽高
height: this.height * 4,
background: '#fff', // 默认背景色
progress(percent) { // 绘制进度
},
finish(url) {
console.log("创建的图片", url);
},
error(res) {
console.log(res);
// uni.hideLoading()
// 画失败的原因
}
}, this);
let data = {
//直接获取wxml数据
list: [{
type: 'wxml',
class: '.long_friend .draw_canvas',
limit: '.long_friend ',
x: 0,
y: 0
} ]
}
//传入数据,画制canvas图片
drawImage.draw(data, this);
},
解读draw函数
创建wxml2canvas对象
这一步是为了创建wxml2canvas对象,其中传入的参数有三个,第一个参数为一个对象option。第二个参数为创建图片成功时的回调函数,成功时的回调函数第一个参数为图片的地址。第三个参数为失败时的回调函数,会返回失败原因以及状态码,第四个参数传this,是为了防止“canvasToTempFilePath: fail canvas is empty ”报错,报这个错是因为调取wx.canvasToTempFilePath 接口获取不到canvas,同样的需要传入上下文的this。
其中option的宽高,也是生成图片的宽高,我将其设置为元素的初始宽度的两倍,是因为如果是等比的话,图片会模糊。如果发现将宽高*2还是出现图片糊的情况,可以适当调整倍数。
//创建wxml2canvas对象
let drawImage = new Wxml2Canvas({
element: 'share', // canvas节点的id,
obj: that, // 在组件中使用时,需要传入当前组件的this
width: this.width * 2, // 宽高
height: this.height * 2,
background: '#fff', // 默认背景色
progress(percent) { // 绘制进度
},
finish(url) {
console.log("创建的图片", url);
},
error(res) {
console.log(res);
// uni.hideLoading()
// 画失败的原因
}
}, this);
初始化属性option,其属性属性如下:
属性名 | 类型 | 默认值 | 是否必填 | 说明 |
element | String | “” | 是 | 画布的id |
width | Number | 0 | 是 | 画布的宽,以iphone6的375为基准,其他机型按比例自动设置实际宽度 |
height | Number | 0 | 是 | 画布的高,同上 |
destZoom | Number | 3 | 否 | 输出的图片的像素密度,不建议传值,如果需要控制图片大小,可以适当减小 |
zoom | Number | 1 | 否 | 画布整体缩放比例,不建议传值,会覆盖各种机型的适配 |
translateX | Number | 0 | 否 | 画布整体横向位移 |
translateY | Number | 0 | 否 | 画布整体纵向位移 |
height | Number | height * 2 | 否 | 输出的图片的高度 |
background | String | #ffffff | 否 | 画布的整体背景色 |
gradientBackground | Object | null | 否 | 画布整体的渐变背景色 |
finish | Function | null | 否 | 绘制成功后回调函数, 返回值url,绘制图片的本地路径 |
progress | Function | null | 否 | 绘制进度,返回值percent,0-100 |
error | Function | null | 否 | 绘制失败后回调函数,返回值object,包含具体原因 |
绘制失败的原因如下:
错误码 | 原因 | 说明 |
---|---|---|
errcode | errmsg | e |
1000 | save canvas error | 保存图片失败 |
1001 | download pic error | 预下载图片失败 |
1002 | drawRect error | 绘制矩形失败 |
1003 | drawImage error | 绘制图片失败 |
1004 | drawText error | 绘制文本失败 |
1005 | drawCircle error | 绘制圆形图片失败 |
1006 | drawCircleImage error | 绘制圆形失败 |
1007 | drawLine error | 绘制线条失败 |
1008 | drawWxml error | 绘制Wxml失败 |
1009 | drawWxml preLoadImage error | 预下载Wxml图片失败 |
表格数据转载自:https://github.com/liudongyun1215/wxml2canvas
函数内声明的data对象:
这里的type可以为矩形(rect),圆形(circle),线条(line),图片(image),文本(text)等,声明type为wxml时,会查询绘制元素节点的样式并绘制,class是待查询绘制的节点类名,会查询所有相同的类名。而limit是下面x和y的参考元素,故x和y就是class中元素参照limit祖先元素的偏移值。其更多属性参照与:https://github.com/liudongyun1215/wxml2canvas
let data = {
//直接获取wxml数据
list: [{
type: 'wxml',
class: '.share__canvas1 .draw_canvas',// draw_canvas指定待绘制的元素
limit: '.share__canvas1',// 限定绘制元素的范围,取指定元素与它的相对位置
x: 0,
y: 0
} ]
}
好啦,这就是小谭今天要分享的内容,总结一下,其实这个功能看起来很麻烦,但是只要把思路理清楚在一步步实现就行。说个题外话,wx小程序官方自带组件的问题其实还是蛮坑的。所以,要慎用!血的教训,太惨了。
更多推荐
所有评论(0)