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

前言

我们前面实现了时间刻度尺,鼠标移动显示时间,接下来我们实现鼠标点击某个时间进行弹框。

效果

实现

1.监听鼠标按下事件

2.编写弹框页面

3.时间转换

javascript 复制代码
<template>
  <div>
      <canvas id="rulerCanvas" width="1200" height="400"></canvas>

     <el-dialog v-model="dialogVisible" title="添加调料" width="500">
          <div>
              <el-input v-model="input1" style="width: 240px" />
          </div>
          <div style="margin-top: 10px">
              <el-input v-model="input2" style="width: 240px" />
          </div>
          <template #footer>
              <div>
                  <el-button @click="dialogVisible = false">取消</el-button>
                  <el-button type="primary" @click="dialogVisible = false">确认</el-button>
              </div>
          </template>
      </el-dialog>
  </div>
</template>
<script setup>
import * as fabric  from 'fabric';
import {ref, onMounted} from 'vue';
 
 
const canvas = ref(null);

const value1 = ref(true);
const dialogVisible = ref(false);
const input1 = ref("测试商品名称");
const input2 = ref("");
const dialogConfirm = () => {
  dialogVisible.value = false;
  console.log("====添加====")
};

 
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 onMouseDown = (options) => {
  if (value1.value) {
    console.log("====onMouseMove====", options);
    let startNumber = options.pointer.x - 40;
    let timeNumber = parseInt(startNumber / 20);
    input2.value = timeToStr(timeNumber);
    dialogVisible.value = true;
  }
};

const drawRuler = () => {
  canvas.value = new fabric.Canvas('rulerCanvas');
 
  // 鼠标事件
  canvas.value.on('mouse:move', onMouseMove);

  canvas.value.on('mouse:down', onMouseDown);

  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>

如果侵权请联系我删除。

相关推荐
白兰地空瓶12 小时前
🚀 10 分钟吃透 CSS position 定位!从底层原理到避坑实战,搞定所有布局难题
前端·css
T___T12 小时前
Ajax 数据请求详解与实战
javascript·面试
onthewaying12 小时前
在Android平台上使用Three.js优雅的加载3D模型
android·前端·three.js
冴羽12 小时前
能让 GitHub 删除泄露的苹果源码还有 8000 多个相关仓库的 DMCA 是什么?
前端·javascript·react.js
悟能不能悟12 小时前
jsp怎么拿到url参数
java·前端·javascript
程序猿小蒜13 小时前
基于SpringBoot的企业资产管理系统开发与设计
java·前端·spring boot·后端·spring
Mapmost13 小时前
零代码+三维仿真!实现自然灾害的可视化模拟与精准预警
前端
程序猿_极客13 小时前
JavaScript 的 Web APIs 入门到实战全总结(day7):从数据处理到交互落地的全链路实战(附实战案例代码)
开发语言·前端·javascript·交互·web apis 入门到实战
suzumiyahr13 小时前
用awesome-digital-human-live2d创建属于自己的数字人
前端·人工智能·后端
计算机学姐13 小时前
基于SpringBoot的健身房管理系统【智能推荐算法+可视化统计】
java·vue.js·spring boot·后端·mysql·spring·推荐算法