canvas+fabric实现时间刻度尺(一)

前言

需求:显示一个时间刻度尺,鼠标移动会显示当前时间

技术:我们采用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>

如果侵权请联系我删除。

相关推荐
虎头金猫1 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
AI职业加油站1 天前
AI智能体应用工程师证书:政策红利下的职业新风口
大数据·运维·人工智能·学习·职场发展
此冬歌咏2 天前
K8s 节点故障实战:优雅驱逐 31 秒,硬故障 331 秒,以及那个永远 Pending 的 Pod
运维·k8s
-梅2 天前
linux(8) 软硬链接
linux·运维·服务器
张洛闻Eren2 天前
k8s云原生【第十课】:水平 Pod 自动扩缩容
运维·数据库·云原生·kubernetes·github
其实防守也摸鱼2 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
布裘2 天前
【银河麒麟】V4桌面图标消失,右击鼠标没反应排查
运维·银河麒麟·桌面环境
懂软件的胡子个哥2 天前
微信机器人为什么需要“回复候选”而不是所有 AI 内容直接发送
运维·微信·自动化·wechatapi·个人微信号二次开发
云贝贝贝2 天前
腾讯云 TDSQL(MySQL 版)性能优化与慢查询排障实战 6 招
运维·腾讯云
Lsetea2 天前
证书没到期却报certificate has expired:OpenSSL定位中间证书与系统时间
运维·https·ssl证书·openssl·证书链