使用canvas进行截图,就是在canvas画布上把想要的东西画一遍然后保存成图片。
如果是线上图片要使用wx.getImageInfo进行转换再显示在canvas上
wxml:
<view class="canvas-box" >
<canvas
type="2d"
id="canvas"
style='width:100%; height:350px'
></canvas>
</view>
<view>
<button class="confirm" bindtap="saveImg">保存</button>
</view>
wxss:
/* pages/result/result.wxss */
.result-text {
text-align: center;
margin-top: 10rpx;
}
.confirm {
border: 1rpx;
margin: 20rpx auto;
text-align: center;
background-color: #ccc;
}
.confirm-img {
width: 200rpx;
height: 200rpx;
}
.canvas-box {
width: 100%;
margin-top: 25rpx;
}
.list {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
font-size: 32rpx;
padding: 10rpx;
}
js:
// pages/result/result.js
Page({
/**
* 页面的初始数据
*/
data: {
showCanvas: true,
screenWidth: 0,
screenHeight: 0,
imgUrl: './submit.png',
list: [{
title: '姓名',
content: '张三'
},
{
title: '性别',
content: '男'
},
{
title: '证件类型',
content: '身份证'
},
{
title: '证件号码',
content: '1234567890'
},
{
title: '联系地址',
content: '的各个省份的就士大夫顺丰速递是不是跟你说的'
},
{
title: '邮政编码',
content: '111111'
},
],
canvasHeight: 0
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
let that = this
let canvas = null;
const dpr = wx.getSystemInfoSync().pixelRatio
const rpx = wx.getSystemInfoSync().windowWidth
// canvas定位都是以px为单位
// rpx转换为px:
// rpx单位大小 / 750 * wx.getSystemInfoSync().windowWidth = px单位大小
let xMargin = 10 / 750 * rpx //画布侧边距
let yMargin = 20 / 750 * rpx //画布上下边距
let lMargin = 10 / 750 * rpx + 2 //行距
let textSize = parseInt(32 / 750 * rpx) //字体大小
const textWidth = parseInt((398 / 750) * rpx); // 列表定宽,超出换行显示
const secondLineHeight = parseInt((38 / 750) * rpx); // 一行超出,第二行多出的高度
let imgWidth = parseInt(200 / 750 * rpx) //图片宽
let imgHeight = parseInt(200 / 750 * rpx) //图片高
let imgMarginTop = 20 / 750 * rpx + 2 //图片高
wx.createSelectorQuery()
.select('#canvas')
.fields({
node: true,
size: true
})
.exec(async (res) => {
canvas = res[0].node;
const ctx = canvas.getContext('2d');
//画布大小根据屏幕分辨率进行缩放,防止模糊
canvas.width = res[0].width * dpr
canvas.height = res[0].height * dpr
ctx.scale(dpr, dpr)
//画布背景色
ctx.fillStyle = "pink";
ctx.fillRect(0, 0, canvas.width, canvas.height)
//画图片
const canvasImg = canvas.createImage()
canvasImg.src = that.data.imgUrl
let canvasImgPo = await new Promise((resolve, reject) => {
canvasImg.onload = () => {
resolve(canvasImg)
}
canvasImg.onerror = (e) => {
reject(e)
}
});
let imgCenter = rpx / 2 - imgWidth / 2 //图片居中显示
ctx.drawImage(canvasImgPo, imgCenter, imgMarginTop, imgWidth, imgHeight);
//画文字样式
ctx.textBaseline = "top";
ctx.font = `${textSize}px none`;
// 左边标题
function getTextLeft() {
ctx.textAlign = 'left';
ctx.fillStyle = '#666666';
}
// 右边对应内容
function getTextRight() {
ctx.fillStyle = '#262626';
ctx.textAlign = 'right';
}
let allLines = 0; // 共有几个个多行数据
let linesCount = 0; // 多行数据的行数总和
//左侧文字
that.data.list.map((item, index) => {
const addLine = linesCount - allLines; // 除正常单行外多出来的行数
let lineWidth = 0; // 字符串的长度px
let lastIdx = 0; // 截取字符串的下标
let itemLineCount = 0; // 单个数据的行数
let listHeight = yMargin + imgHeight + imgMarginTop + (textSize + lMargin * 2) * index
// 如果内容长度超过规定的398rpx,就换行显示
if (ctx.measureText(item.content).width >= textWidth) {
for (let i = 0; i < item.content.length; i++) {
lineWidth += ctx.measureText(item.content[i]).width
if (lineWidth >= textWidth) {
getTextRight();
ctx.fillText(item.content.substring(lastIdx, i), (rpx - xMargin), listHeight + addLine * secondLineHeight + secondLineHeight * itemLineCount);
lastIdx = i;
itemLineCount++;
linesCount++;
lineWidth = 0;
}
if (i === item.content.length - 1) {
getTextRight();
ctx.fillText(
item.content.substring(lastIdx, i + 1),
(rpx - xMargin),
listHeight + addLine * secondLineHeight + secondLineHeight * itemLineCount,
);
linesCount++;
itemLineCount++;
}
}
getTextLeft();
ctx.fillText(item.title, xMargin, listHeight + addLine * secondLineHeight);
allLines++;
}else{
listHeight += secondLineHeight * addLine;
getTextRight();
ctx.fillText(item.content, (rpx - xMargin), listHeight);
getTextLeft();
ctx.fillText(item.title, xMargin, listHeight);
}
})
})
},
async saveImg() {
const query = wx.createSelectorQuery();
const canvasObj = await new Promise((resolve, reject) => {
query.select('#canvas')
.fields({
node: true,
size: true
})
.exec(async (res) => {
resolve(res[0].node);
})
});
wx.canvasToTempFilePath({
canvas: canvasObj, //现在的写法
success: (res) => {
//保存图片
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: function (data) {
wx.showToast({
title: '已保存到相册',
icon: 'success',
duration: 2000
})
},
fail: function (err) {
console.log('fff')
if (err.errMsg === "saveImageToPhotosAlbum:fail:auth denied" || err.errMsg === "saveImageToPhotosAlbum:fail auth deny" || err.errMsg === "saveImageToPhotosAlbum:fail authorize no response") {
wx.showModal({
title: '提示',
content: '需要您授权保存相册',
showCancel: false,
success: modalSuccess => {
wx.openSetting({
success(settingdata) {
if (settingdata.authSetting['scope.writePhotosAlbum']) {
// wx.showModal({
// title: '提示',
// content: '获取权限成功,再次点击图片即可保存',
// showCancel: false,
// })
} else {
wx.showModal({
title: '提示',
content: '获取权限失败',
showCancel: false,
})
}
},
fail(failData) {
console.log("failData", failData)
},
complete(finishData) {
console.log("finishData", finishData)
}
})
}
})
} else {
wx.showToast({
title: '请保存图片',
icon: 'none',
duration: 2000
})
}
},
complete(res) {
console.log('com');
}
})
},
fail(res) {
console.log('fail');
}
}, this)
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})