vue实现手动标尺模块
实现手动标尺模块的方法
基本结构与样式
创建一个Vue组件,包含标尺的HTML结构和CSS样式。标尺通常分为水平标尺和垂直标尺,需要定义刻度线、数字标签等元素。
<template>
<div class="ruler-container">
<div class="horizontal-ruler" ref="horizontalRuler"></div>
<div class="vertical-ruler" ref="verticalRuler"></div>
</div>
</template>
<style>
.ruler-container {
position: relative;
width: 100%;
height: 100%;
}
.horizontal-ruler, .vertical-ruler {
position: absolute;
background: #f0f0f0;
}
.horizontal-ruler {
top: 0;
left: 0;
width: 100%;
height: 20px;
border-bottom: 1px solid #ccc;
}
.vertical-ruler {
top: 0;
left: 0;
width: 20px;
height: 100%;
border-right: 1px solid #ccc;
}
</style>
刻度生成逻辑
在Vue的mounted生命周期中生成刻度线。根据容器大小计算刻度间隔,动态添加DOM元素。
export default {
mounted() {
this.drawRulers();
},
methods: {
drawRulers() {
const hRuler = this.$refs.horizontalRuler;
const vRuler = this.$refs.verticalRuler;
// 水平标尺刻度
for (let i = 0; i < hRuler.offsetWidth; i += 10) {
const tick = document.createElement('div');
tick.style.position = 'absolute';
tick.style.left = `${i}px`;
tick.style.height = i % 50 === 0 ? '10px' : '5px';
tick.style.width = '1px';
tick.style.backgroundColor = '#999';
hRuler.appendChild(tick);
if (i % 100 === 0) {
const label = document.createElement('span');
label.textContent = i;
label.style.position = 'absolute';
label.style.left = `${i}px`;
label.style.top = '12px';
label.style.fontSize = '10px';
hRuler.appendChild(label);
}
}
// 垂直标尺刻度(类似逻辑)
}
}
}
交互功能实现
添加鼠标移动事件监听,显示当前位置的指示线。使用Vue的数据绑定更新指示线位置。
data() {
return {
currentX: 0,
currentY: 0,
showIndicator: false
}
},
methods: {
handleMouseMove(e) {
this.currentX = e.clientX - this.$el.getBoundingClientRect().left;
this.currentY = e.clientY - this.$el.getBoundingClientRect().top;
this.showIndicator = true;
},
handleMouseLeave() {
this.showIndicator = false;
}
}
动态缩放支持
添加缩放功能,通过调整刻度间隔和标签来适应不同的缩放级别。
props: {
zoomLevel: {
type: Number,
default: 1
}
},
watch: {
zoomLevel() {
this.redrawRulers();
}
},
methods: {
redrawRulers() {
// 清除旧刻度
this.$refs.horizontalRuler.innerHTML = '';
this.$refs.verticalRuler.innerHTML = '';
// 根据zoomLevel重新绘制
this.drawRulers();
}
}
性能优化
对于大型标尺,使用Canvas渲染代替DOM操作可以提高性能。
drawCanvasRuler() {
const canvas = this.$refs.rulerCanvas;
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 绘制刻度逻辑
for (let i = 0; i < canvas.width; i += 10 * this.zoomLevel) {
ctx.beginPath();
ctx.moveTo(i, 0);
ctx.lineTo(i, i % 50 === 0 ? 15 : 10);
ctx.stroke();
}
}
组件封装
将标尺功能封装为可复用的Vue组件,提供props接口自定义样式和行为。
props: {
color: {
type: String,
default: '#999'
},
showLabels: {
type: Boolean,
default: true
},
unit: {
type: String,
default: 'px'
}
}
注意事项
- 标尺位置需要与实际内容区域同步,可能需要使用
ResizeObserver监听尺寸变化 - 移动端需要考虑触摸事件的支持
- 高精度场景下需要处理亚像素渲染问题
- 国际化场景下需要处理不同单位的转换(如px到mm)







