用cancas画名片 涉及到技术 原型头像、文字超出换行、字体大小颜色、背景图
wxml 页面内容
<view class="pages"> <canvas canvas-id="shareKapian" style="width:{{width}}px;height:{{height}}px;"></canvas> </view>
wxjs内容
其中如果需要用到线上图片需要通过localImge 函数将线上路径转为本地路径方可。
一共分为几个步骤 先开机相机权限canvasKapian、然后开始绘制名片canvasClick、最后下载名片downFn。
Page({ data: { width: 320, height: 300, isDisable: false,//防止多次点击 }, onLoad: function (options) { this.canvasKapian(); }, //绘制名片 canvasKapian() { wx.getSetting({ success: res => { console.log(res); if (!res.authSetting[‘scope.writePhotosAlbum‘]) { wx.authorize({ scope: ‘scope.writePhotosAlbum‘, success: res => { this.canvasClick(); }, fail: err => { wx.showModal({ title: "提示", content: ‘图片保存失败,您需要开启相册权限并且重新保存,是否开启?‘, success: res => { if (res.confirm) { wx.openSetting({ success: (res) => { if (res.authSetting[‘scope.writePhotosAlbum‘]) { this.canvasClick(); } else { wx.showToast({ title: ‘获取权限失败,无法使用保存图片或视频到您的相册‘, icon: ‘none‘ }) } }, }) } } }) } }) } else { this.canvasClick(); } } }) }, canvasClick() { this.setData({ isDisable: true }) wx.showLoading({ title: ‘名片生成中...‘, }) // let image1 = this.localImge(this.data.background); // let image2 = this.localImge(this.data.wxCode); // let image3 = this.localImge(this.data.headerImg); // Promise.all([image1, image2, image3]).then(res => { // let background1 = res[0]; // let wxCode1 = res[1]; // let headerImg1 = res[2]; const ctx = wx.createCanvasContext("shareKapian"); ctx.setFillStyle("#22DDB8"); //背景色 // 背景图 ctx.drawImage(‘../../image/bc.jpg‘, 0, 0, this.data.width, this.data.height); ctx.fillRect(0, 0, this.data.width, this.data.height); let top = 30; let left = 30; // 头像 this.circleImg(ctx, ‘../../image/bc.jpg‘, left, top, 20) //活动 ctx.fillStyle="#9B712E"; ctx.setFontSize(18); ctx.font = ‘bold‘; ctx.fillText(‘bingxiaoxiao‘, left + 50, top); // 介绍 ctx.setFontSize(14); this.drawText(ctx, ‘2020年7月24日上午,中国外交部通知美国驻华使馆,中方决定撤销对美国驻成都总领事馆的设立和运行许可,并对该总领事馆停止一切业务和活动提出具体要求。‘, left + 50, top + 25 , 0, 135) ctx.draw(false, () => { wx.canvasToTempFilePath({ canvasId: "shareKapian", success: res => { wx.hideLoading(); this.setData({ catShopUrl: res.tempFilePath }); this.downFn(); }, fail: err => { console.log(‘生成失败‘, err); } }); }); // }).catch(err => { // console.log(err); // wx.hideLoading(); // wx.showToast({ // title: ‘图片加载失败,请返回重试‘, // icon: ‘none‘ // }) // }) }, //保存图片 downFn() { let imgurl = ‘‘; wx.showLoading({ title: ‘保存中...‘, }) imgurl = this.data.catShopUrl; wx.saveImageToPhotosAlbum({ filePath: imgurl, success: res => { wx.hideLoading() wx.showToast({ title: "保存成功,从相册中分享到朋友圈吧", icon: "none", duration: 4000 }); this.setData({ isDisable: false }) }, fail: function (err) { console.log(err) if (err.errMsg === "saveImageToPhotosAlbum:fail:auth denied" || err.errMsg === "saveImageToPhotosAlbum:fail auth deny") { wx.hideLoading(); wx.showModal({ title: "提示", content: ‘图片保存失败,您需要开启相册权限并且重新保存,是否开启?‘, success: res => { if (res.confirm) { wx.openSetting({ complete: (res) => { console.log(res); }, }) } } }) } } }); }, //生成本地图片 localImge: function (src) { console.log(‘src‘, src); return new Promise(function (resolve, reject) { wx.downloadFile({ url: src, success: function (res) { resolve(res.tempFilePath); }, fail: err => { reject(err) } }); }); }, // 超出换行 drawText: function (ctx, str, leftWidth, initHeight, titleHeight, canvasWidth) { var lineWidth = 0; var 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 += 16; //16为字体的高度防止文字重叠 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 }, // 圆形图片 circleImg: function (ctx, img, x, y, r) { 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() }, })