vue实现标尺栏
实现标尺栏的基本思路
在Vue中实现标尺栏,通常需要结合HTML5的Canvas或SVG进行绘制,同时监听滚动事件以同步标尺与内容的移动。以下是两种常见实现方式。
基于Canvas的实现
创建一个Vue组件,使用Canvas绘制水平和垂直标尺。通过监听滚动事件更新标尺位置。
<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可以创建矢量标尺,缩放时不会失真。
<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的响应式数据管理标尺样式,使其能适应不同主题或用户偏好设置。通过计算属性动态计算标尺刻度间隔,确保在不同缩放级别下都能清晰显示。







