当前位置:首页 > VUE

vue实现刻度尺时间轴

2026-01-07 06:53:57VUE

实现刻度尺时间轴的基本思路

在Vue中实现刻度尺时间轴,通常需要结合HTML5 Canvas或SVG进行绘制。核心逻辑包括计算刻度位置、动态渲染时间标签以及处理用户交互(如拖动、缩放)。以下是具体实现方法:

使用Canvas绘制刻度尺

创建Canvas组件并动态绘制刻度线:

vue实现刻度尺时间轴

<template>
  <div class="ruler-container">
    <canvas ref="canvas" :width="width" :height="height"></canvas>
  </div>
</template>

<script>
export default {
  props: {
    width: { type: Number, default: 1000 },
    height: { type: Number, default: 60 },
    startTime: { type: Date, default: () => new Date() },
    endTime: { type: Date, required: true }
  },
  mounted() {
    this.drawRuler();
  },
  methods: {
    drawRuler() {
      const canvas = this.$refs.canvas;
      const ctx = canvas.getContext('2d');
      ctx.clearRect(0, 0, this.width, this.height);

      const totalSeconds = (this.endTime - this.startTime) / 1000;
      const pixelsPerSecond = this.width / totalSeconds;

      // 绘制主刻度(小时)
      for (let i = 0; i <= totalSeconds; i += 3600) {
        const x = i * pixelsPerSecond;
        ctx.beginPath();
        ctx.moveTo(x, 0);
        ctx.lineTo(x, 30);
        ctx.stroke();

        // 添加时间标签
        const time = new Date(this.startTime.getTime() + i * 1000);
        ctx.fillText(
          time.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
          x + 2,
          45
        );
      }

      // 绘制次刻度(分钟)
      ctx.strokeStyle = '#ccc';
      for (let i = 0; i <= totalSeconds; i += 60) {
        const x = i * pixelsPerSecond;
        ctx.beginPath();
        ctx.moveTo(x, 15);
        ctx.lineTo(x, 30);
        ctx.stroke();
      }
    }
  }
};
</script>

实现交互功能

添加拖动和缩放功能需要结合事件处理:

vue实现刻度尺时间轴

// 在methods中添加
handleWheel(e) {
  e.preventDefault();
  const delta = e.deltaY > 0 ? 0.9 : 1.1;
  this.zoom(delta, e.offsetX);
},

zoom(scaleFactor, mouseX) {
  // 计算新的时间范围
  const timeAtMouse = this.startTime.getTime() + 
    (mouseX / this.width) * (this.endTime - this.startTime);

  const newRange = (this.endTime - this.startTime) * scaleFactor;

  this.startTime = new Date(timeAtMouse - (mouseX / this.width) * newRange);
  this.endTime = new Date(this.startTime.getTime() + newRange);

  this.drawRuler();
}

在模板中添加事件监听:

<canvas 
  ref="canvas" 
  @wheel.prevent="handleWheel"
  @mousedown="startDrag"
  @mousemove="handleDrag"
  @mouseup="endDrag">
</canvas>

使用SVG实现替代方案

如果不需要复杂绘制逻辑,SVG方案更简洁:

<template>
  <svg :width="width" :height="height">
    <!-- 主刻度 -->
    <g v-for="(tick, i) in majorTicks" :key="'major-' + i">
      <line 
        :x1="tick.position" 
        y1="0" 
        :x2="tick.position" 
        y2="30" 
        stroke="#000"/>
      <text 
        :x="tick.position + 5" 
        y="45" 
        font-size="12">
        {{ tick.label }}
      </text>
    </g>

    <!-- 次刻度 -->
    <line 
      v-for="(tick, i) in minorTicks" 
      :key="'minor-' + i"
      :x1="tick.position" 
      y1="15" 
      :x2="tick.position" 
      y2="30" 
      stroke="#ccc"/>
  </svg>
</template>

<script>
export default {
  computed: {
    majorTicks() {
      // 计算主刻度位置和标签
    },
    minorTicks() {
      // 计算次刻度位置
    }
  }
}
</script>

性能优化建议

  1. 虚拟渲染:对于超长时间轴,只渲染可视区域内的刻度(类似无限列表优化)
  2. 防抖处理:缩放和拖动时使用防抖避免频繁重绘
  3. Web Worker:复杂计算放在Web Worker中执行
  4. CSS Transform:平移时使用CSS transform而非重绘所有刻度

第三方库推荐

  1. vis.js:提供成熟的Timeline组件
  2. d3.js:强大的数据可视化库,适合自定义时间轴
  3. chronoline.js:专门的时间轴库

以上方案可根据项目需求选择原生实现或集成现有库。

标签: 刻度尺时间
分享给朋友:

相关文章

css制作时间轴

css制作时间轴

使用 Flexbox 布局制作时间轴 通过 Flexbox 可以快速实现水平或垂直时间轴。以下是一个垂直时间轴的示例代码: .timeline { display: flex; flex-…