Vue3中使用paper.js

Paper.js的使用

在这里插入图片描述

安装Paper

npm install paper

引入Paper.js

import * as Paper from "paper";

创建画布

// 创建画布
<template>
  <canvas id="myCanvas" ref="myCanvas"></canvas>
</template>

实例化Paper、Project以及Tool

const paperInstance = new Paper.PaperScope();
let project: null | paper.Project = null;//全局项目,用来设置图层、导入导出数据等
const tool = new Paper.Tool();//全局工具,用来监听事件

onMounted(() => {
  paperInstance.setup(document.getElementById("myCanvas") as HTMLCanvasElement);
  project = new Paper.Project(
    document.getElementById("myCanvas") as HTMLCanvasElement
  );
  tool.activate();
});

画圆

const drawCircle = () => {
  const circle = new Paper.Path.Circle({
    center: [200, 100], //中心点  或者使用new Path.Point(200,100)
    radius: 50, //半径
    fillColor: new Paper.Color("red"), //填充颜色
    strokeColor: new Paper.Color("black"), //边框颜色
  });
  circle.strokeWidth = 2;
};

画点和线

const drawPointAndLine = () => {
  const point = new Paper.Point(500, 100); //点位置
  const path = new Paper.Path(); //需要path才能画出来
  // point.selected = true; //选中样式
  path.add(point); // 将点添加到路径中
  const copyPoint = point.clone(); // 克隆点
  copyPoint.set(600, 100); // 设置克隆点的位置
  path.add(copyPoint); // 将克隆点添加到路径中 2个点形成一条线
  path.strokeColor = new Paper.Color("black"); // 设置路径的边框颜色
  path.strokeWidth = 4;
  path.selected = true; // 选中路径
};

画矩形

const drawRectangle = () => {
  // 方式一
  const rect1 = new Paper.Path.Rectangle({
    center: [200, 400], //中心点
    size: [50, 100], //边长
    radius: [5, 5], //圆角
    fillColor: "orange",
    strokeColor: "black",
    strokeWidth: 4,
    rotation: 45, //旋转角度
    selected: true, //选中样式
  });
  // 方式二
  const topLeft = new Paper.Point(200, 20); //坐上角位置
  const rectSize = new Paper.Size(200, 200); //大小
  const rect2 = new Paper.Rectangle(topLeft, rectSize); //通过坐上角和大小创建矩形 还可以通过坐上角和右下角创建矩形等
  const radius = new Paper.Size(30, 30); //圆角
  const path = new Paper.Path.Rectangle(rect2, radius); //将矩形通过path画出来
  path.fillColor = new Paper.Color("blue");
  path.position.set({
    x: 300,
    y: 300,
  });
  path.selected = true;
};

导入图片

import Demo1 from "../../assets/demo1.jpg";

const drawImg = () => {
  const img = new Paper.Raster(Demo1);
  img.position.set(700, 600);
  img.scale(0.2);
};

画文字

const drawText = () => {
  const text = new Paper.PointText({
    position: [500, 200], //文本位置
    fillColor: "black",
    justification: "center",
    fontSize: 20, //字体大小
    content: "测试文字",
    locked: false, //锁定
  });
};

Item组

  const drawGroup = () => {
  const group = new Paper.Group();
  const text = new Paper.PointText({
    position: [0, -50 - 10], //文本位置
    content: "圆",
    fillColor: "black",
    justification: "center",
    fontSize: 20, //字体大小
  });
  const circle = new Paper.Path.Circle({
    center: [0, 0], //中心点
    radius: 50, //半径
    fillColor: "red", //填充颜色
  });
  group.addChildren([text, circle]);
  group.position.set(1200, 800);
};

曲线

const drawCurve = () => {
  const group = new Paper.Group();
  const earth = new Paper.Path.Circle({
    center: [800, 200],
    radius: 50,
    fillColor: new Paper.Color("green"),
  });

  var firstPoint1 = calculatePointOnCircle(800, 200, 50, (Math.PI / 18) * 19);
  var secondPoint1 = calculatePointOnCircle(800, 200, 50, (Math.PI / 18) * 1);
  var handleOut1 = new Paper.Point(160, 60);
  var handleIn1 = new Paper.Point(-160, 20);
  var firstSegment = new Paper.Segment(firstPoint1, undefined, handleIn1);
  var secondSegment = new Paper.Segment(secondPoint1, handleOut1, undefined);
  const curve1 = new Paper.Path([firstSegment, secondSegment]);
  curve1.strokeColor = new Paper.Color("black");
  curve1.strokeWidth = 8;
  curve1.locked = true;
  curve1.selected = false;

  group.addChildren([earth, curve1]);
};

监听键盘事件

const onKeyDown = () => {
   // 通过tool来监听
  tool.onKeyDown = (event: any) => {
    console.log(event);
    if (event.event.key === "z" && event.event.ctrlKey) {
    }
  };
};

监听鼠标事件

const onMouse = () => {
  const children = project?.activeLayer.children; //获取所有的item
  // 全局的鼠标事件
  tool.onMouseDown = (event: any) => {
    if (!event.item) {
      children?.forEach((item: any) => {
        item.selected = false;
      });
    } else {
      children?.forEach((item: any) => {
        item.selected = false;
      });
      event.item.selected = true;
    }
  };
  // 单个item的事件
  children?.forEach((item: any) => {
    // 每个item添加按下鼠标事件
    item.onMouseDown = () => {
      project?.activeLayer.addChild(item);//提高层级
      item.selected = true;
    };
    // 每个item添加鼠标拖动事件
    item.onMouseDrag = (event: paper.MouseEvent) => {
      item.position.set(
        item.position.x + event.delta.x,
        item.position.y + event.delta.y
      );
    };
  });
};

设置动画

let direction = "right";
const drawAnimate = () => {
  const node = new Paper.Path.Circle({
    center: [200, 100],
    radius: 50,
  });
  node.strokeColor = new Paper.Color("black");
  node.fillColor = new Paper.Color("white");
  node.onFrame = () => {
    const maxWidth = document.body.clientWidth;
    if (direction === "right") {
      if (node.bounds.right >= maxWidth) {
        direction = "left";
      }
    } else {
      if (node.bounds.left <= 0) {
        direction = "right";
      }
    }
    if (direction === "right") {
      node.bounds.x += 5;
    } else {
      node.bounds.x -= 5;
    }
  };
};

动画线

const drawAnimateLine = () => {
  const line = new Paper.Path.Line({
    from: [1200, 200],
    to: [1200, 600],
    strokeColor: new Paper.Color("red"),
    strokeWidth: 8,
  });
  line.style.dashArray = [10, 10];
  line.onFrame = () => {
    line.style.dashOffset -= 1;
    if (line.style.dashOffset <= 0) {
      line.style.dashOffset = 100;
    }
  };
};

