最近做一个功能,是在小程序里保存图片,因为本身内容不是图片,所以只能把内容绘画成图片,才能保存下来,
这是跟我们需求写的页面效果:
下面是实现的代码:
wxml部分
<button bindtap="cartridge">显示图片</button>
<!-- 弹窗 -->
<view class='imagePathBox' hidden="{{maskHidden}}">
<image src="{{imagePath}}" mode="aspectFill" class='canvas-img'></image>
<button class='saveBtn' bindtap='saveBtn'>保存到手机</button>
<view class='remind'>您的信息仅会保留1个月,请及时保存哦~</view>
<view>
<image src="../../images/close.png" class='close' bindtap='closeBtn'></image>
</view>
<view hidden="{{maskHidden == false}}" class="mask"></view>
<view class="canvas-box">
<canvas style="width: 375px;height: 667px;position:fixed;top:9999px;" canvas-id="mycanvas" />
</view>
</view>
js部分
Page({
/**
* 页面的初始数据
*/
data: {
maskHidden: true,
date: '2019-08-30',
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
},
// 显示图片
cartridge() {
const that = this;
wx.showToast({
title: '生成中...',
icon: 'loading',
duration: 1000
});
setTimeout(function () {
wx.hideToast()
that.createNewImg();
that.setData({
maskHidden: false
});
}, 2000)
},
// 创建图片内容
createNewImg: function () {
const that = this;
const content = "兹证明 张三(先生/女生)于 " + that.data.date + " 参加国际交流中心小程序培训,通过考试,成绩合格。"
that.setData({
content: content
})
const context = wx.createCanvasContext('mycanvas');
context.fillRect(0, 0, 375, 667) //绘制区域,和wxml的画布大小一致
const imgPath = '../../images/bj.jpg'; //添加背景图片
context.drawImage(imgPath, 0, 0, 375, 667);
//绘制标题
context.setFontSize(40);
context.setFillStyle('#ff5b89');
context.setTextAlign('center');
context.fillText("合格证书", 185, 113);
context.stroke();
// 绘制内容
context.setFontSize(18);
context.setFillStyle('#333333');
context.setTextAlign('left');
that.drawText(context, that.data.content, 22, 182, 330, 330)
context.stroke();
// 结束语
context.setFontSize(18);
context.setFillStyle('#333333');
context.setTextAlign('right');
context.fillText("国际合作交流中心", 360, 348);
context.fillText(that.data.date, 360, 373);
context.stroke();
// 绘图的命令
context.draw();
//将生成好的图片保存到本地,需要延迟一会,绘制期间耗时
setTimeout(function () {
wx.canvasToTempFilePath({
canvasId: 'mycanvas',
success: function (res) {
const tempFilePath = res.tempFilePath;
that.setData({
imagePath: tempFilePath,
canvasHidden: true
});
},
fail: function (res) {
console.log(res);
}
});
}, 200);
},
//文本换行 参数:1、canvas对象,2、文本 3、距离左侧的距离 4、距离顶部的距离 5、6、文本的宽度
drawText: function (ctx, str, leftWidth, initHeight, titleHeight, canvasWidth) {
let lineWidth = 0;
let lastSubStrIndex = 0; //每次开始截取的字符串的索引
for (let i = 0; i < str.length; i++) {
lineWidth += ctx.measureText(str[i]).width;
if (lineWidth > canvasWidth) {
ctx.fillText(str.substring(lastSubStrIndex, i), leftWidth, initHeight); //绘制截取部分
initHeight += 30; //30为字体的高度,//行间距
lineWidth = 0;
lastSubStrIndex = i;
titleHeight += 30;
}
if (i == str.length - 1) { //绘制剩余部分
ctx.fillText(str.substring(lastSubStrIndex, i + 1), leftWidth, initHeight);
}
}
// 标题border-bottom 线距顶部距离
titleHeight = titleHeight + 10;
return titleHeight
},
closeBtn() {
this.setData({
maskHidden: true
})
}
})
css部分:
/* 需要绘制的画布 */
.imagePathBox {
width: 100%;
height: 100%;
background: rgba(55, 60, 81, 0.8);
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 10;
}
/* 生成的图片--白色区域 */
.canvas-img {
width: 80%;
height: 75%;
position: fixed;
top: 50rpx;
left: 50%;
margin-left: -40%;
z-index: 10;
border-radius: 40rpx;
/* background: url(https://cmitoa.chinamobilesz.com:9110/static/img/courseBackground.png) 0 0 no-repeat;background-size: 100% 100%; */
}
/* 保存到手机 */
.saveBtn {
display: block;
width: 60%;
height: 88rpx;
padding: 0;
line-height: 88rpx;
text-align: center;
position: fixed;
bottom: 413rpx;
left: 20%;
background: #ff5b89;
color: #fff;
font-size: 30rpx;
border-radius: 44rpx;
z-index: 11;
}
/* 底部提醒 */
.remind {
position: fixed;
bottom: 330rpx;
color: #ff5b89;
font-size: 20rpx;
z-index: 11;
text-align: center;
width: 100%;
}
/* 关闭按钮 */
.imagePathBox .close {
display: block;
width: 76rpx;
height: 76rpx;
position: fixed;
bottom: 130rpx;
left: 331rpx;
}
.imagePathBox .close image {
width: 100%;
height: 100%;
}