微信小程序繪制分享圖例子:
demo下載地址:https://gitee.com/v-Xie/wxCanvasShar
大致代碼會再以下說明
基礎知識點:
了解canvas基礎知識
wx.createCanvasContext()//微信小程序創建畫布
wx.canvasToTempFilePath()//將畫布canvas轉為圖片
wx.saveImageToPhotosAlbum() //微信小程序保存至相冊
canvas繪制以及繪制過程中的坑:(請看后面的代碼部分)
1.繪制頭像后之后繪制的內容不顯示
2.頭像地址換成網絡地址后無法顯示
3.實現多行文本換行並且獲取繪制的文本的高度
<!--index.wxml--> <view class="container"> <!-- 畫布 --> <!-- canvas --> <canvas canvas-id="myCanvas" style="width:300px;height:320px;position:fixed;top:40px;"></canvas> <!-- 要保存至相冊的圖片 --> <view class='imagePathBox'> <text>要分享的圖片</text> <image src="{{imagePath}}"></image> </view> <button bindlongpress='baocun'>長按保存分享</button> </view>
//index.js const app = getApp() Page({ data: { imagePath:'', imgurl:'https://aecpm.alicdn.com/simba/img/TB1p4s3GVXXXXb6XVXXSutbFXXX.jpg' }, onLoad: function() { // 調用畫布 // this.createNewImg(); var self=this; wx.downloadFile({ url: self.data.imgurl, success: function (res) { // 只要服務器有響應數據,就會把響應內容寫入文件並進入 success 回調,業務需要自行判斷是否下載到了想要的內容 if (res.statusCode === 200) { console.log(res, "rrrr") self.setData({ imgurl: res.tempFilePath }) console.log('頭像臨時路徑====='); console.log(self.data.imgurl); // self.createNewImg(); // 調用canvas繪制的結果圖 } } }) setTimeout(function(){ self.createNewImg(); },500); }, /* 繪制圓行頭像 clip()從原始畫布中剪切任意形狀和尺寸。 坑點:1.繪制頭像后之后繪制的內容不顯示 2.頭像地址換成網絡地址以后無效 提示:一旦剪切了某個區域,則所有之后的繪圖都會被限制在被剪切的區域內(不能訪問畫布上的其他區域)。 解決方案:坑1: 原因:clip()造成 解決方案:可在使用 clip() 方法前通過使用 save() 方法對當前畫布區域進行保存, 並在以后的任意時間通過 restore() 方法對其進行恢復 坑2: 原因:1.未將網絡地址轉換為臨時路徑 2.未配置download選項的合法域名 解決方案:wx.downloadFile()實現臨時路徑轉換,並配置合法域名 */ circleImg(ctx, img, x, y, r) { ctx.save(); 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.fillText('文本','文本的左上角x坐標位置','文本的左上角y坐標位置'); startXpoint:文本左上角x坐標位置 startYpoint:左上角y坐標位置 textHeight:文本與頂部基線距離[文本高度] canvasWidth:畫布大小 fontSize:文本字體大小 lineHeight:行高 */ drawText(ctx, str, startXpoint, startYpoint, textHeight, canvasWidth, fontSize, lineHeight) { var textWidth = 0; var lastSubStrIndex = 0; //每次開始截取的字符串的索引 for (let i = 0; i < str.length; i++) { textWidth += ctx.measureText(str[i]).width; if (textWidth > canvasWidth) { ctx.font = "normal 14px Arial"; ctx.fillStyle = 'green'; ctx.fillText(str.substring(lastSubStrIndex, i), startXpoint, startYpoint); //繪制截取部分 startYpoint += fontSize; //16為字體的高度 textWidth = 0; lastSubStrIndex = i; textHeight += lineHeight; } if (i == str.length - 1) { //繪制剩余部分 ctx.fillText(str.substring(lastSubStrIndex, i + 1), startXpoint, startYpoint); } } // 繪制后文本的高度 return textHeight }, /* 1.繪制畫布 2.將canvas轉換為圖片保存到本地,然后將圖片路徑傳給image圖片的src */ createNewImg: function () { var self = this; var ctx = wx.createCanvasContext('myCanvas'); // 初始要畫一個相當於畫布大小的容器 //設計稿分享圖多大,畫布就多大 ctx.strokeStyle = "#ccc"; ctx.strokeRect(0, 0, 300, 320); //繪制矩形 //語法:填充型fillRect(x,y,w,h) 或 描邊型strokeRect(x,y,w,h) x,y坐標起點 w:矩形寬度 h:矩形高度 ctx.fillStyle = "#FF0000"; ctx.fillRect(20, 20, 50, 40); ctx.strokeStyle = "blue"; ctx.strokeRect(140, 20, 50, 40); //繪制線條 //語法:moveTo(x,y)線條起始坐標 (同樣可以用來改變畫筆的起始坐標點) lineTo(x,y);線條結束坐標 ctx.moveTo(20, 80); ctx.lineTo(200, 100); ctx.textWidth = 10;//線條寬度 ctx.lineCap = 'round'//lineCap 線段端點顯示的樣子 ,值為butt,round 和 square。默認是 butt ctx.strokeStyle = "green"; ctx.stroke(); //繪制圓 //語法:arc(x,y,r,start,stop) x,y圓心中心點坐標 r:半徑 start: 起始角度 stop:結束角度 ctx.beginPath();//重新創建路徑 ctx.arc(40, 130, 30, 0, 2 * Math.PI); ctx.strokeStyle = "purple"; ctx.textWidth = 4;//描邊寬度 ctx.fillStyle = "red"; ctx.fill(); ctx.stroke(); //繪制文本 //語法:fillText(text, x, y, [maxWidth]) strokeText(text, x, y, [maxWidth]) ctx.font = "normal 18px Arial"; ctx.textAlign = 'center'; ctx.textBaseline = 'bottom'; ctx.fillStyle = 'blue'; ctx.fillText("繪制文本", 120, 140); ctx.strokeText("繪制文本", 120, 170);//沒有設置新的strokeStyle或textWidth等時會自動繼承上一個strokeStyle或textWidth等 // ctx.textWidth = 1;//strokeStyle或textWidth // ctx.strokeStyle = "green"; ctx.strokeText("繪制文本", 120, 200); var img='../../images/2.jpg'; ctx.drawImage(img, 10, 170, 60, 70); ctx.fillStyle = 'red'; this.circleImg(ctx,img,200,20,40); ctx.fillText("繼續啊", 240, 140); ctx.drawImage(self.data.imgurl, 180, 150, 100, 80); var text ="把握大好時機,認真理性投資。用自己的才華和智慧積極進取。把握大好時機,認真理性投資。用自己的才華和智慧積極進取。"; self.drawText(ctx, text, 160, 260, 0, 260, 14, 0); ctx.save(); // 保存當前ctx的狀態 ctx.restore(); ctx.draw(); setTimeout(function () { wx.canvasToTempFilePath({ x: 0, y: 0, width: 300, height: 320, destWidth: 300 * 2,//生成圖片的大小設置成canvas大小的二倍解決模糊 destHeight: 320 * 2, canvasId: 'myCanvas', success: function (res) { var tempFilePath = res.tempFilePath; self.setData({ imagePath: tempFilePath }); wx.hideToast(); console.log('canvas圖片地址:' + self.data.imagePath); } }); }, 600); }, //點擊保存到相冊 baocun: function () { var self = this; wx.saveImageToPhotosAlbum({ filePath: self.data.imagePath, success(res) { wx.showModal({ content: '圖片已保存到相冊,趕緊曬一下吧~', showCancel: false, confirmText: '好的', confirmColor: '#333', success: function (res) { if (res.confirm) { console.log('用戶點擊確定'); } }, fail: function (res) { console.log(res) } }) } }) }, })