下载成图片

const screenShot = () => {
  // 获取svg元素,将整个canvas导出为svg
  const flash = project?.exportSVG();
  // 将SVG元素转换为字符串
  var serializer = new XMLSerializer();
  var xmlString = serializer.serializeToString(flash as SVGAElement);
  // 创建一个Blob对象
  var blob = new Blob([xmlString], { type: "image/svg+xml;charset=utf-8" });
  // 创建一个指向该Blob的URL
  var url = URL.createObjectURL(blob);
  // 创建一个a标签
  var a = document.createElement("a");
  a.href = url;
  a.download = "my-svg-file.svg";
  // 将a标签添加到文档中,触发点击事件,然后将其从文档中删除
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
};

缩放画布

const mouseWheel = (e: any) => {
  paperInstance.view.zoom = paperInstance.view.zoom * (1 + e.wheelDelta / 1000);
};

onMounted(() => {
  canvasEl.addEventListener("wheel", mouseWheel);
});
onUnmounted(() => {
  const canvasEl = document.getElementById("myCanvas") as HTMLCanvasElement;
  canvasEl.removeEventListener("wheel", mouseWheel);
});

拖拽画布

const downPoint = {
  x: 0,
  y: 0,
};
let zoom = 1;

const mouseMove = (e: any) => {
  const translateX = e.x - downPoint.x;
  const translateY = e.y - downPoint.y;
  // 移动距离 需要除以缩放比例否则移动会 过快或慢
  paperInstance.view.translate({
    x: translateX / zoom,
    y: translateY / zoom,
  });
  downPoint.x = e.x;
  downPoint.y = e.y;
};

const cancelMove = () => {
  const canvasEl = document.getElementById("myCanvas") as HTMLCanvasElement;
  canvasEl.removeEventListener("mousemove", mouseMove);
  canvasEl.removeEventListener("mouseup", cancelMove);
};

onMounted(() => {
  paperInstance.view.onMouseDown = (e: paper.MouseEvent) => {
    const ele = e.target as unknown as paper.View;
    if (ele === paperInstance.view) {
      //只有拖canvas才能拖动
      downPoint.x = e.x;
      downPoint.y = e.y;
      zoom = paperInstance.view.zoom;
      canvasEl.addEventListener("mousemove", mouseMove);
      canvasEl.addEventListener("mouseup", cancelMove);
    }
  };
});

