前端Canvas:让你的网站更具视觉冲击力

张开发
2026/5/22 22:22:25 15 分钟阅读
前端Canvas:让你的网站更具视觉冲击力
前端Canvas让你的网站更具视觉冲击力毒舌时刻前端Canvas这不是游戏开发才用的吗Canvas性能差我不用——结果错过了丰富的视觉效果Canvas太复杂了我学不会——结果只能用静态图片我用CSS就够了要Canvas干嘛——结果无法实现复杂的动画效果。醒醒吧Canvas不是游戏开发的专利前端也可以用它来创建丰富的视觉效果为什么你需要这个丰富的视觉效果创建动态图形、动画和游戏高性能直接操作像素性能优异交互性支持鼠标、触摸等交互数据可视化绘制图表、仪表盘等跨平台在所有现代浏览器中运行反面教材// 反面教材简单的Canvas绘制 function drawCircle() { const canvas document.getElementById(canvas); const ctx canvas.getContext(2d); // 绘制一个简单的圆形 ctx.beginPath(); ctx.arc(100, 100, 50, 0, Math.PI * 2); ctx.fillStyle red; ctx.fill(); ctx.stroke(); } // 反面教材没有优化的动画 function animate() { const canvas document.getElementById(canvas); const ctx canvas.getContext(2d); let x 0; setInterval(() { // 每次都清除整个画布 ctx.clearRect(0, 0, canvas.width, canvas.height); // 绘制移动的矩形 ctx.fillStyle blue; ctx.fillRect(x, 50, 50, 50); x 1; if (x canvas.width) { x 0; } }, 16); }正确的做法// 正确的做法Canvas基础绘制 function basicDrawing() { const canvas document.getElementById(canvas); const ctx canvas.getContext(2d); // 设置画布尺寸 canvas.width 800; canvas.height 600; // 绘制矩形 ctx.fillStyle blue; ctx.fillRect(50, 50, 100, 100); // 绘制圆形 ctx.beginPath(); ctx.arc(250, 100, 50, 0, Math.PI * 2); ctx.fillStyle red; ctx.fill(); // 绘制路径 ctx.beginPath(); ctx.moveTo(350, 50); ctx.lineTo(450, 150); ctx.lineTo(350, 150); ctx.closePath(); ctx.strokeStyle green; ctx.lineWidth 2; ctx.stroke(); // 绘制文本 ctx.font 24px Arial; ctx.fillStyle black; ctx.textAlign center; ctx.fillText(Canvas绘制示例, canvas.width / 2, 30); } // 正确的做法Canvas动画 function canvasAnimation() { const canvas document.getElementById(canvas); const ctx canvas.getContext(2d); canvas.width 800; canvas.height 600; let x 0; let y canvas.height / 2; let dx 2; let dy 2; const radius 20; function animate() { // 清除画布 ctx.clearRect(0, 0, canvas.width, canvas.height); // 绘制移动的圆形 ctx.beginPath(); ctx.arc(x, y, radius, 0, Math.PI * 2); ctx.fillStyle purple; ctx.fill(); // 边界检测 if (x radius canvas.width || x - radius 0) { dx -dx; } if (y radius canvas.height || y - radius 0) { dy -dy; } // 更新位置 x dx; y dy; // 使用requestAnimationFrame requestAnimationFrame(animate); } animate(); } // 正确的做法Canvas交互 function canvasInteraction() { const canvas document.getElementById(canvas); const ctx canvas.getContext(2d); canvas.width 800; canvas.height 600; let isDrawing false; let lastX 0; let lastY 0; // 鼠标按下事件 canvas.addEventListener(mousedown, (e) { isDrawing true; [lastX, lastY] [e.offsetX, e.offsetY]; }); // 鼠标移动事件 canvas.addEventListener(mousemove, (e) { if (!isDrawing) return; ctx.beginPath(); ctx.moveTo(lastX, lastY); ctx.lineTo(e.offsetX, e.offsetY); ctx.strokeStyle black; ctx.lineWidth 2; ctx.stroke(); [lastX, lastY] [e.offsetX, e.offsetY]; }); // 鼠标释放事件 canvas.addEventListener(mouseup, () { isDrawing false; }); // 鼠标离开事件 canvas.addEventListener(mouseout, () { isDrawing false; }); } // 正确的做法Canvas数据可视化 function canvasChart() { const canvas document.getElementById(canvas); const ctx canvas.getContext(2d); canvas.width 800; canvas.height 600; // 数据 const data [12, 19, 3, 5, 2, 3, 7, 11, 15, 18, 10, 6]; const labels [1月, 2月, 3月, 4月, 5月, 6月, 7月, 8月, 9月, 10月, 11月, 12月]; // 绘制坐标系 const padding 50; const chartWidth canvas.width - padding * 2; const chartHeight canvas.height - padding * 2; // X轴 ctx.beginPath(); ctx.moveTo(padding, canvas.height - padding); ctx.lineTo(canvas.width - padding, canvas.height - padding); ctx.stroke(); // Y轴 ctx.beginPath(); ctx.moveTo(padding, padding); ctx.lineTo(padding, canvas.height - padding); ctx.stroke(); // 绘制数据 const maxValue Math.max(...data); const barWidth chartWidth / data.length; data.forEach((value, index) { const barHeight (value / maxValue) * chartHeight; const x padding index * barWidth; const y canvas.height - padding - barHeight; // 绘制柱子 ctx.fillStyle rgba(54, 162, 235, 0.6); ctx.fillRect(x 5, y, barWidth - 10, barHeight); // 绘制标签 ctx.font 12px Arial; ctx.fillStyle black; ctx.textAlign center; ctx.fillText(labels[index], x barWidth / 2, canvas.height - padding 15); }); // 绘制标题 ctx.font 20px Arial; ctx.fillStyle black; ctx.textAlign center; ctx.fillText(月度销售数据, canvas.width / 2, padding / 2); } // 正确的做法Canvas图像处理 function canvasImageProcessing() { const canvas document.getElementById(canvas); const ctx canvas.getContext(2d); canvas.width 800; canvas.height 600; // 加载图像 const img new Image(); img.crossOrigin anonymous; img.onload () { // 绘制原始图像 ctx.drawImage(img, 0, 0, 400, 300); // 获取图像数据 const imageData ctx.getImageData(0, 0, 400, 300); const data imageData.data; // 处理图像灰度 for (let i 0; i data.length; i 4) { const r data[i]; const g data[i 1]; const b data[i 2]; const gray (r g b) / 3; data[i] gray; data[i 1] gray; data[i 2] gray; } // 绘制处理后的图像 ctx.putImageData(imageData, 400, 0); }; img.src https://picsum.photos/800/600; }毒舌点评看看这才叫前端Canvas不是简单地绘制几个图形而是创建丰富的视觉效果、动画和交互。记住Canvas是一个强大的工具它可以让你创建从简单的图表到复杂的游戏等各种视觉效果。合理使用Canvas可以让你的网站更具视觉冲击力。所以别再觉得Canvas复杂了它是前端视觉效果的重要工具总结基础绘制矩形、圆形、路径、文本等动画效果使用requestAnimationFrame实现流畅动画交互操作鼠标、触摸等事件处理数据可视化绘制图表、仪表盘等图像处理像素级操作实现滤镜效果性能优化合理使用缓存、避免频繁重绘响应式根据容器大小调整画布尺寸工具库使用Chart.js、Fabric.js等库简化开发前端Canvas让你的网站更具视觉冲击力

更多文章