【前端可视化】Canvas 下载图片添加背景色因为缩放导致比例不同问题

发布时间 2023-06-29 09:04:44作者: 努力挣钱的小鑫

比例不同是因为缩放导致的,缩放导致绘图中心发生改变,我们需要把填充的背景色的范围扩大(根据缩放比例来),同时背景色要绘制在现有画布的后面,防止重叠遮挡。

感觉一个小下载,需要注意的事项还是挺多的,记录下,希望能帮助到其他人,里面的一些 API 请参考 MDN 文档。

下面的参考代码,自己根据自己实际项目需要来修改就行。

// 下载图片
const handleDownloadImg = () => {
  const canvas = document.querySelector('canvas');
  if (!canvas) {
    ElMessage({
      message: '未找到canvas',
      type: 'warning',
    });
    return;
  }
  // 设置背景色
  const ctx = canvas.getContext('2d');
  if (ctx) {
    // 绘制层级问题 globalCompositeOperation:在现有的画布内容后面绘制新的图形
    ctx.globalCompositeOperation = 'destination-over';
    ctx.fillStyle = mapConfig.backgroundColor;
    // 获取canvas的缩放比例, 用于缩放操作,下面要还原canvas的缩放比例
    const scale = ctx.getTransform().a / 2;
    ctx.fillRect(
      -canvas.width / 2 / scale,
      -canvas.height / 2 / scale,
      canvas.width / scale,
      canvas.height / scale,
    );
  }
  // toDataURL() 方法返回一个包含图片展示的 data URI 。可以使用 type 参数其类型,默认为 PNG 格式。
  // jpeg 格式支持设置图片质量,并且背景有颜色
  const img = canvas.toDataURL('image/jpeg', 1);
  const a = document.createElement('a');
  a.href = img;
  a.download = `${props.project?.name || projectStore.project.name}${
    props.subTitle || ''
  }.png`;
  a.click();
  // 下载完后还原globalCompositeOperation(根据项目需要来,我这里是图谱,部分组件会因为这个属性改变样式)
  if (ctx) {
    ctx.globalCompositeOperation = 'source-over';
  }
};