自定义选中样式和拖拽边角进行放大缩小

  const addSelect = (item: paper.Item) => {
    const rect = new Paper.Path.Rectangle({
      center: item.bounds.center, //中心点
      size: item.bounds.size, //边长
      strokeColor: new Paper.Color("blue"),
      strokeWidth: 1,
    });
    const topLeftRect = new Paper.Path.Rectangle({
      center: item.bounds.topLeft, //中心点
      size: [10, 10], //边长
      fillColor: new Paper.Color("#fff"),
      strokeColor: new Paper.Color("blue"),
      strokeWidth: 1,
      name: "topLeftRect",
    });
    const topRightRect = new Paper.Path.Rectangle({
      center: item.bounds.topRight, //中心点
      size: [10, 10], //边长
      fillColor: new Paper.Color("#fff"),
      strokeColor: new Paper.Color("blue"),
      strokeWidth: 1,
      name: "topRightRect",
    });
    const bottomLeftRect = new Paper.Path.Rectangle({
      center: item.bounds.bottomLeft, //中心点
      size: [10, 10], //边长
      fillColor: new Paper.Color("#fff"),
      strokeColor: new Paper.Color("blue"),
      strokeWidth: 1,
      name: "bottomLeftRect",
    });
    const bottomRightRect = new Paper.Path.Rectangle({
      center: item.bounds.bottomRight, //中心点
      size: [10, 10], //边长
      fillColor: new Paper.Color("#fff"),
      strokeColor: new Paper.Color("blue"),
      strokeWidth: 1,
      name: "bottomRightRect",
    });
    const topCenterRect = new Paper.Path.Rectangle({
      center: item.bounds.topCenter, //中心点
      size: [10, 10], //边长
      fillColor: new Paper.Color("#fff"),
      strokeColor: new Paper.Color("blue"),
      strokeWidth: 1,
      name: "topCenterRect",
    });
    const leftCenterRect = new Paper.Path.Rectangle({
      center: item.bounds.leftCenter, //中心点
      size: [10, 10], //边长
      fillColor: new Paper.Color("#fff"),
      strokeColor: new Paper.Color("blue"),
      strokeWidth: 1,
      name: "leftCenterRect",
    });
    const rightCenterRect = new Paper.Path.Rectangle({
      center: item.bounds.rightCenter, //中心点
      size: [10, 10], //边长
      fillColor: new Paper.Color("#fff"),
      strokeColor: new Paper.Color("blue"),
      strokeWidth: 1,
      name: "rightCenterRect",
    });
    const bottomCenterRect = new Paper.Path.Rectangle({
      center: item.bounds.bottomCenter, //中心点
      size: [10, 10], //边长
      fillColor: new Paper.Color("#fff"),
      strokeColor: new Paper.Color("blue"),
      strokeWidth: 1,
      name: "bottomCenterRect",
    });
    // 将矩形和四个角添加到组中
    const g1 = new Paper.Group([
      rect,
      topLeftRect,
      topRightRect,
      bottomLeftRect,
      bottomRightRect,
      topCenterRect,
      leftCenterRect,
      rightCenterRect,
      bottomCenterRect,
    ]);
    // 将选择框和当前元素添加到组中,目的是统一选择框和当前元素的拖拽缩放等
    const g2 = new Paper.Group([item, g1]);
    // 配置了drag才开启
    if (config.itemHandle?.includes("drag")) {
      g2.onMouseDrag = (e: paper.MouseEvent) => {
        e.stopPropagation();
        g2.position.set(
          item.position.x + e.delta.x,
          item.position.y + e.delta.y
        );
      };
    }
    topLeftRect.onMouseDrag = (e: paper.MouseEvent) => {
      e.stopPropagation();
      if (
        item.bounds.size.height - e.delta.y <= 20 ||
        item.bounds.size.width - e.delta.x <= 20
      ) {
        return;
      }
      item.bounds.center.y += e.delta.y;
      item.bounds.center.x += e.delta.x;
      item.bounds.size.height -= e.delta.y;
      item.bounds.size.width -= e.delta.x;

      rect.bounds.center.y += e.delta.y;
      rect.bounds.center.x += e.delta.x;
      rect.bounds.size.height -= e.delta.y;
      rect.bounds.size.width -= e.delta.x;

      // 左上 xy
      topLeftRect.bounds.x += e.delta.x;
      topLeftRect.bounds.y += e.delta.y;
      // 右上 y
      topRightRect.bounds.y += e.delta.y;
      // 左下 x
      bottomLeftRect.bounds.x += e.delta.x;
      // 上中 xy
      topCenterRect.bounds.y += e.delta.y;
      topCenterRect.bounds.x += e.delta.x / 2;
      // 左中 xy
      leftCenterRect.bounds.y += e.delta.y / 2;
      leftCenterRect.bounds.x += e.delta.x;
      // 右中 y
      rightCenterRect.bounds.y += e.delta.y / 2;
      // 下中 x
      bottomCenterRect.bounds.x += e.delta.x / 2;
    };
    topRightRect.onMouseDrag = (e: paper.MouseEvent) => {
      e.stopPropagation();
      if (
        item.bounds.size.height - e.delta.y <= 20 ||
        item.bounds.size.width + e.delta.x <= 20
      ) {
        return;
      }
      item.bounds.center.y += e.delta.y;
      item.bounds.size.height -= e.delta.y;
      item.bounds.size.width += e.delta.x;

      rect.bounds.center.y += e.delta.y;
      rect.bounds.size.height -= e.delta.y;
      rect.bounds.size.width += e.delta.x;

      // 右上 xy
      topRightRect.bounds.x += e.delta.x;
      topRightRect.bounds.y += e.delta.y;
      // 左上 y
      topLeftRect.bounds.y += e.delta.y;
      // 右下 x
      bottomRightRect.bounds.x += e.delta.x;
      // 上中 xy
      topCenterRect.bounds.y += e.delta.y;
      topCenterRect.bounds.x += e.delta.x / 2;
      // 左中 y
      leftCenterRect.bounds.y += e.delta.y / 2;
      // 右中 xy
      rightCenterRect.bounds.y += e.delta.y / 2;
      rightCenterRect.bounds.x += e.delta.x;
      // 下中 x
      bottomCenterRect.bounds.x += e.delta.x / 2;
    };
    bottomLeftRect.onMouseDrag = (e: paper.MouseEvent) => {
      e.stopPropagation();
      if (
        item.bounds.size.height + e.delta.y <= 20 ||
        item.bounds.size.width - e.delta.x <= 20
      ) {
        return;
      }
      item.bounds.center.x += e.delta.x;
      item.bounds.size.height += e.delta.y;
      item.bounds.size.width -= e.delta.x;

      rect.bounds.center.x += e.delta.x;
      rect.bounds.size.height += e.delta.y;
      rect.bounds.size.width -= e.delta.x;

      // 左下 xy
      bottomLeftRect.bounds.x += e.delta.x;
      bottomLeftRect.bounds.y += e.delta.y;
      // 坐上 x
      topLeftRect.bounds.x += e.delta.x;
      // 右下 y
      bottomRightRect.bounds.y += e.delta.y;
      // 上中 x
      topCenterRect.bounds.x += e.delta.x / 2;
      // 左中 xy
      leftCenterRect.bounds.y += e.delta.y / 2;
      leftCenterRect.bounds.x += e.delta.x;
      // 右中 y
      rightCenterRect.bounds.y += e.delta.y / 2;
      // 下中 xy
      bottomCenterRect.bounds.y += e.delta.y;
      bottomCenterRect.bounds.x += e.delta.x / 2;
    };
    bottomRightRect.onMouseDrag = (e: paper.MouseEvent) => {
      e.stopPropagation();
      if (
        item.bounds.size.height + e.delta.y <= 20 ||
        item.bounds.size.width + e.delta.x <= 20
      ) {
        return;
      }
      item.bounds.size.height += e.delta.y;
      item.bounds.size.width += e.delta.x;

      rect.bounds.size.height += e.delta.y;
      rect.bounds.size.width += e.delta.x;

      // 右下
      bottomRightRect.bounds.x += e.delta.x;
      bottomRightRect.bounds.y += e.delta.y;
      // 右上 x
      topRightRect.bounds.x += e.delta.x;
      // 左下 y
      bottomLeftRect.bounds.y += e.delta.y;
      // 上中 x
      topCenterRect.bounds.x += e.delta.x / 2;
      // 左中 y
      leftCenterRect.bounds.y += e.delta.y / 2;
      // 右中 xy
      rightCenterRect.bounds.y += e.delta.y / 2;
      rightCenterRect.bounds.x += e.delta.x;
      // 下中 xy
      bottomCenterRect.bounds.y += e.delta.y;
      bottomCenterRect.bounds.x += e.delta.x / 2;
    };
    topCenterRect.onMouseDrag = (e: paper.MouseEvent) => {
      e.stopPropagation();
      if (item.bounds.size.height - e.delta.y <= 20) {
        return;
      }
      item.bounds.center.y += e.delta.y;
      item.bounds.size.height -= e.delta.y;

      rect.bounds.center.y += e.delta.y;
      rect.bounds.size.height -= e.delta.y;

      // 左上 y
      topLeftRect.bounds.y += e.delta.y;
      // 右上 y
      topRightRect.bounds.y += e.delta.y;
      // 上中 y
      topCenterRect.bounds.y += e.delta.y;
      // 左中 y
      leftCenterRect.bounds.y += e.delta.y / 2;
      // 右中 y
      rightCenterRect.bounds.y += e.delta.y / 2;
    };
    leftCenterRect.onMouseDrag = (e: paper.MouseEvent) => {
      e.stopPropagation();
      if (item.bounds.size.width - e.delta.x <= 20) {
        return;
      }
      item.bounds.center.x += e.delta.x;
      item.bounds.size.width -= e.delta.x;

      rect.bounds.center.x += e.delta.x;
      rect.bounds.size.width -= e.delta.x;

      // 左上 x
      topLeftRect.bounds.x += e.delta.x;
      // 左下 x
      bottomLeftRect.bounds.x += e.delta.x;
      // 左中 x
      leftCenterRect.bounds.x += e.delta.x;
      // 上中 x
      topCenterRect.bounds.x += e.delta.x / 2;
      // 下中 x
      bottomCenterRect.bounds.x += e.delta.x / 2;
    };
    bottomCenterRect.onMouseDrag = (e: paper.MouseEvent) => {
      e.stopPropagation();
      if (item.bounds.size.height + e.delta.y <= 20) {
        return;
      }
      item.bounds.size.height += e.delta.y;

      rect.bounds.size.height += e.delta.y;

      // 左下 y
      bottomLeftRect.bounds.y += e.delta.y;
      // 右下 y
      bottomRightRect.bounds.y += e.delta.y;
      // 下中 y
      bottomCenterRect.bounds.y += e.delta.y;
      // 左中 y
      leftCenterRect.bounds.y += e.delta.y / 2;
      // 右中 y
      rightCenterRect.bounds.y += e.delta.y / 2;
    };
    rightCenterRect.onMouseDrag = (e: paper.MouseEvent) => {
      e.stopPropagation();
      if (item.bounds.size.width + e.delta.x <= 20) {
        return;
      }
      item.bounds.size.width += e.delta.x;

      rect.bounds.size.width += e.delta.x;

      // 右上 x
      topRightRect.bounds.x += e.delta.x;
      // 右下 x
      bottomRightRect.bounds.x += e.delta.x;
      // 右中 x
      rightCenterRect.bounds.x += e.delta.x;
      // 上中 x
      topCenterRect.bounds.x += e.delta.x / 2;
      // 下中 x
      bottomCenterRect.bounds.x += e.delta.x / 2;
    };
    [
      topLeftRect,
      topRightRect,
      bottomLeftRect,
      bottomRightRect,
      topCenterRect,
      leftCenterRect,
      rightCenterRect,
      bottomCenterRect,
    ].forEach((item) => {
      item.onMouseLeave = (e: paper.MouseEvent) => {
        e.stopPropagation();
        cursor.value = "default";
      };
      item.onMouseEnter = (e: paper.MouseEvent) => {
        e.stopPropagation();
        switch (e.target.name) {
          case "topLeftRect":
            cursor.value = "nw-resize";
            break;
          case "topRightRect":
            cursor.value = "ne-resize";
            break;
          case "bottomLeftRect":
            cursor.value = "sw-resize";
            break;
          case "bottomRightRect":
            cursor.value = "se-resize";
            break;
          case "topCenterRect":
            cursor.value = "n-resize";
            break;
          case "leftCenterRect":
            cursor.value = "w-resize";
            break;
          case "rightCenterRect":
            cursor.value = "e-resize";
            break;
          case "bottomCenterRect":
            cursor.value = "s-resize";
            break;
        }
      };
    });

    return [g1, g2, item];
  };

