Canvas 和 SVG 的实用案例

以下是 Canvas 和 SVG 的实用案例对比及实现代码,涵盖核心特性和典型应用场景:


一、Canvas 动态时钟(位图绘制)

<canvas id="clock" width="300" height="300"></canvas>

<script>
const canvas = document.getElementById('clock');
const ctx = canvas.getContext('2d');

function drawClock() {
  // 清空画布
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  
  // 绘制表盘
  ctx.beginPath();
  ctx.arc(150, 150, 140, 0, Math.PI * 2);
  ctx.strokeStyle = '#333';
  ctx.lineWidth = 4;
  ctx.stroke();

  // 绘制刻度
  for (let i = 0; i < 60; i++) {
    ctx.beginPath();
    const angle = (i * Math.PI) / 30;
    const length = i % 5 === 0 ? 15 : 5;
    ctx.moveTo(150 + Math.cos(angle) * 125, 150 + Math.sin(angle) * 125);
    ctx.lineTo(150 + Math.cos(angle) * (125 - length), 150 + Math.sin(angle) * (125 - length));
    ctx.stroke();
  }

  // 获取时间
  const now = new Date();
  const hours = now.getHours() % 12;
  const minutes = now.getMinutes();
  const seconds = now.getSeconds();

  // 绘制时针
  ctx.save();
  ctx.translate(150, 150);
  ctx.rotate((hours * 30 + minutes * 0.5) * Math.PI / 180);
  ctx.beginPath();
  ctx.moveTo(0, 0);
  ctx.lineTo(0, -60);
  ctx.lineWidth = 6;
  ctx.stroke();
  ctx.restore();

  // 动画循环
  requestAnimationFrame(drawClock);
}

drawClock();
</script>

核心要点:

  1. 使用 getContext('2d') 获取绘图上下文
  2. 通过 clearRect 实现画面刷新
  3. 数学计算实现坐标定位
  4. requestAnimationFrame 优化动画性能

二、SVG 可交互柱状图(矢量图形)

<svg width="400" height="300" id="chart">
  <!-- X轴 -->
  <path d="M50 250 H350" stroke="#999" />
  
  <!-- 数据列 -->
  <rect x="70" y="150" width="40" height="100" fill="#4CAF50" class="bar">
    <title>销售额: ¥12000</title>
  </rect>
  <rect x="150" y="100" width="40" height="150" fill="#2196F3" class="bar">
    <title>销售额: ¥18000</title>
  </rect>
  <rect x="230" y="50" width="40" height="200" fill="#FF9800" class="bar">
    <title>销售额: ¥24000</title>
  </rect>

  <!-- 文字标签 -->
  <text x="90" y="270" text-anchor="middle">Q1</text>
  <text x="170" y="270" text-anchor="middle">Q2</text>
  <text x="250" y="270" text-anchor="middle">Q3</text>
</svg>

<style>
.bar {
  transition: all 0.3s;
  cursor: pointer;
}
.bar:hover {
  opacity: 0.8;
  transform: translateY(-2px);
}
</style>

核心要点:

  1. 原生 SVG 标签声明式绘图
  2. CSS 直接控制样式和动画
  3. 内置 <title> 实现 Tooltip
  4. 矢量特性保证缩放不失真

三、技术选型对比表

特性CanvasSVG
图像类型位图(像素操作)矢量图(XML描述)
渲染方式立即模式(需手动刷新)保留模式(自动管理)
交互实现需手动计算坐标区域原生支持DOM事件
性能表现大数据量渲染更优(游戏/可视化)复杂图形渲染更高效
典型应用动态图表/图像处理可缩放图标/数据可视化
学习曲线需要图形API知识类似HTML的声明式语法
动画实现通过JS逐帧绘制CSS动画/SMIL

四、混合使用场景

地图可视化方案:

  1. 使用 SVG 绘制基础地图轮廓
  2. Canvas 叠加实时热力图
  3. WebGL 处理3D地形
// 获取SVG路径数据
const paths = document.querySelectorAll('svg path');

// Canvas叠加绘制
ctx.globalCompositeOperation = 'multiply';
paths.forEach(path => {
  const points = getPathPoints(path); // 解析SVG路径
  drawHeatmap(points); // Canvas绘制热力
});

五、现代框架集成

  1. React + Canvas

    useEffect(() => {
      const ctx = canvasRef.current.getContext('2d');
      // 使用requestAnimationFrame驱动动画
    }, []);
    
  2. Vue + SVG

    <template>
      <svg>
        <circle 
          v-for="(item, i) in data" 
          :cx="i * 50 + 30" 
          :cy="100" 
          :r="item.value / 10"
        />
      </svg>
    </template>
    

关键决策建议:

  • 选择 Canvas 当需要:

    • 处理图像像素(滤镜/合成)
    • 高频更新动画(游戏)
    • 大数据量绘制(10k+元素)
  • 选择 SVG 当需要:

    • 可访问性(屏幕阅读器支持)
    • 精细交互(hover/click事件)
    • 响应式缩放(高分辨率设备)

掌握两者的核心差异,根据具体场景选择最佳方案,亦可结合使用实现互补优势。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小赖同学啊

感谢上帝的投喂

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值