前言
在 Canvas 中我們常常遇到的一個需求 繪制一個圓形或者一個圓角矩形圖像,常用於展示用戶頭像,我們知道 CSS 有 border-radius 屬性,但是 Canvas 是沒有的~😂
很尷尬,我們就來瞅瞅怎么整出一個圓形頭像~
Part.1 效果
圓形頭像
圓角矩形
Part.2 原理
首先,制作圓形和圓角矩形並不是一個方法,但是都大同小異~
圓形使用的是:arc()
圓角使用的是:arcTo()
圓形:利用 Canvas 先畫出一個圓形,然后將圖片定位到圓形中心位置進行剪切,將超出圓形的部分去掉,就會形成一個圓形
圓角:利用 Canvas 先畫出一個圓角矩形,然后將圖片定位到圓角矩形位置進行剪切,將超出圓形的部分去掉,就會形成一個圓角矩形
區別在於,圓角需要我們一段一段的自己畫出來,而圓形有現成的方法只用設置想要的值即可
Part.3 代碼展示
HTML
1 <template> 2 <view class="layout"> 3 <view class="layout-header"> 4 <canvas canvas-id="myCanvas" class="header-canvas"></canvas> 5 </view> 6 </view> 7 </template>
JS
1 <script> 2 export default { 3 onLoad() { 4 uni.showLoading({ 5 title: '我正在努力...', 6 mask: true 7 }); 8 9 // 開始制作頭像 10 this.createPlacard() 11 }, 12 methods: { 13 // 開始制作頭像 14 createPlacard() { 15 uni.getImageInfo({ 16 src: 'https://pic.liesio.com/2020/07/02/e0eb38388da1c.jpg', // 網絡圖片需先下載,得到臨時本地路徑,否則繪入 Canvas 可能會出現空白 17 success: (img)=> { 18 const ctx = wx.createCanvasContext('myCanvas', this); 19 ctx.fillStyle = "#FFFFFF"; 20 ctx.fillRect(0, 0, uni.upx2px(750), uni.upx2px(1000)); 21 22 // 如何在 Canvas 中繪入圓形圖片? 23 // 原理:利用 Canvas 先畫出一個圓形,然后將圖片定位到圓形中心位置進行剪切,將超出圓形的部分去掉,就會形成一個圓形 24 this.circleImgOne(ctx, img.path, uni.upx2px(175), uni.upx2px(95), uni.upx2px(200)); 25 26 // 如何在 Canvas 中繪入圓角矩形? 27 // 原理:利用 Canvas 先畫出一個圓角矩形,然后將圖片定位到圓角矩形位置進行剪切,將超出圓形的部分去掉,就會形成一個圓角矩形 28 //this.circleImgTwo(ctx, img.path, uni.upx2px(105), uni.upx2px(95), uni.upx2px(512), uni.upx2px(382), uni.upx2px(20)); 29 30 ctx.draw(); 31 uni.hideLoading() 32 } 33 }) 34 }, 35 36 /* 37 * 參數說明 38 * ctx Canvas實例 39 * img 圖片地址 40 * x x軸坐標 41 * y y軸坐標 42 * r 圓形半徑 43 */ 44 circleImgOne(ctx, img, x, y, r) { 45 // 如果在繪制圖片之后還有需要繪制別的元素,需啟動 save() 、restore() 方法,否則 clip() 方法會導致之后元素都不可見 46 // save():保存當前 Canvas 畫布狀態 47 // restore():恢復到保存時的狀態 48 49 /* ctx.save(); */ 50 let d = r * 2; 51 let cx = x + r; 52 let cy = y + r; 53 ctx.arc(cx, cy, r, 0, 2 * Math.PI); 54 ctx.strokeStyle = '#FFFFFF'; // 設置繪制圓形邊框的顏色 55 ctx.stroke(); // 繪制出圓形,默認為黑色,可通過 ctx.strokeStyle = '#FFFFFF', 設置想要的顏色 56 ctx.clip(); 57 ctx.drawImage(img, x, y, d, d); 58 /* ctx.restore(); */ 59 }, 60 61 /* 62 * 參數說明 63 * ctx Canvas實例 64 * img 圖片地址 65 * x x軸坐標 66 * y y軸坐標 67 * w 寬度 68 * h 高度 69 * r 弧度大小 70 */ 71 circleImgTwo(ctx, img, x, y, w, h, r) { 72 // 畫一個圖形 73 if (w < 2 * r) r = w / 2; 74 if (h < 2 * r) r = h / 2; 75 ctx.beginPath(); 76 ctx.moveTo(x + r, y); 77 ctx.arcTo(x + w, y, x + w, y + h, r); 78 ctx.arcTo(x + w, y + h, x, y + h, r); 79 ctx.arcTo(x, y + h, x, y, r); 80 ctx.arcTo(x, y, x + w, y, r); 81 ctx.closePath(); 82 ctx.strokeStyle = '#FFFFFF'; // 設置繪制圓形邊框的顏色 83 ctx.stroke(); 84 ctx.clip(); 85 ctx.drawImage(img, x, y, w, h); 86 } 87 } 88 } 89 </script>
CSS
1 <style lang="scss" scoped> 2 .layout { 3 .layout-header { 4 width: 750upx; 5 background:rgba(255,255,255,1); 6 .header-canvas { 7 width: 750upx; 8 height: 700upx; 9 box-shadow:0 5upx 16upx 0 rgba(20,104,255,0.07); 10 } 11 } 12 } 13 </style>