完整代码

<template>
  <div class="container">
    <canvas id="myCanvas" ref="canvasEl"></canvas>
  </div>
</template>

<script lang="ts">
export default { name: "Paper" };
</script>
<script lang="ts" setup>
import * as Paper from "paper";
import { onMounted, reactive } from "vue";
import Demo1 from "../../assets/demo1.jpg";
import { CanvasHandle, ItemHandle, usePaper } from "./";

let direction = "right";
const config = reactive({
  zoom: true,
  canvasHandle: "select" as CanvasHandle,
  itemHandle: ["select", "drag"] as ItemHandle,
  tooltips: () => {
    return "123";
  },
});
const { canvasEl, cursor, registerMouseEvent } = usePaper(config);//使用配置进行创建

const drawAnimate = () => {
  const node = new Paper.Path.Circle({
    center: [200, 100],
    radius: 50,
  });
  node.strokeColor = new Paper.Color("black");
  node.fillColor = new Paper.Color("white");
  node.onFrame = () => {
    const maxWidth = document.body.clientWidth;
    if (direction === "right") {
      if (node.bounds.right >= maxWidth) {
        direction = "left";
      }
    } else {
      if (node.bounds.left <= 0) {
        direction = "right";
      }
    }
    if (direction === "right") {
      node.bounds.x += 5;
    } else {
      node.bounds.x -= 5;
    }
  };
};

const drawCircle = () => {
  const circle = new Paper.Path.Circle({
    center: [200, 100], //中心点
    radius: 50, //半径
    fillColor: new Paper.Color("red"), //填充颜色
    strokeColor: new Paper.Color("black"), //边框颜色
    cursor: "pointer",
  });
  circle.strokeWidth = 2;

  const pathData = "M 50 100 L 100 0 L 0 0 Z";
  const path = new Paper.Path(pathData);
  path.strokeColor = new Paper.Color("black");
  path.fillColor = new Paper.Color("green");
  path.strokeWidth = 2;
  path.strokeWidth = 2;
  path.position.set(400, 100);
};

const drawPointAndLine = () => {
  const point = new Paper.Point(500, 100); //点位置
  const path = new Paper.Path(); //需要path才能画出来
  // point.selected = true; //选中样式
  path.add(point); // 将点添加到路径中
  const copyPoint = point.clone(); // 克隆点
  copyPoint.set(600, 100); // 设置克隆点的位置
  path.add(copyPoint); // 将克隆点添加到路径中 2个点形成一条线
  path.strokeColor = new Paper.Color("black"); // 设置路径的边框颜色
  path.strokeWidth = 4;
};

const drawRectangle = () => {
  // 方式一
  const rect1 = new Paper.Path.Rectangle({
    center: [200, 400], //中心点
    size: [50, 100], //边长
    radius: [5, 5], //圆角
    fillColor: "orange",
    strokeColor: "black",
    strokeWidth: 4,
    rotation: 45, //旋转角度
  });
  // 方式二
  const topLeft = new Paper.Point(200, 20); //坐上角位置
  const rectSize = new Paper.Size(200, 200); //大小
  const rect2 = new Paper.Rectangle(topLeft, rectSize); //通过坐上角和大小创建矩形 还可以通过坐上角和右下角创建矩形等
  const radius = new Paper.Size(30, 30); //圆角
  const path = new Paper.Path.Rectangle(rect2, radius); //将矩形通过path画出来
  path.fillColor = new Paper.Color("blue");
  path.position.set({
    x: 300,
    y: 300,
  });
};

const drawImg = () => {
  const img = new Paper.Raster(Demo1);
  const rect2 = new Paper.Rectangle(img.bounds.topLeft, img.bounds.size); //通过坐上角和大小创建矩形 还可以通过坐上角和右下角创建矩形等
  const path = new Paper.Path.Rectangle(rect2);
  path.strokeColor = new Paper.Color("transparent");
  path.strokeWidth = 4;
  img.position.set(700, 600);
  img.scale(0.2);
  // addSelect(img);
};

const drawText = () => {
  const text = new Paper.PointText({
    position: [1600, 50], //文本位置
    fillColor: "black",
    justification: "center",
    fontSize: 20, //字体大小
    content: "下载",
    locked: false, //锁定
    name: "download",
    style: {
      cursor: "pointer",
    },
  });
};

const drawGroup = () => {
  const group = new Paper.Group();
  const text = new Paper.PointText({
    position: [0, -50 - 10], //文本位置
    content: "圆",
    fillColor: "black",
    justification: "center",
    fontSize: 20, //字体大小
  });
  const circle = new Paper.Path.Circle({
    center: [0, 0], //中心点
    radius: 50, //半径
    fillColor: "red", //填充颜色
  });
  group.addChildren([text, circle]);
  group.position.set(1200, 800);
};

