user1
2024-06-28 c7b33fe92cf6d4449ca5919353c15611ae9ad410
src/components/graffiti/index.vue
@@ -1,3 +1,4 @@
<!-- 涂色连线题控件 -->
<template>
  <div class="page">
    <div class="main">
@@ -5,7 +6,6 @@
        <canvas
          id="canvas"
          :style="{
            backgroundImage: `url(${backgroundImage})`,
            backgroundSize: 'cover',
            backgroundPosition: 'center',
          }"
@@ -38,7 +38,7 @@
    return {
      canvas: null,
      context: null,
      painting: false,
      painting: false,  // 记录状态,鼠标是否在按下状态
      historyData: [], // 存储历史数据,用于撤销
      brushSize: 5, // 笔刷大小
      brushColor: "#000000", // 笔刷颜色
@@ -68,18 +68,39 @@
      this.canvas.addEventListener("mouseleave", this.closePaint);
    }
    this.toolClear();
    const oldData = localStorage.getItem('graffiti-data')
    const oldData = localStorage.getItem(this.config.activeBook.name + '-graffiti-' + this.page)
    if(oldData) {
      this.backgroundImage = oldData
    }
  },
  // watch:{
  //   backgroundImage:{
  //     handler(newValue) {
  //       if(newValue && this.context) {
  //         const imgData = new Image();
  //         // 分两种情况,初次的图片 直接用外部链接,需要加跨域和时间戳,二次保存的作为背景则不需要
  //         const oldData = localStorage.getItem(this.config.activeBook.name + '-graffiti-' + this.page)
  //         if(oldData) {
  //           imgData.src = newValue
  //         } else {
  //           imgData.src = newValue + '?' + new Date().getTime();
  //           imgData.setAttribute('crossOrigin', '');
  //         }
  //         imgData.onload = () => {
  //           this.context.drawImage(imgData,0,0)
  //         }
  //       }
  //     }
  //   }
  // },
  methods: {
    changeBackground(imgUrl) {
      this.backgroundImage = imgUrl;
    },
    // 初始化 画布,设置大小背景色
    initCanvas() {
      const that = this
      function resetCanvas() {
      const resetCanvas = () => {
        const elPanel = document.getElementById("canvas_panel");
        that.canvas.width = elPanel.clientWidth;
        that.canvas.height = elPanel.clientHeight;
@@ -90,9 +111,22 @@
        that.context.fillRect(0, 0, that.canvas.width, that.canvas.height);
        that.context.fillStyle = "black";
        that.getCanvasOffset(); // 更新画布位置
        // 设置画布背景图
        const imgData = new Image();
        // 分两种情况,初次的图片 直接用外部链接,需要加跨域和时间戳,二次保存的作为背景则不需要
        const oldData = localStorage.getItem(this.config.activeBook.name + '-graffiti-' + this.page)
        if(oldData) {
          imgData.src = oldData
        } else {
          imgData.src = this.backgroundImage + '?' + new Date().getTime();
          imgData.setAttribute('crossOrigin', '');
        }
        imgData.onload = () => {
          this.context.drawImage(imgData,0,0)
        }
      }
      resetCanvas();
      // 监听窗口大小 ,窗口改变重新渲染画布
      window.addEventListener("resize", resetCanvas);
    },
@@ -110,7 +144,7 @@
        y: y - this.canvasOffset.top,
      };
    },
    // 鼠标抬起方法
    downCallback(event) {
      // 先保存之前的数据,用于撤销时恢复(绘制前保存,不是绘制后再保存)
      const data = this.context.getImageData(
@@ -129,7 +163,7 @@
        this.brushTool === "eraser" ? "#FFFFFF" : this.brushColor;
      this.painting = true;
    },
    // 鼠标移动方法(计算坐标并渲染轨迹)
    moveCallback(event) {
      if (!this.painting) {
        return;
@@ -142,19 +176,21 @@
    closePaint() {
      this.painting = false;
    },
    // 重新计算画布的偏移值
    updateCanvasOffset() {
      this.getCanvasOffset(); // 重新计算画布的偏移值
      this.getCanvasOffset();
    },
    // 改变笔刷大小
    onChangeSize(size) {
      this.brushSize = size;
    },
    // 改变笔刷颜色
    onChangeColor(color) {
      this.brushColor = color;
    },
    // 保存,清空等按钮
    onChangeTool(tool) {
      this.brushTool = tool;
      console.log(tool);
      switch (tool) {
        case "clear":
          this.toolClear();
@@ -167,16 +203,30 @@
          break;
      }
    },
    // 清空canvas所有内容(背景图除外)
    toolClear() {
      this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
      this.resetToolActive();
      // 新加内容,清空后将背景图再设置上去
      const imgData = new Image();
      // 分两种情况,初次的图片 直接用外部链接,需要加跨域和时间戳,二次保存的作为背景则不需要
      const oldData = localStorage.getItem(this.config.activeBook.name + '-graffiti-' + this.page)
      if(oldData) {
        imgData.src = oldData
      } else {
        imgData.src = this.backgroundImage + '?' + new Date().getTime();
        imgData.setAttribute('crossOrigin', '');
      }
      imgData.onload = () => {
        this.context.drawImage(imgData,0,0)
      }
    },
    // 原保存方法
    // 保存画布背景和划线到本地方法
    toolSave() {
      var imgData = this.canvas.toDataURL({format: 'png', quality:1, width:800,});
      localStorage.setItem('graffiti-data',imgData)
      localStorage.setItem(this.config.activeBook.name + '-graffiti-' + this.page,imgData)
    },
    // 保存方法,保存为一张图片并下载
    // 保存为一张图片并下载的方法
    saveImgData() {
      var link = document.createElement("a");
      var imgData = this.canvas.toDataURL({format: 'png', quality:1, width:20000, height:4000});
@@ -196,11 +246,14 @@
        return new Blob([u8arr], {type:mime});
      }
    },
    // 返回上一步方法(撤销)
    toolUndo() {
      //
      if (this.historyData.length <= 0) {
        this.resetToolActive();
        return;
      }
      // 将画的上一步数据写入canvas 重新渲染
      const lastIndex = this.historyData.length - 1;
      this.context.putImageData(this.historyData[lastIndex], 0, 0);
      this.historyData.pop();