vue截图-html2canvas

使用html2canvas进行截图操作

在 Vue 中使用 ​​html2canvas​​ 将 HTML 元素(如包含贝塞尔曲线的 Canvas/SVG)转换为图片

下载html2canvas

npm install html2canvas

在页面中使用,要截取哪个div的内容,先给这个div加一个ref标识,如ref=“html_container”

主要用到的:
在这里插入图片描述

具体代码:

<template>
  <div class="CanvasPage" ref="html_container">
    <!-- 未处理时的canvas画布数据 -->
    <canvas :id="'canvas' + '002'" :style="`position: absolute; `"></canvas>
    <!-- 使用赛贝尔曲线以及笔锋处理之后的画布数据 -->
    <canvas
      :id="'canvas' + '001'"
      @pointerdown.stop="onPointerDown"
      :style="`position: absolute; `"
      @touchstart="onTouchstart"
    ></canvas>
    
    <div class="CanvasPageSave">
      <el-button @click="toSave" type="primary">保存当前页面</el-button>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted } from "vue";
import { Bezier } from "bezier-js";
import html2canvas from 'html2canvas'
let html_container = ref(null);
let canvas, ctx;
let canvasCover, ctxCover;
const winH = window.innerHeight,
      winW = window.innerWidth;

let isMove = false;
// canvas初始化
const initCanvas = () => {
  canvas = document.getElementById("canvas001");
  ctx = canvas.getContext("2d", {
    antialias: true, // 抗锯齿
  });
  canvas.width = winW; // canvas宽度
  canvas.height = winH; // canvas高度
  ctx.lineWidth = 2; // 画线默认宽度
  ctx.strokeStyle = "red"; // 设置颜色

  // 复制出来一份原始的canvas画线数据
  canvasCover = document.getElementById("canvas002");
  ctxCover = canvasCover.getContext("2d", {
    antialias: true, // 抗锯齿
  });
  canvasCover.width = winW; // canvas宽度
  canvasCover.height = winH; // canvas高度
  ctxCover.lineWidth = 2; // 画线默认宽度
  ctxCover.strokeStyle = "red"; // 设置颜色
};

let startx = ref(0), //起始坐标
  starty = ref(0),
  pointerId = ref(null);

let points = []; // 收集所有点的数据

// pointerdown同时处理鼠标、触摸屏和触控笔。
const onPointerDown = (e) => {
  points = [];
  isMove = true;
  const { offsetX, offsetY } = e;
  pointerId = e.pointerId;
  startx.value = offsetX;
  starty.value = offsetY;
  

  canvas.addEventListener("pointermove", onDrawMove);
  canvas.addEventListener("pointerup", onDrawUp);
};
 
/* 单个触摸事件 */
// 处理移动逻辑
const onDrawMove = (e) => {
  if (isMove) {
    const { offsetX, offsetY } = e;

    if (pointerId != e.pointerId) return;

    // 原始画线数据
    ctxCover.beginPath();
    ctxCover.lineWidth = 2; // 设置线条粗细
    ctxCover.moveTo(startx.value, starty.value);
    ctxCover.lineTo(offsetX, offsetY);
    ctxCover.stroke();
    ctxCover.closePath();

    startx.value = offsetX;
    starty.value = offsetY;
    points.push({
      x: offsetX,
      y: offsetY,
    });
    e.preventDefault();
  }
}
// 处理释放逻辑
const onDrawUp = (e) => {
  ctx.closePath();
  // 鼠标释放时处理线条,将处理过的数据显示,之前的数据清空
  drawSmoothLine();
  points = [];
  isMove = false;
  document.removeEventListener("pointermove", onDrawMove);
  document.removeEventListener("pointerup", onDrawUp);
}
// 优化线条
const drawSmoothLine = () => {
  isMove = false;
  if (points.length > 1) {
    let num1 = 200; // 补点数
    let num2 = 20; // 从后面开始变细的点数
    const startWidth = 2; // 设置线条粗细
    const endWidth = 0; // 最后变细的宽度
    ctxCover.clearRect(0, 0, canvasCover.width, canvasCover.height); // 清除原始数据
    // 在释放的时候使用贝塞尔曲线重新处理画出来的线
    ctx.lineWidth = startWidth;// 设置线条粗细
    // 使用赛贝尔曲线让线条更丝滑
    const bez = new Bezier(points);
    const pointOnCurve = bez.getLUT(num1); // 补点
    ctx.beginPath();
    ctx.moveTo(pointOnCurve[0].x, pointOnCurve[0].y);
    // 截取,从开始截取到需要变细的位置,正常画线
    pointOnCurve.slice(0, -num2).forEach((p) => ctx.lineTo(p.x, p.y)); 
    ctx.stroke();
    // 笔锋,设置线从哪个位置开始,按一定比例变细
    pointOnCurve.slice(-num2).forEach((p, px) => {
      const lineWidth = startWidth + ((endWidth - startWidth) * px) / num2;
      ctx.lineWidth = lineWidth;
      ctx.lineTo(p.x, p.y);
      ctx.stroke();
    });
    ctx.lineWidth = startWidth;
    ctx.closePath();
  }
};

const toSave = () => {
  // html2canvas截取工具,第一个参数是截取的元素这里使用的ref,第二个参数是相应的配置
  html2canvas(html_container.value, {
      background: 'transparent',
      useCORS: true
  }).then((canvas) => {
    const base64 = canvas.toDataURL().replace(/^data:image\/(png|jpg);base64,/, '');
    // console.log(`data:image/png;base64,${base64}`);

    // 可选:自动下载图片
    const link = document.createElement('a');
    link.download = 'bezier-curve.png';
    link.href = `data:image/png;base64,${base64}`;
    link.click();
  });
}
onMounted(() => {
  initCanvas();
});
</script>

<style scoped lang="scss">
.CanvasPage {
  width: 100%;
  height: 100%;
  background-color: #044444;
  position: relative;
  .CanvasPageSave {
    position: absolute;
    left: 0;
    top: 0;
  }
}
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sunshinedada

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值