const drawCurve = () => {
  const group = new Paper.Group();
  const earth = new Paper.Path.Circle({
    center: [800, 200],
    radius: 50,
    fillColor: new Paper.Color("green"),
  });

  var firstPoint1 = calculatePointOnCircle(800, 200, 50, (Math.PI / 18) * 19);
  var secondPoint1 = calculatePointOnCircle(800, 200, 50, (Math.PI / 18) * 1);
  var handleOut1 = new Paper.Point(160, 60);
  var handleIn1 = new Paper.Point(-160, 20);
  var firstSegment = new Paper.Segment(firstPoint1, undefined, handleIn1);
  var secondSegment = new Paper.Segment(secondPoint1, handleOut1, undefined);
  const curve1 = new Paper.Path([firstSegment, secondSegment]);
  curve1.strokeColor = new Paper.Color("black");
  curve1.strokeWidth = 8;
  curve1.locked = true;
  curve1.selected = false;
  curve1.style.strokeCap = "round"; //圆角

  group.addChildren([earth, curve1]);
};

const drawAnimateLine = () => {
  const line = new Paper.Path.Line({
    from: [1200, 200],
    to: [1200, 600],
    strokeColor: new Paper.Color("red"),
    strokeWidth: 8,
  });
  line.style.dashArray = [10, 10];
  line.onFrame = () => {
    line.style.dashOffset -= 1;
    if (line.style.dashOffset <= 0) {
      line.style.dashOffset = 100;
    }
  };
};

const drawArc = () => {
  const group = new Paper.Group();
  const arc = new Paper.Path.Arc({
    from: [0, 50],
    through: [50, 0],
    to: [50, 100],
    strokeColor: "black",
    fillColor: "red",
    strokeWidth: 4,
  });

  const pathData = "M 50 50 L 50 101 L -1 50 Z";
  const path = new Paper.Path(pathData);
  path.fillColor = new Paper.Color("white");
  path.strokeWidth = 0;
  group.addChildren([arc, path]);
};

const calculatePointOnCircle = (
  centerX: number,
  centerY: number,
  radius: number,
  angle: number
) => {
  var x = centerX + radius * Math.cos(angle);
  var y = centerY + radius * Math.sin(angle);
  return new Paper.Point(x, y);
};

onMounted(() => {
  drawCircle();
  drawPointAndLine();
  drawRectangle();
  drawImg();
  drawText();
  drawGroup();
  drawAnimateLine();
  drawAnimate();
  drawArc();
  setTimeout(() => {
    drawCurve(); //注册事件之后画出来 不会响应事件
    registerMouseEvent(); //需要重新注册一下事件
  }, 3000);
});
</script>

<style lang="scss" scoped>
.container {
  width: 100%;
  height: 100%;
  position: relative;
  #myCanvas {
    width: 100%;
    height: 100%;
    cursor: v-bind(cursor);
  }
  .control {
    div {
      position: absolute;
      width: 10px;
      height: 10px;
      background-color: #fff;
      border: 1px solid blue;
    }
    .top-left {
      cursor: nw-resize;
    }
    .top-right {
      cursor: ne-resize;
    }
    .bottom-left {
      cursor: sw-resize;
    }
    .bottom-right {
      cursor: se-resize;
    }
  }
}
</style>

将元素的拖拽缩放、canvas的拖拽缩放抽离成hook

import { nextTick, onMounted, onUnmounted, ref, toRaw, watch } from "vue";
import * as Paper from "paper";
export type CanvasHandle = "select" | "drag" | "none";
export type ItemHandle = CanvasHandle[] | CanvasHandle;
export interface PaperConfig {
  zoom: boolean;
  canvasHandle: CanvasHandle;
  itemHandle: ItemHandle;
  tooltips: string | (() => string);
}

