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 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);
};

完整代码

<template>
  <canvas id="myCanvas" ref="myCanvas"></canvas>
</template>

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

const paperInstance = new Paper.PaperScope();
let project: null | paper.Project = null;
const tool = new Paper.Tool();

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 drawCircle = () => {
  const circle = new Paper.Path.Circle({
    center: [200, 100], //中心点
    radius: 50, //半径
    fillColor: new Paper.Color("red"), //填充颜色
    strokeColor: new Paper.Color("black"), //边框颜色
  });
  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;
  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;
};

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: [1600, 50], //文本位置
    fillColor: "black",
    justification: "center",
    fontSize: 20, //字体大小
    content: "下载",
    locked: false, //锁定
    name: "download",
  });
};

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]);
};

/**
 * @description 监听键盘事件
 */
const onKeyDown = () => {
  tool.onKeyDown = (event: any) => {
    console.log(event);
    if (event.event.key === "z" && event.event.ctrlKey) {
    }
  };
};

/**
 * @description 监听鼠标事件
 */
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;
    }
    // 下载
    const download = project?.getItem({
      name: "download",
    });
    if (download === event.item) {
      screenShot();
    }
  };
  console.log(children);
  // 单个item的事件
  children?.forEach((item: any) => {
    // 每个item添加按下鼠标事件
    item.onMouseDown = () => {
      project?.activeLayer.addChild(item); //提高层级
      item.selected = true; //选中样式
    };
    // 每个item添加鼠标拖动事件
    item.onMouseDrag = (event: paper.MouseEvent) => {
      console.log(event);
      item.position.set(
        item.position.x + event.delta.x,
        item.position.y + event.delta.y
      );
    };
  });
};

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 calculatePointOnCircle = (
  centerX: number,
  centerY: number,
  radius: number,
  angle: number
) => {
  var x = centerX + radius * Math.cos(angle);
  var y = centerY + radius * Math.sin(angle);
  console.log(x, y);
  return new Paper.Point(x, y);
};

onMounted(() => {
  paperInstance.setup(document.getElementById("myCanvas") as HTMLCanvasElement);
  project = new Paper.Project(
    document.getElementById("myCanvas") as HTMLCanvasElement
  );
  drawCircle();
  drawPointAndLine();
  drawRectangle();
  drawImg();
  drawText();
  drawGroup();
  drawCurve();
  tool.activate();
  onKeyDown();
  onMouse();
  drawAnimate();
});
</script>

<style lang="scss" scoped>
#myCanvas {
  width: 100%;
  height: 100%;
}
</style>

相关推荐

  1. vue3使用ref

    2024-03-28 06:28:03       37 阅读
  2. vue3 使用vue-types

    2024-03-28 06:28:03       30 阅读
  3. Vue3teleport如何使用

    2024-03-28 06:28:03       48 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-28 06:28:03       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-28 06:28:03       106 阅读
  3. 在Django里面运行非项目文件

    2024-03-28 06:28:03       87 阅读
  4. Python语言-面向对象

    2024-03-28 06:28:03       96 阅读

热门阅读

  1. Ubuntu16.04 切换系统python和gcc版本

    2024-03-28 06:28:03       41 阅读
  2. 添加图像MFC PDF

    2024-03-28 06:28:03       38 阅读
  3. git merge 和 git rebase

    2024-03-28 06:28:03       44 阅读
  4. pulsar: 批量接收消息

    2024-03-28 06:28:03       43 阅读
  5. 数据结构奇妙旅程之深入解析归并排序

    2024-03-28 06:28:03       46 阅读
  6. C 指针数组

    2024-03-28 06:28:03       37 阅读
  7. pytorch笔记篇:pandas之数据预处理(更新中)

    2024-03-28 06:28:03       42 阅读
  8. Android数据存储:SQLite、Room

    2024-03-28 06:28:03       48 阅读
  9. 基于Python的旅游网站数据爬虫分析

    2024-03-28 06:28:03       37 阅读
  10. docker安装postgresql数据库包含postgis扩张

    2024-03-28 06:28:03       40 阅读