微信小程序自定义二维码分享图--Canvas画图及注意事项
在一二月份做项目的时候,需要做一个微信小程序的自定义的二维码,在此记录与分享如何用Canvas画图怎么自定义一个美观的二维码分享图。
先展示下效果:
展示的是一个个人中心的小demo,下文会把这个demo的地址分享,导入项目后,点击分享推荐就可得到该效果。
页面
//PersonalPage.wxml
<view class='user'>
<view class='firstlayout'>
<image src="{{img}}" class='firstimagestyle'></image>
<view class='firstfontstyle'>{{name}}</view>
<view class='secondlayout'>
<view class='secondlayoutitem'>
<view class='firstfontstyle'>积分:</view>
<view class='firstfontstyle'>{{scores}}</view>
</view>
<!--<view class='lineview'></view>-->
<view class='secondlayoutitem'>
<view class='firstfontstyle'>余额:</view>
<view class='firstfontstyle'>{{balance}}</view>
</view>
</view>
</view>
<view class='user-item'>
<view class='item' bindtap='bindViewTapbasic'>
<image class='secondimagestyle' src='/images/personCenter/5.png'></image>
<view class=' item-title'>基本信息</view>
<image src='/images/personCenter/2.png' class='thirdimagestyle'></image>
</view>
<view class='item' bindtap='bindViewTapaddress'>
<image class='secondimagestyle' src='/images/personCenter/3.png'></image>
<view class=' item-title'>我的地址</view>
<image src='/images/personCenter/2.png' class='thirdimagestyle'></image>
</view>
<view class='item' bindtap="bindViewTap">
<image class='secondimagestyle' src='/images/personCenter/7.png'></image>
<view class=' item-title'>我的订单</view>
<image src='/images/personCenter/2.png' class='thirdimagestyle'></image>
</view>
<view class='item' bindtap="onShareTap">
<image class='secondimagestyle' src='/images/personCenter/4.png'></image>
<view class=' item-title'>分享推荐</view>
<image src='/images/personCenter/2.png' class='thirdimagestyle'></image>
</view>
<view class='item' bindtap='bindViewTapsetup'>
<image class='secondimagestyle' src='/images/personCenter/6.png'></image>
<view class='item-title'>关于我们</view>
<image src='/images/personCenter/2.png' class='thirdimagestyle'></image>
</view>
</view>
</view>
//二维码分享图是隐藏的
<view class="bg" bindtap='hideview' style='display:{{display}}'></view>
<view class="show" bindtap='hideview' style='display:{{display}}'>
<view class='containera'>
<image class="imagesa" src="{{shareImgSrc}}"></image>
<view class='fourlayoutstylea'>
<button size="{{primarySize}}" bindtap="showLocal"> 保存分享图片 </button>
</view>
<view class="canvas-box">
<canvas canvas-id="myCanvas" style="width:100%;height:{{windowHeight}}px;"></canvas>
</view>
</view>
</view>
布局
//PersonalPage.wxss
page{
width:100%;
height: 100%;
}
.user{
background: rgb(245, 245, 245);
width:100%;
height: 100%;
}
.user-item{
margin-top: 30rpx;
width:100%;
display: flex;
flex-direction: column;
}
.item{
background: #fff;
height:100rpx;
margin-top:20rpx;
line-height: 100rpx;
display: flex;
justify-content: space-between;
}
.item-title{
flex-grow: 4;
margin-left: 20rpx;
}
.container{
/*弹性模型*/
display:flex;
/*垂直方向 列方向 排布*/
flex-direction:column;
/*居中*/
/*align-items:center;*/
/*要从整体解决排布的问题是最好的方案*/
background: rgb(245, 245, 245);
}
.containe1{
margin-top: 50rpx;
width: 100%;
display: flex;
flex-direction:column;
}
.firstlayout{
/*弹性模型*/
display:flex;
/*垂直方向 列方向 排布*/
flex-direction:column;
/*居中*/
align-items:center;
/*要从整体解决排布的问题是最好的方案*/
width: 100%;
height: 400rpx;
background: #21bba6;
}
.firstimagestyle{
width: 180rpx;
height: 180rpx;
margin: 20rpx;
border-radius: 50%;
border:3px solid #FFFFFF;
}
.firstfontstyle{
font-size:34rpx;
color: #FFFFFF;
}
.secondlayout{
width: 550rpx;
height: 50rpx;
/*弹性模型*/
display:flex;
flex-direction: row;
/*居中*/
/*align-items:center;*/
justify-content:center;
margin-top: 25rpx;
}
.secondlayoutitem{
width: 50%;
display:flex;
flex-direction: row;
justify-content:center;
}
.lineview{
width: 2rpx;
height: 40rpx;
background: #FFFFFF;
margin-top: 6rpx;
}
.secondimagestyle{
width: 40rpx;
height: 40rpx;
margin: 30rpx;
}
.fourthlayout{
width:50%;
height: 100%;
text-align:right;
}
.thirdimagestyle{
width: 60rpx;
height: 60rpx;
margin: 20rpx;
}
.secondfontstyle{
flex-grow: 4;
margin-left: 40rpx;
}
.lineviewtwo{
width: 100%rpx;
height: 1px;
background: #708090;
}
.bg {
display: none;
position: absolute;
top: 0%;
left: 0%;
width: 100%;
height: 100%;
background-color: black;
z-index: 1001;
-moz-opacity: 0.7;
opacity: 0.70;
filter: alpha(opacity=70);
}
.show {
text-align: center;
position: absolute;
top: 5%;
left: 10%;
width: 80%;
height: 90%;
z-index: 1002;
}
.canvas-box {
height: 100%;
width: 100%;
position: fixed;
left: 0;
top: 999999rpx;
}
.containera {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
position: relative;
}
image {
width: 100%;
height: 75%;
}
.fourlayoutstylea {
width: 50%;
height: 200rpx;
align-items: center;
position: absolute;
bottom: 0;
left: 50%;
margin-left: -25%;
}
Canvas画图
//点击事件
onShareTap: function (event) {
wx.showLoading({
title: '生成中',
})
this.setData({
display: "block",
})
var that = this;
that.onshow("溯夜", "../../images/personCenter/1.jpg");
// wx.getImageInfo({
// src: app.globalData.img,
// success: function (sres) {
// that.onshow(app.globalData.name, sres.path);
// }
// })
},
在这里注意的是,微信小程序不能直接获取网络上的图片资源,如果想要引用网络上的图片资源,需要缓存,可以调用 wx.getImageInfo方法缓存,缓存成功该方法会返回图片的地址,这个地址微信小程序可以直接引用。
onshow: function (name, img) {
var that = this;
// canvas绘制文字和图片,创建画图
const ctx = wx.createCanvasContext('myCanvas');
//绘制背景图
var bgImgPath = '../../images/personCenter/17.jpg'
var imgPath = '../../images/personCenter/ma.jpg';//二维码
ctx.drawImage(bgImgPath, 0, 0, this.data.windowWidth, 280);
ctx.setFillStyle('white')
ctx.fillRect(0, 280, 300, 120);
ctx.drawImage(imgPath, 190, 290, 100, 100);
ctx.drawImage(img, 10, 290, 40, 40)
//绘制字体,颜色,与位置
ctx.setFontSize(14)
ctx.setFillStyle('#6F6F6F')
ctx.fillText(name, 63, 314)
ctx.setFontSize(15)
ctx.setFillStyle('#111111')
ctx.fillText('亲们快来使用回收利器', 10, 350)
ctx.fillText(name + '在筑梦回收', 10, 370)
ctx.setFontSize(10)
ctx.fillText('长按扫码查看详情', 10, 390)
//canvasToTempFilePath必须要在draw的回调中执行,否则会生成失败,官方文档有说明
ctx.draw(false, setTimeout(function () {
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: that.data.windowWidth,
height: that.data.windowHeight,
destWidth: that.data.windowWidth * 2,
destHeight: that.data.windowHeight * 2,
canvasId: 'myCanvas',
success: function (res) {
console.log(res.tempFilePath);
wx.hideLoading();
that.setData({
shareImgSrc: res.tempFilePath
})
},
fail: function (res) {
wx.hideLoading();
wx.showToast({
title: '生成失败',
icon: "none"
})
}
})
}, 200));
},
这里一定小心注意的是,canvasToTempFilePath必须要在draw的回调中执行,否则会生成失败,官方文档有说明。 而且,为保证图片生成的清晰度,destWidth与destHeight需设置成你原来期待高度与宽度的n倍,一般两到三倍就行了,否则图片很大,生成较慢。
保存在本地
//保存在本地
showLocal: function () {
var that = this;
console.log(that.data.shareImgSrc);
wx.saveImageToPhotosAlbum({
filePath: that.data.shareImgSrc,
success(res) {
wx.showModal({
title: '存图成功',
content: '图片成功保存到相册了,去发圈噻~',
showCancel: false,
confirmText: '好哒',
confirmColor: '#21bba6',
success: function (res) {
if (res.confirm) {
console.log('用户点击确定');
}
}
})
}, fail: function () {
wx.showToast({
title: '保存失败',
icon: "none"
})
}
})
}
})