原生也可以使用,不过需要稍加修改。uni. 替换为 wx.
https://github.com/liudongyun1215/wxml2canvas
1.下载 wxml2canvas
npm install wxml2canvas
2.页面代码 html 部分可以自己改成自己需要样式 记住带好class即可
<template>
<view>
<view class="plane planel" id="plane">
<view class="bg answer_draw_canvas" data-type="background-image">
<view class="box answer_draw_canvas">
<view class="h answer_draw_canvas" data-type="text" data-text='我的推广码'>我的推广码</view>
<view class="h2 answer_draw_canvas" data-type="text" data-text='分享二维码,让好友扫码添加'>分享二维码,让好友扫码添加</view>
</view>
<view class="codebox answer_draw_canvas" data-type="background-image">
<image :src="qrcode" :data-url='qrcode' class="code answer_draw_canvas" data-type="image"></image>
<view class="btn" @click="onQrCode" data-type="text">保存海报</view>
</view>
<view class="box answer_draw_canvas">
<image class="logo answer_draw_canvas" src="/static/image/mine/plane_logo.png" data-type="image" data-url="/static/image/mine/plane_logo.png"></image>
<view class="p answer_draw_canvas" data-type="text" data-text='家政服务'>家政服务</view>
<view class="p answer_draw_canvas" data-type="text" data-text='家电维修'>家电维修</view>
<view class="info answer_draw_canvas" data-type="text" data-text='长按识别图中二维码前往小程序'>长按识别图中二维码前往小程序</view>
</view>
</view>
</view>
<canvas canvas-id="answerCanvas" class="answerCanvas" :style="'width:' + width + 'px;height:' + height + 'px;'"></canvas>
</view>
</template>
<script>
import Wxml2Canvas from 'wxml2canvas';
export default {
data() {
return {
// 二维码路径
qrcode: '',
width: '0',
height: '0',
imgUrl:'',
}
},
methods: {
// 分享二维码
onshare() {
},
getCode() {
this.$post('api/qrcode/huoqu_code').then(res => {
if (res.data.code == 1) {
this.base64ToSave(res.data.data)
}
})
},
mapShare() {
// app 的保存方法
},
onQrCode() {
uni.getSetting({
success:res=>{
console.log();
if(res.authSetting['scope.writePhotosAlbum']){
uni.showLoading({
title: '加载中'
})
const that = this
const query = uni.createSelectorQuery().in(this);
query.select('#plane').fields({
size: true,
scrollOffset: true
}, data => {
let width = data.width;
let height = data.height;
this.width = width
this.height = height
setTimeout(() => {
that.draw()
}, 3000);
}).exec()
}else {
uni.authorize({
scope:'scope.writePhotosAlbum',
fail:err=>{
uni.openSetting()
this.global.toast('此功能需要打开相册权限')
}
})
}
}
})
},
draw() {
let that = this
//创建wxml2canvas对象
let drawImage = new Wxml2Canvas({
element: 'answerCanvas', // canvas节点的id,
obj: that, // 在组件中使用时,需要传入当前组件的this
width: this.width * 2, // 宽 自定义
height: this.height * 2, // 高 自定义
background: '#000', // 默认背景色 设置背景色
progress(percent) { // 绘制进度
// console.log(percent);
},
finish(url) {
uni.saveImageToPhotosAlbum({
filePath:url,
success(){
uni.hideLoading()
},
fail() {
uni.hideLoading()
}
})
},
error(res) {
console.log(res);
// uni.hideLoading()
// 画失败的原因
}
}, this);
//传入数据,画制canvas图片
let data = {
//直接获取wxml数据
list: [{
type: 'wxml',
class: '.planel .answer_draw_canvas', // answer_canvas这边为要绘制的wxml元素跟元素类名, answer_draw_canvas要绘制的元素的类名(所有要绘制的元素都要添加该类名)
limit: '.plane', // 这边为要绘制的wxml元素跟元素类名,最外面的元素
x: 0,
y: 0
}]
}
drawImage.draw(data, this);
},
base64ToSave(base64data,FILE_BASE_NAME='tmp_base64src') {
let that = this
const fsm = uni.getFileSystemManager();
return new Promise((resolve, reject) => {
//format这个跟base64数据的开头对应
const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64data) || [];
if (!format) {
reject(new Error('ERROR_BASE64SRC_PARSE'));
}
const filePath = `${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}.${format}`;
const buffer = wx.base64ToArrayBuffer(bodyData);
fsm.writeFile({
filePath,
data: buffer,
encoding: 'binary',
success() {
that.qrcode = filePath
resolve(filePath);
},
fail() {
reject(new Error('ERROR_BASE64SRC_WRITE'));
},
});
});
},
},
onLoad(option) {
this.getCode()
},
}
</script>
<style lang="less" scoped>
* {
margin: 0;
padding: 0;
}
.plane {
}
.box {
width: 100%;
display: flex;
align-items: center;
flex-direction: column;
}
.bg {
background: url('') 0 0 no-repeat;
background-size: 750rpx;
min-height: 100vh;
box-sizing: border-box;
display: flex;
align-items: center;
flex-direction: column;
justify-content: space-between;
padding-bottom: 10rpx;
}
.h {
width: 100%;
padding: 0 70rpx;
box-sizing: border-box;
height: 70rpx;
font-weight: bold;
color: #FFFFFF;
line-height: 70rpx;
}
.h2 {
width: 100%;
padding: 0 70rpx;
box-sizing: border-box;
font-size: 28rpx;
font-weight: bold;
color: #FFF;
line-height: 39rpx;
margin: 16rpx 0 0;
}
.codebox {
background: url(/uploads/20231009/130cb2db4444e8c5d4e10b5b37b5a44b.png) 0 0 no-repeat;
width: 690rpx;
height: 600rpx;
background-size: 100%;
display: flex;
align-items: center;
flex-direction: column;
.code {
width: 318rpx;
height: 318rpx;
margin: 157rpx 0 14rpx;
}
.btn {
width: 282rpx;
height: 59rpx;
text-align: center;
font-size: 25rpx;
color: #FFFFFF;
line-height: 59rpx;
background: linear-gradient(90deg, #696AF6 0%, #B3BEF7 100%);
border-radius: 30rpx;
}
}
.logo {
width: 282rpx;
height: 86rpx;
margin: 0 0 14rpx;
}
.p {
font-size: 30rpx;
font-weight: bold;
color: #FFFFFF;
line-height: 42rpx;
letter-spacing: 6px;
width: 100%;
text-align: center;
}
.info {
font-size: 28rpx;
font-weight: bold;
color: #FFF;
line-height: 39rpx;
margin-top: 55rpx;
}
</style>