data () {
return {
rpx :1
}
}
/** 获取屏幕额宽高 */
let menuButtonObject = wx.getMenuButtonBoundingClientRect();
wx.getSystemInfo({
success: res => {
this.rpx = res.windowWidth / 375;
let statusBarHeight = res.statusBarHeight;
this.navHeight =
statusBarHeight +
menuButtonObject.height +
(menuButtonObject.top - statusBarHeight) * 2; // 导航高度
this.screenWidth = res.screenWidth;
this.screenHeight = res.screenHeight - this.navHeight;
}
});
<canvas canvas-id="mycanvas" :style="{width:screenWidth+'px',height:screenHeight+'px'}" />
this.screenHeight就是屏幕有效区域的高度
this.rpx就是自适应的值,由于canvas绘制位置的时候,都有宽高,你只需要*this.rpx,就会自适应宽高了
/** 换行 */
async lineFend (txt, context, height) {
var text = txt;
var chr = text.split(''); // 这个方法是将一个字符串分割成字符串数组
var temp = '';
var row = [];
context.setFontSize(11 * this.rpx);
context.setFillStyle('#000');
for (var a = 0; a < chr.length; a++) {
/**拿到文字的宽度*/
if (context.measureText(temp).width < 300) {
temp += chr[a];
} else {
a--; // 这里添加了a-- 是为了防止字符丢失,效果图中有对比
row.push(temp);
temp = '';
}
}
row.push(temp);
// 如果数组长度大于2 则截取前两个
if (row.length > 2) {
var rowCut = row.slice(0, 2);
var rowPart = rowCut[1];
var test = '';
var empty = [];
for (let a = 0; a < rowPart.length; a++) {
if (context.measureText(test).width < 280) {
test += rowPart[a];
} else {
break;
}
}
empty.push(test);
var group = empty[0] + '...'; // 这里只显示两行,超出的用...表示
rowCut.splice(1, 1, group);
row = rowCut;
}
for (let b = 0; b < row.length; b++) {
context.fillText(
row[b],
50 * this.rpx,
(height + b * 20) * this.rpx,
280 * this.rpx
);
}
},
用法例子
var context = wx.createCanvasContext('mycanvas');
context.setFontSize(11 * this.rpx);
context.setFillStyle('#000');
context.setTextAlign('left');
context.fillText(
`证件号码为:${this.res.certificateNumber}`,
50 * this.rpx,
(190 + this.height) * this.rpx
);
context.stroke();
(注意:如果多张网络需要循环下载,待最后一直)
// 将canvas转换为图片保存到本地,然后将图片路径传给image图片的src
canvasImgs() {
var arr = [this.userInfo.headImg, this.userInfo.qrCode];//接口中的图片地址
for (let i = 0; i < arr.length; i++) {
wx.downloadFile({
url: arr[i],
success: res => {
setTimeout(() => {
this.array.push(res.tempFilePath);
if (this.array.length === 2) {
this.createNewImg();//绘制canvas的方法
}
}, 500);
}
});
}
},
// 绘制成圆角
/**r是圆的半径*/
circleImg(ctx, img, x, y, r) {
ctx.fill();//第一次没加此处,绘制圆后,超出的部门没有隐藏
ctx.save();
ctx.beginPath(); //开始创建一个路径
var d = 2 * r;
var cx = x + r;
var cy = y + r;
ctx.arc(cx, cy, r, 0, 2 * Math.PI);
ctx.clip();
ctx.drawImage(img, x, y, d, d);
ctx.restore(); //恢复之前保存的绘图上下文
ctx.draw();
// ctx.restore();
},
注意:如果取消保存后,要重新打开相册权限功能
/*
* 保存到相册
*/
<span @click="tosave">保存到相册</span>
// 重新保存图片
tosave: function() {
var that = this;
/** 检测用户是否授权**/
wx.getSetting({
success: function(res) {
/** 授权,则调用相册**/
if (res.authSetting["scope.writePhotosAlbum"] === true) {
that.saveimg();
} else if (res.authSetting["scope.writePhotosAlbum"] === false) {
/** 未授权,则打开授权页面,让用户授权**/
wx.openSetting({
success: res => {
/** 授权成功,则保存图片,失败则不保存**/
if (res.authSetting["scope.writePhotosAlbum"] === true) {
that.saveimg();
}
}
});
} else {
that.saveimg();
}
},
fail: function(res) {
console.log("打开设置失败", res);
}
});
},
// 保存图片到相册
saveimg: function() {
var _that = this;
wx.saveImageToPhotosAlbum({
filePath: _that.tempFilePath,
success(res) {
wx.showToast({
title: "已保存到相册"
});
},
fail(res) {}
});
}
最后附上我的代码和效果图(此canvas没有用到上述第二条)
<template>
<div class="code-box">
<div class="head-box">
<div class="page-title">我的积分</div>
<div class="back-bt" @click="back"></div>
</div>
<div class="code-image">
<img src="/static/images/code-box.png" class="code-bg" />
<div class="head-box">
<image :src="userInfo.headImg" />
<span>{{nickName}}</span>
</div>
<div class="code">
<img :src="userInfo.qrCode" alt />
</div>
</div>
<!-- <img :src="tempFilePath" class="canvasImg" alt /> -->
<canvas
canvas-id="mycanvas"
class="mycanvas"
:style="{width:screenWidth+'px',height:screenHeight+'px'}"
/>
<div class="download">
<img src="/static/images/download-icon.png" alt />
<span @click="tosave">保存到相册</span>
</div>
</div>
</template>
<script>
export default {
data() {
return {
hide: true,
rpx: 1,
tempFilePath: "",
screenWidth: "",
screenHeight: "",
navHeight: null,
canvasHeight: null,
id: null,
res: null,
height: null,
productHeigth: 0,
priceHeigth: 0,
photoUrl: "",
nickName: "",
userInfo: {},
array: []
};
},
mounted() {
const data = wx.getStorageSync("userInfo");
this.userInfo = data;
this.nickName = data.nickName;
/**网络图片循环 */
this.map();
},
methods: {
back() {
wx.navigateBack({});
},
// 绘制成圆角
circleImg(ctx, img, x, y, r) {
ctx.fill();
ctx.save();
ctx.beginPath(); //开始创建一个路径
var d = 2 * r;
var cx = x + r;
var cy = y + r;
ctx.arc(cx, cy, r, 0, 2 * Math.PI);
ctx.clip();
ctx.drawImage(img, x, y, d, d);
ctx.restore(); //恢复之前保存的绘图上下文
ctx.draw();
// ctx.restore();
},
// 将canvas转换为图片保存到本地,然后将图片路径传给image图片的src
map() {
var arr = [this.userInfo.headImg, this.userInfo.qrCode];
for (let i = 0; i < arr.length; i++) {
wx.downloadFile({
url: arr[i],
success: res => {
setTimeout(() => {
this.array.push(res.tempFilePath);
if (this.array.length === 2) {
this.createNewImg();
}
}, 500);
}
});
}
},
createNewImg() {
/** 获取屏幕额宽高 */
let menuButtonObject = wx.getMenuButtonBoundingClientRect();
wx.getSystemInfo({
success: res => {
this.rpx = res.windowWidth / 375;
let statusBarHeight = res.statusBarHeight;
this.navHeight =
statusBarHeight +
menuButtonObject.height +
(menuButtonObject.top - statusBarHeight) * 2; // 导航高度
this.screenWidth = res.screenWidth;
this.screenHeight = res.screenHeight - this.navHeight;
}
});
console.log(this.screenWidth, this.screenHeight);
var context = wx.createCanvasContext("mycanvas");
context.setFillStyle("#DDC1A7");
context.fillRect(0, 0, this.screenWidth, this.screenHeight);
// wx.downloadFile({
// url: img,
// success: res => {
// console.log(res, "uuuuuuuuuuuu");
// var imgUrl = res.tempFilePath;
var path1 = "/static/images/code-box.png";
wx.getImageInfo({
src: path1,
success: item => {
console.log(item, "ttttttt");
console.log(this.screenWidth, this.screenHeight);
context.drawImage(
path1,
18 * this.rpx,
52 * this.rpx,
339 * this.rpx,
443 * this.rpx
);
// 绘制头像
var path2 = this.userInfo.headImg;
this.circleImg(
context,
this.array[0],
148 * this.rpx,
40 * this.rpx,
40 * this.rpx
);
// 绘制标语
var textWidth =
(this.screenWidth - context.measureText(this.nickName).width) / 2;
context.setFontSize(16 * this.rpx);
context.setFillStyle("#0B0707");
context.fillText(
`${this.nickName}`,
textWidth * this.rpx,
147 * this.rpx
);
context.stroke();
var path3 = this.userInfo.qrCode;
context.drawImage(
this.array[1],
88 * this.rpx,
240 * this.rpx,
200 * this.rpx,
200 * this.rpx
);
var that = this;
context.draw(
true,
setTimeout(function() {
// 将生成好的图片保存到本地,需要延迟一会,绘制期间耗时
wx.canvasToTempFilePath({
x: 0,
y: 0,
fileType: "jpg",
quality: 0.8,
canvasId: "mycanvas",
success: function(res) {
console.log(res.tempFilePath, "[[[[[[[[[[[[[[[[[[[[[[");
// var tempFilePath = res.tempFilePath;
wx.hideLoading();
that.tempFilePath = res.tempFilePath;
that.hide = false;
},
fail: function(res) {
console.log(res);
}
});
}, 200)
);
},
fail: function(fres) {}
});
// }
// });
},
/*
* 保存到相册
*/
// 重新保存图片
tosave: function() {
var that = this;
/** 检测用户是否授权**/
wx.getSetting({
success: function(res) {
/** 授权,则调用相册**/
if (res.authSetting["scope.writePhotosAlbum"] === true) {
that.saveimg();
} else if (res.authSetting["scope.writePhotosAlbum"] === false) {
/** 未授权,则打开授权页面,让用户授权**/
wx.openSetting({
success: res => {
/** 授权成功,则保存图片,失败则不保存**/
if (res.authSetting["scope.writePhotosAlbum"] === true) {
that.saveimg();
}
}
});
} else {
that.saveimg();
}
},
fail: function(res) {
console.log("打开设置失败", res);
}
});
},
// 保存图片到相册
saveimg: function() {
var _that = this;
wx.saveImageToPhotosAlbum({
filePath: _that.tempFilePath,
success(res) {
wx.showToast({
title: "已保存到相册"
});
},
fail(res) {}
});
}
},
created() {}
};
</script>
<style scoped lang="less">
.mycanvas {
position: fixed;
left: 2000px;
}
.code-box {
width: 100%;
height: 100%;
display: flex;
align-items: center;
flex-direction: column;
background: linear-gradient(
107deg,
rgba(221, 193, 167, 1) 0%,
rgba(242, 231, 219, 1) 100%
);
.canvasImg {
width: 100%;
height: 100%;
position: fixed;
top: -50px;
left: 0;
z-index: 99;
}
.head-box {
width: 100%;
height: 75px;
position: relative;
.back-bt {
width: 10px;
height: 10px;
border-bottom: 2px solid #333333;
border-right: 2px solid #333333;
position: absolute;
top: 45px;
left: 20px;
z-index: 100;
transform: rotate(135deg);
}
.page-title {
position: absolute;
top: 40px;
font-size: 17px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 700;
color: rgba(51, 51, 51, 1);
text-align: center;
width: 100%;
}
}
.code-image {
width: 339px;
height: 434px;
position: relative;
margin-top: 60px;
.code {
position: absolute;
bottom: 44px;
width: 100%;
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
img {
width: 200px;
height: 200px;
}
}
.code-bg {
width: 100%;
height: 100%;
position: absolute;
}
.head-box {
position: absolute;
top: -25px;
width: 100%;
height: 150px;
display: flex;
align-items: center;
z-index: 1000;
flex-direction: column;
image {
width: 80px;
height: 80px;
border-radius: 50%;
border: solid 5px #ffffff;
}
span {
height: 22px;
font-size: 16px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 700;
color: rgba(11, 7, 7, 1);
line-height: 22px;
margin-top: 15px;
}
}
}
.download {
display: flex;
align-items: center;
margin-top: 20px;
img {
width: 16px;
height: 16px;
}
span {
height: 24px;
font-size: 15px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 700;
color: rgba(11, 7, 7, 1);
line-height: 21px;
margin-left: 10px;
}
}
}
</style>