前言
需求:显示一个时间刻度尺,鼠标移动会显示当前时间
技术:我们采用canvas+fabric进行实现
效果
实现
1.创建canvas(设置宽高)设为全局变量
2.引入fabric包
3.画时间刻度尺(长方形+横线)
4.增加鼠标移动事件并画虚线时间显示
5.增加鼠标离开事件并销毁虚线时间
javascript
<template>
<div>
<canvas id="rulerCanvas" width="1200" height="400"></canvas>
</div>
</template>
<script setup>
import * as fabric from 'fabric';
import {ref, onMounted} from 'vue';
const canvas = ref(null);
onMounted(() => {
drawRuler();
});
let movDummyLine = null;
let movDummyLineText = null;
const onMouseMove = (options) => {
if (options.pointer.x >= 40) {
if (movDummyLine) {
canvas.value.remove(movDummyLine);
canvas.value.remove(movDummyLineText);
}
// 添加虚线
movDummyLine = new fabric.Line([0, 800, 1, 0], {
stroke: 'red',
strokeDashArray: [5, 5],
strokeWidth: 1,
selectable: false,
}).set({ left: options.pointer.x, top: 36 });
canvas.value.add(movDummyLine);
// group.add(movDummyLine);
// 添加文字 (options.pointer.x)
let startNumber = options.pointer.x - 40 + 20;
let timeNumber = parseInt(startNumber / 20);
movDummyLineText = new fabric.Text(timeToStr(timeNumber), {
fontSize: 12,
fill: 'black',
selectable: false,
textAlign: 'center',
}).set({ left: options.pointer.x - 12, top: 20 });
canvas.value.add(movDummyLineText);
// group.add(movDummyLineText);
}
};
const drawRuler = () => {
canvas.value = new fabric.Canvas('rulerCanvas');
// 鼠标事件
canvas.value.on('mouse:move', onMouseMove);
canvas.value.on('mouse:out', () => {
if (movDummyLine) {
canvas.value.remove(movDummyLine);
canvas.value.remove(movDummyLineText);
movDummyLine = null;
movDummyLineText = null;
}
});
// 时间刻度
const startHour = 0;
const startMinute = 0;
const intervalMinutes = 5; // 间隔
const totalHours = 1; // 当前刻度时间
let currentMinute = startMinute;
let currentHour = startHour;
// 长方形
const rect = new fabric.Rect({
left: 0,
top: 0,
width: 1100,
height: 40,
fill: '#fff',
strokeWidth: 1, // 边框宽度
selectable: false,
});
canvas.value.add(rect);
// 底部边框
const bottomBorder = new fabric.Line([0, 40, 1200, 40], {
stroke: '#000000',
strokeWidth: 1,
selectable: false,
});
canvas.value.add(bottomBorder);
// 时间刻度
for (let i = 0; i <= totalHours * 60; i += intervalMinutes) {
const x = (i / (totalHours * 60)) * canvas.value.width + 40;
const timeText = formatTime(currentHour, currentMinute);
// 画刻度线
const b = new fabric.Line([x, 50, x, 60], {
stroke: 'black',
strokeWidth: 1,
selectable: false,
}).set({ left: x, top: 28 });
canvas.value.add(b);
// 添加时间文本
const a = new fabric.Text(timeText, {
fontSize: 12,
fill: 'black',
selectable: false,
textAlign: 'center',
}).set({ left: x-14, top: 10 });
canvas.value.add(a);
// 更新分钟和小时
currentMinute += intervalMinutes;
if (currentMinute >= 60) {
currentMinute = 0;
currentHour++;
}
}
};
const formatTime = (hour, minute) => {
return `${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}`;
};
const timeToStr = (seconds) => {
const minutes = Math.floor(seconds / 60);
const secs = seconds % 60;
const paddedMinutes = String(minutes).padStart(2, '0');
const paddedSeconds = String(secs).padStart(2, '0');
return `${paddedMinutes}:${paddedSeconds}`;
};
</script>
<style>
#rulerCanvas {
border: 1px solid black;
}
</style>
如果侵权请联系我删除。