视频编辑器时间轴刻度尺的实现

在视频编辑器中,时间轴刻度尺是一个非常重要的组件,它能直观地展示视频的时间位置。今天我们来详细讲解一下时间轴刻度尺的实现原理。

核心实现

1. Canvas绘制基础

时间轴刻度尺使用Canvas实现,主要包含以下几个关键点:

js 复制代码
const canvas = document.getElementById('time-ruler-canvas');
const ctx = canvas.getContext('2d');
canvas.width = timeline.lengthInpx; // 画布宽度根据时间轴长度动态设置
ctx.strokeStyle = '#353535';  // 设置刻度线颜色

2. 刻度绘制逻辑

刻度的绘制采用分级显示的方式:

  • 普通刻度:3px高

  • 5的倍数刻度:6px高

  • 10的倍数刻度:16px高,并显示时间文本

具体实现代码:

js 复制代码
function drawTick(tick, unit) {
  let length = 3;
  ctx.lineWidth = 1;
  
  // 判断刻度等级
  if (tick % 5 === 0) length = 6;
  if (tick % 10 === 0) length = 16;

  // 画刻度线
  ctx.moveTo(tick * timeline.scale * unit, 0);
  ctx.lineTo(tick * timeline.scale * unit, length);
  ctx.stroke();

  // 在10的倍数刻度处绘制时间文本
  if (tick % 10 === 0) {
    ctx.fillStyle = '#9f9f9f';
    ctx.fillText(sec2hsm(tick * unit), tick * timeline.scale * unit + 2, length);
  }
}

Tip: sec2hsm 是一个工具方法,把64s转换成01:04

3. 比例尺算法

比例尺(scale)决定了时间轴的显示密度。在代码中,scale表示1秒在画布上占用的像素数。比如:

  • scale = 10 表示 1秒 = 10px

  • scale = 20 表示 1秒 = 20px

为了保证刻度的清晰可读,设计一个自适应的刻度单位池:

js 复制代码
const unitPool = [
  { scale: 45, unit: 1/10 },  // 比例尺>=45px时,1个刻度表示0.1秒
  { scale: 20, unit: 1 },     // 比例尺>=20px时,1个刻度表示1秒
  { scale: 10, unit: 2 },     // 比例尺>=10px时,1个刻度表示2秒
  { scale: 4, unit: 3 },      // 比例尺>=4px时,1个刻度表示3秒
  { scale: 1, unit: 6 }       // 比例尺>=1px时,1个刻度表示6秒
];

根据当前的scale值,自动选择合适的刻度单位:

js 复制代码
const unit = unitPool.find((u) => u.scale <= timeline.scale).unit;

4. 缩放实现

缩放的实现主要依赖于Timeline类中的scale属性:

js 复制代码
// Timeline.js
constructor(options) {
  const defaults = {
    scale: 10, // 默认10px = 1s
    // ...其他属性
  }
}

get lengthInpx() {
  return this.end * this.scale * 1.2; // 时间轴总长度 = 总时长 * 比例尺 * 1.2
}

当用户进行缩放操作时,只需要改变scale值,TimeRuler组件会通过Vue的响应式系统自动重新渲染:

js 复制代码
watch(() => timeline.lengthInpx, drawTimeRuler, {
  immediate: true,
  deep: true
});

为了优化性能,使用了throttle防抖处理,减少滚动鼠标滚轮时的触发间隔:

js 复制代码
const drawTimeRuler = throttle(function () {
  canvas.width = Math.min(timeline.lengthInpx, 65535) // 清除画布,宽度最大65535,超出会崩溃
  ctx.strokeStyle = '#353535'

  const unitPool = [
    { scale: 45, unit: 1 / 10 },
    { scale: 20, unit: 1 },
    { scale: 10, unit: 2 },
    { scale: 4, unit: 3 }, // 比例尺4px = 1s,则一个刻度表示3秒
    { scale: 1, unit: 6 } // 比例尺1px = 1s,则一个刻度表示6秒
  ]
  const unit = unitPool.find((u) => u.scale <= timeline.scale).unit
  const tickCount = canvas.width / timeline.scale / unit
  for (let i = 0; i < tickCount; i++) {
    drawTick(i, unit)
  }
}, 200)

总结

时间轴刻度尺的实现核心在于:

  • 使用Canvas进行高效绘制

  • 采用分级刻度显示策略

  • 动态比例尺算法

  • 基于Vue的响应式更新机制

相关推荐
市民中心的蟋蟀5 分钟前
第五章 使用Context和订阅来共享组件状态
前端·javascript·react.js
逆袭的小黄鸭9 分钟前
JavaScript 闭包:强大特性背后的概念、应用与内存考量
前端·javascript·面试
carterwu20 分钟前
各个大厂是怎么实现组件库和相应扩展的?基础组件、区块、页面
前端
Face21 分钟前
promise 规范应用
前端
Mintopia22 分钟前
Node.js 中 fs.readFile API 的使用详解
前端·javascript·node.js
Face23 分钟前
事件循环
前端·javascript
ONE_Gua25 分钟前
chromium魔改——navigator.webdriver 检测
前端·后端·爬虫
CodePencil25 分钟前
CSS专题之盒模型
前端·css
谦谦橘子25 分钟前
服务端渲染原理解析
前端·javascript·react.js
carterwu26 分钟前
umi+模块联邦-配置指南
前端