export const usePaper = (config: PaperConfig) => {
  const defaultConfig: PaperConfig = {
    zoom: true,
    canvasHandle: "drag",
    itemHandle: "none",
    tooltips: "我是提示",
  };
  config = { ...defaultConfig, ...config };

  const paperInstance = ref<paper.PaperScope>(new Paper.PaperScope());
  const canvasEl = ref<HTMLCanvasElement>();
  const zoom = ref(1);
  const selection = ref<paper.Path.Rectangle>();
  const selectionGroup = ref<paper.Item[]>();
  const cursor = ref("default");

  const downPoint = {
    x: 0,
    y: 0,
  };
  const map = new WeakMap();

  watch(
    () => selectionGroup.value,
    (newValue, oldValue) => {
      if (oldValue) {
        oldValue[0].remove();
      }
    }
  );

  const mouseWheel = (e: any) => {
    if (config.zoom) {
      e.preventDefault();
      paperInstance.value.view.zoom =
        paperInstance.value.view.zoom * (1 + e.wheelDelta / 1000);
      zoom.value = paperInstance.value.view.zoom;
    }
  };

  /**
   * @description 处理canvas拖拽选中
   */
  const canvasHandleFn = () => {
    // 鼠标按下操作
    paperInstance.value.view.onMouseDown = (event: paper.MouseEvent | any) => {
      const ele = event.target as unknown as paper.View;
      const view = toRaw(paperInstance.value.view);
      // 开启拖拽画布
      if (config.canvasHandle === "drag") {
        /**
         * @description 拖画布
         */
        const mouseMove = (e: any) => {
          const translateX = e.x - downPoint.x;
          const translateY = e.y - downPoint.y;
          paperInstance.value.view.translate({
            x: translateX / zoom.value,
            y: translateY / zoom.value,
          });
          downPoint.x = e.x;
          downPoint.y = e.y;
        };
        /**
         * @description 取消监听
         */
        const cancelMove = () => {
          canvasEl.value?.removeEventListener("mousemove", mouseMove);
          canvasEl.value?.removeEventListener("mouseup", cancelMove);
        };
        if (ele === view) {
          //只有拖canvas才能拖动
          downPoint.x = event.event.pageX;
          downPoint.y = event.event.pageY;
          zoom.value = paperInstance.value.view.zoom;
          canvasEl.value?.addEventListener("mousemove", mouseMove);
          canvasEl.value?.addEventListener("mouseup", cancelMove);
        }
      }

      //框选 鼠标按下给出框选左上角位置
      if (config.canvasHandle === "select") {
        if (ele === view) {
          selection.value = new Paper.Path.Rectangle(
            event.point,
            new Paper.Size(1, 1)
          );
          selection.value.strokeWidth = 1;
          selection.value.strokeColor = new Paper.Color(0, 0, 0, 0.5);
          selection.value.style.dashArray = [4, 4];
          selection.value.name = "selection";
        }
        if (selectionGroup.value && ele === view) {
          // 处理选中组
          const children = selectionGroup.value[2].removeChildren();
          children?.forEach((item) => {
            item.addTo(paperInstance.value.project);
          });
          selectionGroup.value = undefined;
        }
      }
    };
    paperInstance.value.view.onMouseDrag = (e: paper.MouseEvent) => {
      if (selection.value) {
        selection.value.bounds.width += e.delta.x;
        selection.value.bounds.height += e.delta.y;
      }
    };
    paperInstance.value.view.onMouseUp = (e: paper.MouseEvent) => {
      if (selection.value) {
        let childrens: paper.Item[] = [];
        // 处理选中组
        const chooseItems = paperInstance.value.project.getItems({
          match: (item: paper.Item) => {
            const { topLeft, bottomRight } = item.bounds;
            if (
              topLeft.x > selection.value!.bounds.topLeft.x &&
              topLeft.y > selection.value!.bounds.topLeft.y &&
              bottomRight.x < selection.value!.bounds.bottomRight.x &&
              bottomRight.y < selection.value!.bounds.bottomRight.y
            ) {
              // 处理选中组
              if (item instanceof Paper.Group) {
                childrens.push(...item.children);
                return item;
              } else {
                if (!childrens.includes(item)) {
                  return item;
                }
              }
            }
          },
        });
        console.log(chooseItems);
        if (chooseItems.length) {
          // 将框出来的item 组成一个组 组进行缩放拖拽
          const g = new Paper.Group([...chooseItems]);
          selectionGroup.value = addSelect(g);
          paperInstance.value.project?.activeLayer.addChild(
            selectionGroup.value![1]
          ); //提高层级
        }
        if (selection.value) {
          selection.value!.remove();
          selection.value = undefined;
        }
        downPoint.x = 0;
        downPoint.y = 0;
      }
    };
  };

  /**
   * @description 添加选择框 并注册事件
   */
  const addSelect = (item: paper.Item) => {
    const rect = new Paper.Path.Rectangle({
      center: item.bounds.center, //中心点
      size: item.bounds.size, //边长
      strokeColor: new Paper.Color("blue"),
      strokeWidth: 1,
    });
    const topLeftRect = new Paper.Path.Rectangle({
      center: item.bounds.topLeft, //中心点
      size: [10, 10], //边长
      fillColor: new Paper.Color("#fff"),
      strokeColor: new Paper.Color("blue"),
      strokeWidth: 1,
      name: "topLeftRect",
    });
    const topRightRect = new Paper.Path.Rectangle({
      center: item.bounds.topRight, //中心点
      size: [10, 10], //边长
      fillColor: new Paper.Color("#fff"),
      strokeColor: new Paper.Color("blue"),
      strokeWidth: 1,
      name: "topRightRect",
    });
    const bottomLeftRect = new Paper.Path.Rectangle({
      center: item.bounds.bottomLeft, //中心点
      size: [10, 10], //边长
      fillColor: new Paper.Color("#fff"),
      strokeColor: new Paper.Color("blue"),
      strokeWidth: 1,
      name: "bottomLeftRect",
    });
    const bottomRightRect = new Paper.Path.Rectangle({
      center: item.bounds.bottomRight, //中心点
      size: [10, 10], //边长
      fillColor: new Paper.Color("#fff"),
      strokeColor: new Paper.Color("blue"),
      strokeWidth: 1,
      name: "bottomRightRect",
    });
    const topCenterRect = new Paper.Path.Rectangle({
      center: item.bounds.topCenter, //中心点
      size: [10, 10], //边长
      fillColor: new Paper.Color("#fff"),
      strokeColor: new Paper.Color("blue"),
      strokeWidth: 1,
      name: "topCenterRect",
    });
    const leftCenterRect = new Paper.Path.Rectangle({
      center: item.bounds.leftCenter, //中心点
      size: [10, 10], //边长
      fillColor: new Paper.Color("#fff"),
      strokeColor: new Paper.Color("blue"),
      strokeWidth: 1,
      name: "leftCenterRect",
    });
    const rightCenterRect = new Paper.Path.Rectangle({
      center: item.bounds.rightCenter, //中心点
      size: [10, 10], //边长
      fillColor: new Paper.Color("#fff"),
      strokeColor: new Paper.Color("blue"),
      strokeWidth: 1,
      name: "rightCenterRect",
    });
    const bottomCenterRect = new Paper.Path.Rectangle({
      center: item.bounds.bottomCenter, //中心点
      size: [10, 10], //边长
      fillColor: new Paper.Color("#fff"),
      strokeColor: new Paper.Color("blue"),
      strokeWidth: 1,
      name: "bottomCenterRect",
    });
    // 将矩形和四个角添加到组中
    const g1 = new Paper.Group([
      rect,
      topLeftRect,
      topRightRect,
      bottomLeftRect,
      bottomRightRect,
      topCenterRect,
      leftCenterRect,
      rightCenterRect,
      bottomCenterRect,
    ]);
    // 将选择框和当前元素添加到组中,目的是统一选择框和当前元素的拖拽缩放等
    const g2 = new Paper.Group([item, g1]);
    // 配置了drag才开启
    if (config.itemHandle?.includes("drag")) {
      g2.onMouseDrag = (e: paper.MouseEvent) => {
        e.stopPropagation();
        g2.position.set(
          item.position.x + e.delta.x,
          item.position.y + e.delta.y
        );
      };
    }
    topLeftRect.onMouseDrag = (e: paper.MouseEvent) => {
      e.stopPropagation();
      if (
        item.bounds.size.height - e.delta.y <= 20 ||
        item.bounds.size.width - e.delta.x <= 20
      ) {
        return;
      }
      item.bounds.center.y += e.delta.y;
      item.bounds.center.x += e.delta.x;
      item.bounds.size.height -= e.delta.y;
      item.bounds.size.width -= e.delta.x;

      rect.bounds.center.y += e.delta.y;
      rect.bounds.center.x += e.delta.x;
      rect.bounds.size.height -= e.delta.y;
      rect.bounds.size.width -= e.delta.x;

      // 左上 xy
      topLeftRect.bounds.x += e.delta.x;
      topLeftRect.bounds.y += e.delta.y;
      // 右上 y
      topRightRect.bounds.y += e.delta.y;
      // 左下 x
      bottomLeftRect.bounds.x += e.delta.x;
      // 上中 xy
      topCenterRect.bounds.y += e.delta.y;
      topCenterRect.bounds.x += e.delta.x / 2;
      // 左中 xy
      leftCenterRect.bounds.y += e.delta.y / 2;
      leftCenterRect.bounds.x += e.delta.x;
      // 右中 y
      rightCenterRect.bounds.y += e.delta.y / 2;
      // 下中 x
      bottomCenterRect.bounds.x += e.delta.x / 2;
    };
    topRightRect.onMouseDrag = (e: paper.MouseEvent) => {
      e.stopPropagation();
      if (
        item.bounds.size.height - e.delta.y <= 20 ||
        item.bounds.size.width + e.delta.x <= 20
      ) {
        return;
      }
      item.bounds.center.y += e.delta.y;
      item.bounds.size.height -= e.delta.y;
      item.bounds.size.width += e.delta.x;

      rect.bounds.center.y += e.delta.y;
      rect.bounds.size.height -= e.delta.y;
      rect.bounds.size.width += e.delta.x;

      // 右上 xy
      topRightRect.bounds.x += e.delta.x;
      topRightRect.bounds.y += e.delta.y;
      // 左上 y
      topLeftRect.bounds.y += e.delta.y;
      // 右下 x
      bottomRightRect.bounds.x += e.delta.x;
      // 上中 xy
      topCenterRect.bounds.y += e.delta.y;
      topCenterRect.bounds.x += e.delta.x / 2;
      // 左中 y
      leftCenterRect.bounds.y += e.delta.y / 2;
      // 右中 xy
      rightCenterRect.bounds.y += e.delta.y / 2;
      rightCenterRect.bounds.x += e.delta.x;
      // 下中 x
      bottomCenterRect.bounds.x += e.delta.x / 2;
    };
    bottomLeftRect.onMouseDrag = (e: paper.MouseEvent) => {
      e.stopPropagation();
      if (
        item.bounds.size.height + e.delta.y <= 20 ||
        item.bounds.size.width - e.delta.x <= 20
      ) {
        return;
      }
      item.bounds.center.x += e.delta.x;
      item.bounds.size.height += e.delta.y;
      item.bounds.size.width -= e.delta.x;

      rect.bounds.center.x += e.delta.x;
      rect.bounds.size.height += e.delta.y;
      rect.bounds.size.width -= e.delta.x;

      // 左下 xy
      bottomLeftRect.bounds.x += e.delta.x;
      bottomLeftRect.bounds.y += e.delta.y;
      // 坐上 x
      topLeftRect.bounds.x += e.delta.x;
      // 右下 y
      bottomRightRect.bounds.y += e.delta.y;
      // 上中 x
      topCenterRect.bounds.x += e.delta.x / 2;
      // 左中 xy
      leftCenterRect.bounds.y += e.delta.y / 2;
      leftCenterRect.bounds.x += e.delta.x;
      // 右中 y
      rightCenterRect.bounds.y += e.delta.y / 2;
      // 下中 xy
      bottomCenterRect.bounds.y += e.delta.y;
      bottomCenterRect.bounds.x += e.delta.x / 2;
    };
    bottomRightRect.onMouseDrag = (e: paper.MouseEvent) => {
      e.stopPropagation();
      if (
        item.bounds.size.height + e.delta.y <= 20 ||
        item.bounds.size.width + e.delta.x <= 20
      ) {
        return;
      }
      item.bounds.size.height += e.delta.y;
      item.bounds.size.width += e.delta.x;

      rect.bounds.size.height += e.delta.y;
      rect.bounds.size.width += e.delta.x;

      // 右下
      bottomRightRect.bounds.x += e.delta.x;
      bottomRightRect.bounds.y += e.delta.y;
      // 右上 x
      topRightRect.bounds.x += e.delta.x;
      // 左下 y
      bottomLeftRect.bounds.y += e.delta.y;
      // 上中 x
      topCenterRect.bounds.x += e.delta.x / 2;
      // 左中 y
      leftCenterRect.bounds.y += e.delta.y / 2;
      // 右中 xy
      rightCenterRect.bounds.y += e.delta.y / 2;
      rightCenterRect.bounds.x += e.delta.x;
      // 下中 xy
      bottomCenterRect.bounds.y += e.delta.y;
      bottomCenterRect.bounds.x += e.delta.x / 2;
    };
    topCenterRect.onMouseDrag = (e: paper.MouseEvent) => {
      e.stopPropagation();
      if (item.bounds.size.height - e.delta.y <= 20) {
        return;
      }
      item.bounds.center.y += e.delta.y;
      item.bounds.size.height -= e.delta.y;

      rect.bounds.center.y += e.delta.y;
      rect.bounds.size.height -= e.delta.y;

      // 左上 y
      topLeftRect.bounds.y += e.delta.y;
      // 右上 y
      topRightRect.bounds.y += e.delta.y;
      // 上中 y
      topCenterRect.bounds.y += e.delta.y;
      // 左中 y
      leftCenterRect.bounds.y += e.delta.y / 2;
      // 右中 y
      rightCenterRect.bounds.y += e.delta.y / 2;
    };
    leftCenterRect.onMouseDrag = (e: paper.MouseEvent) => {
      e.stopPropagation();
      if (item.bounds.size.width - e.delta.x <= 20) {
        return;
      }
      item.bounds.center.x += e.delta.x;
      item.bounds.size.width -= e.delta.x;

      rect.bounds.center.x += e.delta.x;
      rect.bounds.size.width -= e.delta.x;

      // 左上 x
      topLeftRect.bounds.x += e.delta.x;
      // 左下 x
      bottomLeftRect.bounds.x += e.delta.x;
      // 左中 x
      leftCenterRect.bounds.x += e.delta.x;
      // 上中 x
      topCenterRect.bounds.x += e.delta.x / 2;
      // 下中 x
      bottomCenterRect.bounds.x += e.delta.x / 2;
    };
    bottomCenterRect.onMouseDrag = (e: paper.MouseEvent) => {
      e.stopPropagation();
      if (item.bounds.size.height + e.delta.y <= 20) {
        return;
      }
      item.bounds.size.height += e.delta.y;

      rect.bounds.size.height += e.delta.y;

      // 左下 y
      bottomLeftRect.bounds.y += e.delta.y;
      // 右下 y
      bottomRightRect.bounds.y += e.delta.y;
      // 下中 y
      bottomCenterRect.bounds.y += e.delta.y;
      // 左中 y
      leftCenterRect.bounds.y += e.delta.y / 2;
      // 右中 y
      rightCenterRect.bounds.y += e.delta.y / 2;
    };
    rightCenterRect.onMouseDrag = (e: paper.MouseEvent) => {
      e.stopPropagation();
      if (item.bounds.size.width + e.delta.x <= 20) {
        return;
      }
      item.bounds.size.width += e.delta.x;

      rect.bounds.size.width += e.delta.x;

      // 右上 x
      topRightRect.bounds.x += e.delta.x;
      // 右下 x
      bottomRightRect.bounds.x += e.delta.x;
      // 右中 x
      rightCenterRect.bounds.x += e.delta.x;
      // 上中 x
      topCenterRect.bounds.x += e.delta.x / 2;
      // 下中 x
      bottomCenterRect.bounds.x += e.delta.x / 2;
    };
    [
      topLeftRect,
      topRightRect,
      bottomLeftRect,
      bottomRightRect,
      topCenterRect,
      leftCenterRect,
      rightCenterRect,
      bottomCenterRect,
    ].forEach((item) => {
      item.onMouseLeave = (e: paper.MouseEvent) => {
        e.stopPropagation();
        cursor.value = "default";
      };
      item.onMouseEnter = (e: paper.MouseEvent) => {
        e.stopPropagation();
        switch (e.target.name) {
          case "topLeftRect":
            cursor.value = "nw-resize";
            break;
          case "topRightRect":
            cursor.value = "ne-resize";
            break;
          case "bottomLeftRect":
            cursor.value = "sw-resize";
            break;
          case "bottomRightRect":
            cursor.value = "se-resize";
            break;
          case "topCenterRect":
            cursor.value = "n-resize";
            break;
          case "leftCenterRect":
            cursor.value = "w-resize";
            break;
          case "rightCenterRect":
            cursor.value = "e-resize";
            break;
          case "bottomCenterRect":
            cursor.value = "s-resize";
            break;
        }
      };
    });

    return [g1, g2, item];
  };

  const registerMouseEvent = () => {
    const children = paperInstance.value.project.activeLayer.children;
    // 单个item的事件
    children?.forEach((item: any) => {
      // 每个item添加按下鼠标事件
      item.onMouseDown = (event: paper.MouseEvent) => {
        // 处理点击单个选中
        if (config.itemHandle?.includes("select")) {
          if (map.has(event.target)) {
            // 点击相同item,移除之前的,新添加一个
            selectionGroup.value = map.get(event.target);
            selectionGroup.value![0].remove();
            map.delete(event.target);
            selectionGroup.value = addSelect(new Paper.Group(event.target));
          } else {
            if (selectionGroup.value) {
              // 获取选中组
              const current = selectionGroup.value[1].getItems({
                match: (item: paper.Item) => {
                  if (item === event.target) {
                    return item;
                  }
                },
              });
              // 没有组 添加单个item的选中
              if (!current.length) {
                selectionGroup.value = addSelect(new Paper.Group(event.target));
                map.set(event.target, selectionGroup.value);
              }
            } else {
              selectionGroup.value = addSelect(new Paper.Group(event.target));
            }
          }
          paperInstance.value.project.activeLayer.addChild(
            selectionGroup.value![1]
          ); //提高层级

          // // 下载
          // const download = paperInstance.value.project.getItem({
          //   name: "download",
          // });
          // if (download!.name === event.target.name) {
          //   screenShot();
          // }
        } else if (
          config.itemHandle === "drag" ||
          (config.itemHandle && config.itemHandle[0] === "drag")
        ) {
          paperInstance.value.project.activeLayer.addChild(event.target);
        }
      };
      // 每个item添加鼠标拖动事件
      item.onMouseDrag = (event: paper.MouseEvent | any) => {
        // 只有拖拽 单独开启
        if (
          config.itemHandle === "drag" ||
          (config.itemHandle && config.itemHandle[0] === "drag")
        ) {
          item.position.set(
            item.position.x + event.delta.x,
            item.position.y + event.delta.y
          );
        }
        let tootipsEl = document.querySelector(".tootips") as HTMLElement;
        if (!tootipsEl) {
          tootipsEl = document.createElement("div");
          document.body.appendChild(tootipsEl);
          tootipsEl.innerHTML =
            typeof config.tooltips === "string"
              ? config.tooltips
              : config.tooltips();
          tootipsEl.className = "tootips";
          tootipsEl.style.position = "absolute";
          tootipsEl.style.left = event.event.offsetX + 10 + "px";
          tootipsEl.style.top = event.event.offsetY + 10 + "px";
          tootipsEl.style.color = "#999";
        } else {
          tootipsEl.style.display = "block";
          tootipsEl.style.left = event.event.offsetX + 10 + "px";
          tootipsEl.style.top = event.event.offsetY + 10 + "px";
        }
      };
      item.onMouseEnter = (e: paper.MouseEvent) => {
        cursor.value = "pointer";
      };
      item.onMouseLeave = () => {
        cursor.value = "defatul";
        let tootipsEl = document.querySelector(".tootips") as HTMLElement;
        tootipsEl.style.display = "none";
      };
      item.onMouseMove = (event: paper.MouseEvent | any) => {
        let tootipsEl = document.querySelector(".tootips") as HTMLElement;
        if (!tootipsEl) {
          tootipsEl = document.createElement("div");
          document.body.appendChild(tootipsEl);
          tootipsEl.innerHTML =
            typeof config.tooltips === "string"
              ? config.tooltips
              : config.tooltips();
          tootipsEl.className = "tootips";
          tootipsEl.style.position = "absolute";
          tootipsEl.style.left = event.event.offsetX + 10 + "px";
          tootipsEl.style.top = event.event.offsetY + 10 + "px";
          tootipsEl.style.color = "#999";
        } else {
          tootipsEl.style.display = "block";
          tootipsEl.style.left = event.event.offsetX + 10 + "px";
          tootipsEl.style.top = event.event.offsetY + 10 + "px";
        }
      };
    });
  };

  // const screenShot = () => {
  //   // 获取svg元素,将整个canvas导出为svg
  //   const flash = paperInstance.value.project.exportSVG();
  //   // 将SVG元素转换为字符串
  //   var serializer = new XMLSerializer();
  //   var xmlString = serializer.serializeToString(flash as SVGAElement);
  //   // 创建一个Blob对象
  //   var blob = new Blob([xmlString], { type: "image/svg+xml;charset=utf-8" });
  //   // 创建一个指向该Blob的URL
  //   var url = URL.createObjectURL(blob);
  //   // 创建一个a标签
  //   var a = document.createElement("a");
  //   a.href = url;
  //   a.download = "my-svg-file.svg";
  //   // 将a标签添加到文档中,触发点击事件,然后将其从文档中删除
  //   document.body.appendChild(a);
  //   a.click();
  //   document.body.removeChild(a);
  // };

  onMounted(() => {
    paperInstance.value.setup(canvasEl.value!);
    canvasEl.value?.addEventListener("wheel", mouseWheel);
    nextTick(() => {
      canvasHandleFn();
      registerMouseEvent();
    });
  });

  onUnmounted(() => {
    paperInstance.value.project.clear();
    canvasEl.value?.removeEventListener("wheel", mouseWheel);
  });

  return {
    paperInstance,
    canvasEl,
    zoom,
    cursor,
    selectionGroup,
    addSelect,
    registerMouseEvent,
  };
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值