vue实现尺子
Vue 实现尺子组件
实现一个尺子组件可以通过 Canvas 或纯 CSS 完成。以下是两种常见实现方式:
使用 Canvas 绘制尺子
通过 Canvas 动态绘制刻度线和数字,适合需要高精度或动态缩放场景。
<template>
<div class="ruler-container">
<canvas ref="canvas" :width="width" :height="height"></canvas>
</div>
</template>
<script>
export default {
props: {
width: { type: Number, default: 800 },
height: { type: Number, default: 40 },
scale: { type: Number, default: 1 }, // 缩放比例
startValue: { type: Number, default: 0 } // 起始刻度值
},
mounted() {
this.drawRuler();
},
methods: {
drawRuler() {
const canvas = this.$refs.canvas;
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, this.width, this.height);
// 绘制背景
ctx.fillStyle = '#f5f5f5';
ctx.fillRect(0, 0, this.width, this.height);
// 绘制刻度
const pixelsPerUnit = 50 * this.scale;
const totalUnits = Math.ceil(this.width / pixelsPerUnit);
for (let i = 0; i <= totalUnits; i++) {
const x = i * pixelsPerUnit;
const isMajorTick = i % 10 === 0;
// 刻度线高度
const tickHeight = isMajorTick ? 20 : 10;
// 绘制刻度线
ctx.beginPath();
ctx.moveTo(x, this.height);
ctx.lineTo(x, this.height - tickHeight);
ctx.strokeStyle = '#333';
ctx.stroke();
// 绘制数字
if (isMajorTick) {
ctx.font = '12px Arial';
ctx.fillStyle = '#333';
ctx.textAlign = 'center';
ctx.fillText(
this.startValue + i,
x,
this.height - tickHeight - 5
);
}
}
}
},
watch: {
scale() {
this.drawRuler();
}
}
};
</script>
使用 CSS 实现尺子
纯 CSS 实现适合简单场景,通过伪元素和 flex 布局生成刻度。
<template>
<div class="css-ruler" :style="{ width: `${length}px` }">
<div
v-for="(tick, index) in ticks"
:key="index"
class="tick"
:class="{ 'major-tick': index % 10 === 0 }"
>
<span v-if="index % 10 === 0">{{ index }}</span>
</div>
</div>
</template>
<script>
export default {
props: {
length: { type: Number, default: 800 }, // 尺子长度(像素)
unit: { type: Number, default: 10 } // 每像素代表单位
},
computed: {
ticks() {
return Array(Math.floor(this.length / this.unit)).fill(0);
}
}
};
</script>
<style>
.css-ruler {
display: flex;
height: 40px;
background: #f5f5f5;
position: relative;
}
.tick {
flex: 1;
border-left: 1px solid #999;
position: relative;
height: 10px;
}
.major-tick {
height: 20px;
}
.major-tick span {
position: absolute;
bottom: -20px;
left: -10px;
font-size: 12px;
}
</style>
实现交互功能
添加拖动和缩放功能需要结合鼠标事件:
// 在 Canvas 组件中添加
data() {
return {
isDragging: false,
lastX: 0,
offsetX: 0
}
},
methods: {
handleMouseDown(e) {
this.isDragging = true;
this.lastX = e.clientX;
},
handleMouseMove(e) {
if (!this.isDragging) return;
const dx = e.clientX - this.lastX;
this.offsetX += dx;
this.lastX = e.clientX;
this.drawRuler();
},
handleMouseUp() {
this.isDragging = false;
}
},
mounted() {
this.$refs.canvas.addEventListener('mousedown', this.handleMouseDown);
window.addEventListener('mousemove', this.handleMouseMove);
window.addEventListener('mouseup', this.handleMouseUp);
},
beforeDestroy() {
this.$refs.canvas.removeEventListener('mousedown', this.handleMouseDown);
window.removeEventListener('mousemove', this.handleMouseMove);
window.removeEventListener('mouseup', this.handleMouseUp);
}
垂直尺子实现
将水平尺子逻辑调整为垂直方向,修改 Canvas 绘制逻辑或 CSS 样式:
.vertical-ruler {
width: 40px;
height: 500px;
flex-direction: column;
}
.vertical-tick {
border-left: none;
border-top: 1px solid #999;
}
通过以上方法可以实现基础尺子功能,实际项目中可根据需求添加单位切换、主题定制等功能。Canvas 方案适合高性能需求,CSS 方案则更轻量易维护。







