SVG 与 Canvas 嵌入
SVG 和 Canvas 是 HTML5 图形绘制的两种主要技术方案,各有适用场景。
技术对比
| 特性 | SVG | Canvas |
|---|---|---|
| 图形类型 | 矢量图 | 位图 |
| 渲染方式 | DOM元素 | JavaScript绑定 |
| 事件支持 | 原生支持 | 需手动实现 |
| 缩放 | 无损缩放 | 会模糊 |
| 性能 | 元素多时慢 | 大量绘制性能好 |
| 适用场景 | 图标、图表 | 游戏、图像处理 |
SVG 嵌入方式
内联SVG
HTML
<svg width="100" height="100" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="#3498db"/>
<text x="50" y="55" text-anchor="middle" fill="white">SVG</text>
</svg>
img标签引用
HTML
<img src="icon.svg" alt="图标" width="32" height="32">
CSS背景
CSS
.icon {
width: 32px;
height: 32px;
background-image: url('icon.svg');
background-size: contain;
}
object标签
HTML
<object data="diagram.svg" type="image/svg+xml" width="400" height="300">
<img src="fallback.png" alt="图表">
</object>
SVG 常用元素
基本图形
HTML
<svg width="400" height="200">
<!-- 矩形 -->
<rect x="10" y="10" width="100" height="50" fill="#e74c3c"/>
<!-- 圆形 -->
<circle cx="200" cy="50" r="40" fill="#3498db"/>
<!-- 椭圆 -->
<ellipse cx="320" cy="50" rx="60" ry="30" fill="#2ecc71"/>
<!-- 直线 -->
<line x1="10" y1="120" x2="100" y2="180" stroke="#333" stroke-width="2"/>
<!-- 折线 -->
<polyline points="120,180 160,120 200,180 240,120" fill="none" stroke="#9b59b6"/>
<!-- 多边形 -->
<polygon points="280,180 320,120 360,180" fill="#f39c12"/>
<!-- 路径 -->
<path d="M 10 150 Q 50 100 90 150 T 170 150" fill="none" stroke="#1abc9c" stroke-width="3"/>
</svg>
文本与样式
HTML
<svg width="300" height="100">
<defs>
<linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:#3498db"/>
<stop offset="100%" style="stop-color:#e74c3c"/>
</linearGradient>
</defs>
<text x="150" y="50" text-anchor="middle" font-size="24" fill="url(#gradient)">
渐变文字
</text>
</svg>
Canvas 嵌入
基本语法
HTML
<canvas id="myCanvas" width="400" height="300">
您的浏览器不支持Canvas
</canvas>
JavaScript绑定
JavaScript
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// 绑制矩形
ctx.fillStyle = '#3498db';
ctx.fillRect(10, 10, 100, 50);
// 绑制圆形
ctx.beginPath();
ctx.arc(200, 100, 40, 0, Math.PI * 2);
ctx.fillStyle = '#e74c3c';
ctx.fill();
// 绑制线条
ctx.beginPath();
ctx.moveTo(10, 200);
ctx.lineTo(100, 150);
ctx.strokeStyle = '#2ecc71';
ctx.lineWidth = 3;
ctx.stroke();
Canvas 常用绑定
图形绑定
JavaScript
// 矩形
ctx.fillRect(x, y, width, height); // 填充
ctx.strokeRect(x, y, width, height); // 描边
ctx.clearRect(x, y, width, height); // 清除
// 圆形
ctx.beginPath();
ctx.arc(x, y, radius, startAngle, endAngle);
ctx.fill();
// 路径
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
文字绑定
JavaScript
ctx.font = '24px Arial';
ctx.fillStyle = '#333';
ctx.fillText('Hello Canvas', 50, 100);
ctx.strokeStyle = '#3498db';
ctx.strokeText('描边文字', 50, 150);
图像绑定
JavaScript
const img = new Image();
img.onload = function() {
ctx.drawImage(img, 0, 0, 400, 300);
};
img.src = 'image.png';
// 裁剪绘制
ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh);
动画实现
SVG 动画(CSS)
HTML
<svg width="100" height="100">
<circle cx="50" cy="50" r="20" fill="#3498db">
<animate
attributeName="r"
values="20;40;20"
dur="2s"
repeatCount="indefinite"
/>
</circle>
</svg>
<style>
svg circle {
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { r: 20; }
50% { r: 40; }
}
</style>
Canvas 动画
JavaScript
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
let x = 0;
function animate() {
// 清除画布
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 绘制移动的圆
ctx.beginPath();
ctx.arc(x, 100, 20, 0, Math.PI * 2);
ctx.fillStyle = '#3498db';
ctx.fill();
// 更新位置
x = (x + 2) % canvas.width;
// 请求下一帧
requestAnimationFrame(animate);
}
animate();
选择指南
text
选择 SVG:
✓ 需要矢量缩放(图标、Logo)
✓ 需要事件交互(图表悬停)
✓ 图形元素较少
✓ 需要CSS样式控制
选择 Canvas:
✓ 大量图形绘制(游戏、粒子)
✓ 实时图像处理
✓ 性能要求高
✓ 复杂动画场景
注意:SVG 内联会增加 DOM 节点,大量 SVG 元素会影响性能;Canvas 内容无法被搜索引擎索引。
要点总结
- SVG 矢量图支持无损缩放,适合图标、图表
- Canvas 位图性能好,适合游戏、图像处理
- SVG 内联可直接操作 DOM 和添加事件
- Canvas 需 JavaScript 绑定,事件需手动计算
- 复杂动画和大量图形优先选择 Canvas
📝 发现内容有误?点击此处直接编辑