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

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

核心实现

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的响应式更新机制

相关推荐
计算机-秋大田2 分钟前
基于Spring Boot的兴顺物流管理系统设计与实现(LW+源码+讲解)
java·vue.js·spring boot·后端·spring·课程设计
GDAL33 分钟前
HTML 中的 Canvas 样式设置全解
javascript
m0_5287238139 分钟前
HTML中,title和h1标签的区别是什么?
前端·html
Dark_programmer39 分钟前
html - - - - - modal弹窗出现时,页面怎么能限制滚动
前端·html
GDAL1 小时前
HTML Canvas clip 深入全面讲解
前端·javascript·canvas
禾苗种树1 小时前
在 Vue 3 中使用 ECharts 制作多 Y 轴折线图时,若希望 **Y 轴颜色自动匹配折线颜色**且无需手动干预,可以通过以下步骤实现:
前端·vue.js·echarts
GISer_Jing1 小时前
Javascript排序算法(冒泡排序、快速排序、选择排序、堆排序、插入排序、希尔排序)详解
javascript·算法·排序算法
贵州数擎科技有限公司1 小时前
使用 Three.js 实现流光特效
前端·webgl
JustHappy1 小时前
「我们一起做组件库🌻」做个面包屑🥖,Vue的依赖注入实战💉(VersakitUI开发实录)
前端·javascript·github
拉不动的猪1 小时前
刷刷题16
前端·javascript·面试