原代碼用 document.createElement('span') 搞幾百個點拼圓,再想設置背景色極其反模式。直接用 Canvas 2D API 一行搞定。
<canvas id="myCanvas" width="800" height="600">瀏覽器不支持 Canvas</canvas>
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// 繪製實心圓:中心(400,300),半徑100,填充色藍色,邊框紅色
ctx.beginPath();
ctx.arc(400, 300, 100, 0, Math.PI * 2);
ctx.fillStyle = 'rgba(0, 100, 255, 0.8)'; // 填充顏色 (背景色)
ctx.fill();
ctx.strokeStyle = 'red';
ctx.lineWidth = 3;
ctx.stroke();
// 繪製另一個圓:僅描邊,透明背景
ctx.beginPath();
ctx.arc(200, 200, 50, 0, Math.PI * 2);
ctx.strokeStyle = 'green';
ctx.lineWidth = 2;
ctx.stroke(); // 不調用 fill(),背景透明
</script>
| 需求 | DOM 模擬 (原代碼) | Canvas API |
|---|---|---|
| 繪製圓 | 360 個 span 定位 | ctx.arc(x, y, r, 0, 2π) |
| 填充背景色 | 極難實現 | ctx.fillStyle = 'color'; ctx.fill() |
| 描邊 | 不可行 | ctx.strokeStyle = 'color'; ctx.stroke() |
| 性能 | 極差 (幾百 DOM 節點) | 極佳 (GPU 加速、單繪圖調用) |
| 動畫/交互 | 極其複雜 | requestAnimationFrame 輕鬆實現 |
// 徑向漸變:中心白色 → 邊緣藍色
const gradient = ctx.createRadialGradient(400, 300, 0, 400, 300, 100);
gradient.addColorStop(0, 'white');
gradient.addColorStop(0.5, 'lightblue');
gradient.addColorStop(1, 'darkblue');
ctx.beginPath();
ctx.arc(400, 300, 100, 0, Math.PI * 2);
ctx.fillStyle = gradient;
ctx.fill();
const img = new Image();
img.src = 'texture.png';
img.onload = () => {
const pattern = ctx.createPattern(img, 'repeat');
ctx.beginPath();
ctx.arc(400, 300, 100, 0, Math.PI * 2);
ctx.fillStyle = pattern;
ctx.fill();
};
let radius = 50;
let growing = true;
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.arc(400, 300, radius, 0, Math.PI * 2);
ctx.strokeStyle = `rgba(255, 100, 0, ${0.5 + 0.5 * Math.sin(Date.now()/200)})`;
ctx.lineWidth = 4;
ctx.stroke();
if (growing) {
radius += 2;
if (radius > 150) growing = false;
} else {
radius -= 2;
if (radius < 50) growing = true;
}
requestAnimationFrame(animate);
}
animate();
span 是行內元素,無法設置寬高/背景色填充形狀參考教程:MDN Canvas 教程、W3Schools Canvas。
拋棄 DOM 模擬圖形,擁抱 Canvas/SVG/WebGL,才是前端圖形編程的正道。