問題
最近在開發小程式頁面時,遇到了個頭像清單的子產品,設計稿效果如下圖所示。初看效果圖,似乎很簡單,設定圓形邊界外加每個頭像左偏移,壓蓋上一個頭像就可以了。但仔細觀察就會發現頭像之間還有部分的間隔,關鍵是這部分間隔還是透明的。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICN4ETMfdHLkVGepZ2XtxSZ6l2clJ3LcV2Zh1Wa9M3clN2byBXLzN3btgHL9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsQTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5CNwMjN3YmM1UzY3EGO3MGMzYzXzIDOyYTM5IzLchDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
實作
經過多種嘗試,每個頭像的缺失部分,無法通過壓蓋來實作,也無法通過單純的
CSS
樣式來實作。容易想到的一種思路是通過
canvas
來實作,即通過
canvas
來完成每個頭像的裁剪,然後通過偏移将頭像間距調整到合适的位置。每個頭像的裁剪示意圖如下圖所示:
使用
web
技術實作的核心代碼如下:
// html
<canvas style="width: 200px; height: 200px"></canvas>
// js
const canvasElm = document.querySelector("canvas");
const ctx = canvasElm.getContext("2d");
const img = new Image();
img.src ="/image/url/path";
img.onload = () => {
// 根據canvas大小計算圓形區域的半徑
const r = canvasElm.clientWidth / 2;
// 設定canvas畫布的大小
canvasElm.width = 2 * r;
canvasElm.height = 2 * r;
ctx.save();
// 設定圓形裁選區
ctx.beginPath();
ctx.arc(r, r, r, 2 * Math.PI, false);
ctx.clip();
// 繪制圖檔,隻有落在裁選區的内容被顯示
ctx.drawImage(img, 0, 0, 2 * r, 2 * r);
ctx.restore();
// 設定新的裁選區
ctx.beginPath();
ctx.arc(2.4 * r, r, r, 2 * Math.PI, false);
ctx.clip();
// 隻有落在裁選區的内容被清空
ctx.clearRect(0, 0, 2 * r, 2 * r);
};