当前位置:首页 > VUE

vue实现标尺栏

2026-02-19 21:29:11VUE

实现标尺栏的基本思路

在Vue中实现标尺栏,通常需要结合HTML5的Canvas或SVG进行绘制,同时监听滚动事件以同步标尺与内容的移动。以下是两种常见实现方式。

基于Canvas的实现

创建一个Vue组件,使用Canvas绘制水平和垂直标尺。通过监听滚动事件更新标尺位置。

vue实现标尺栏

<template>
  <div class="ruler-container">
    <canvas ref="horizontalRuler" class="horizontal-ruler"></canvas>
    <canvas ref="verticalRuler" class="vertical-ruler"></canvas>
    <div class="content" @scroll="handleScroll">
      <!-- 你的内容区域 -->
    </div>
  </div>
</template>

<script>
export default {
  mounted() {
    this.drawRulers();
    window.addEventListener('resize', this.drawRulers);
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.drawRulers);
  },
  methods: {
    drawRulers() {
      const hCanvas = this.$refs.horizontalRuler;
      const vCanvas = this.$refs.verticalRuler;

      // 设置Canvas尺寸
      hCanvas.width = hCanvas.offsetWidth;
      hCanvas.height = 20;
      vCanvas.width = 20;
      vCanvas.height = vCanvas.offsetHeight;

      // 绘制标尺
      this.drawHorizontalRuler(hCanvas);
      this.drawVerticalRuler(vCanvas);
    },
    drawHorizontalRuler(canvas) {
      const ctx = canvas.getContext('2d');
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      // 绘制标尺刻度
      for (let i = 0; i < canvas.width; i += 10) {
        ctx.beginPath();
        ctx.moveTo(i, 0);
        ctx.lineTo(i, i % 50 === 0 ? 15 : 10);
        ctx.stroke();

        if (i % 100 === 0) {
          ctx.fillText(i, i + 2, 12);
        }
      }
    },
    drawVerticalRuler(canvas) {
      // 类似水平标尺的实现
    },
    handleScroll(e) {
      // 根据滚动位置更新标尺
    }
  }
}
</script>

<style>
.ruler-container {
  position: relative;
}
.horizontal-ruler {
  position: absolute;
  top: 0;
  left: 20px;
  width: calc(100% - 20px);
  height: 20px;
  border-bottom: 1px solid #ccc;
}
.vertical-ruler {
  position: absolute;
  top: 20px;
  left: 0;
  width: 20px;
  height: calc(100% - 20px);
  border-right: 1px solid #ccc;
}
.content {
  position: absolute;
  top: 20px;
  left: 20px;
  width: calc(100% - 20px);
  height: calc(100% - 20px);
  overflow: auto;
}
</style>

基于SVG的实现

使用SVG可以创建矢量标尺,缩放时不会失真。

vue实现标尺栏

<template>
  <div class="ruler-container">
    <svg class="horizontal-ruler" ref="horizontalRuler"></svg>
    <svg class="vertical-ruler" ref="verticalRuler"></svg>
    <div class="content" @scroll="handleScroll">
      <!-- 内容区域 -->
    </div>
  </div>
</template>

<script>
export default {
  mounted() {
    this.drawSVGRulers();
    window.addEventListener('resize', this.drawSVGRulers);
  },
  methods: {
    drawSVGRulers() {
      const hRuler = this.$refs.horizontalRuler;
      const vRuler = this.$refs.verticalRuler;

      // 清空并重新绘制
      hRuler.innerHTML = '';
      vRuler.innerHTML = '';

      // 创建水平标尺
      for (let i = 0; i < hRuler.clientWidth; i += 10) {
        const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
        line.setAttribute('x1', i);
        line.setAttribute('y1', 0);
        line.setAttribute('x2', i);
        line.setAttribute('y2', i % 50 === 0 ? 15 : 10);
        line.setAttribute('stroke', '#000');
        hRuler.appendChild(line);

        if (i % 100 === 0) {
          const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
          text.setAttribute('x', i + 2);
          text.setAttribute('y', 12);
          text.textContent = i;
          hRuler.appendChild(text);
        }
      }

      // 类似方式创建垂直标尺
    }
  }
}
</script>

使用第三方库

考虑使用现成的标尺库如vue-ruler-tool可以快速实现:

npm install vue-ruler-tool
<template>
  <ruler-tool
    :content-width="2000"
    :content-height="2000"
    :scale="1"
    :thick="20"
    :is-scale-reticle="true"
    :is-open-corner="true"
  >
    <!-- 你的内容 -->
  </ruler-tool>
</template>

<script>
import RulerTool from 'vue-ruler-tool';
export default {
  components: { RulerTool }
}
</script>

性能优化建议

对于动态更新的标尺,使用requestAnimationFrame优化绘制性能。避免在每次滚动事件中都重绘标尺,可以设置节流函数控制重绘频率。

let isDrawing = false;
function throttledDraw() {
  if (!isDrawing) {
    isDrawing = true;
    requestAnimationFrame(() => {
      drawRulers();
      isDrawing = false;
    });
  }
}

响应式设计考虑

使用CSS变量或Vue的响应式数据管理标尺样式,使其能适应不同主题或用户偏好设置。通过计算属性动态计算标尺刻度间隔,确保在不同缩放级别下都能清晰显示。

标签: 标尺vue
分享给朋友:

相关文章

vue实现后退

vue实现后退

Vue 实现后退功能的方法 在 Vue 中实现后退功能通常可以通过以下几种方式完成,具体取决于应用场景和需求。 使用 window.history API 通过原生 JavaScript 的 win…

vue 实现后退

vue 实现后退

实现后退功能的方法 在Vue中实现后退功能通常需要结合浏览器历史记录API或Vue Router的导航方法。以下是几种常见的实现方式: 使用Vue Router的go方法 this.$router…

vue实现popover

vue实现popover

Vue 实现 Popover 的方法 使用第三方库(如 Element UI、Ant Design Vue) 许多成熟的 UI 库已经内置了 Popover 组件,可以直接调用。 Element U…

vue怎么实现 tab

vue怎么实现 tab

Vue 实现 Tab 的方法 使用动态组件和 v-if 通过动态组件或 v-if 指令切换不同 Tab 内容,结合点击事件改变当前激活的 Tab。 <template> &l…

vue实现数据删除

vue实现数据删除

vue实现数据删除的方法 使用v-for和v-on指令 在Vue中可以通过v-for指令渲染列表数据,结合v-on指令监听删除事件。定义一个方法处理删除逻辑,通常使用splice方法从数组中移除指定项…

vue实现拦截登录

vue实现拦截登录

Vue 实现登录拦截的方法 使用路由守卫进行拦截 Vue Router 提供了全局前置守卫 beforeEach,可以在路由跳转前进行验证。在路由配置文件中添加以下代码: import router…