在 canvas 上绘制具有动态值的 svg

Draw svg with dynamic value on canvas

我希望能够将具有动态值(颜色)的 svg 绘制到 canvas。 我试过制作 svg react 组件,所以我可以将颜色传递给 svg,但是我很困惑如何将 react svg 组件绘制到 canvas.

P.S。最好是将 svg 存储在单独的文件中。

工作静态 svg 示例:

import ant_skin_url from '../../assets/AntSkin.svg';

const ant_skin = new Image();
ant_skin.src = ant_skin_url;

context.drawImage(
  ant_skin,
  i * width_cell,
  ii * height_cell,
  width_cell,
  height_cell,
);

React svg 组件,但不清楚如何处理输出(在 canvas 中绘制):

export const AntSkin = (color) => 
  <svg>
    ...
  </svg>

由于您不想渲染 svg 而是将其放入 canvas,因此从 .svg 导入不会有太大帮助。

您可以创建一个组件:

  1. 接收颜色作为道具
  2. 将 svg 内容设为字符串

在安装时,它结合了 svg 字符串和颜色,将其转换为 base64(这是 webpack 从 .svg 导入时所做的)并提供 canvas 和你一样。

这是它的样子

import { useEffect, useMemo, useRef } from "react";

export const Icon = ({ color }) => {
  const ref = useRef();
  const svg = useMemo(
    () => `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve" height="100px" width="100px">
    <g>
      <path color="${color}" d="M28.1,36.6c4.6,1.9,12.2,1.6,20.9,1.1c8.9-0.4,19-0.9,28.9,0.9c6.3,1.2,11.9,3.1,16.8,6c-1.5-12.2-7.9-23.7-18.6-31.3   c-4.9-0.2-9.9,0.3-14.8,1.4C47.8,17.9,36.2,25.6,28.1,36.6z"/>
      <path color="${color}" d="M70.3,9.8C57.5,3.4,42.8,3.6,30.5,9.5c-3,6-8.4,19.6-5.3,24.9c8.6-11.7,20.9-19.8,35.2-23.1C63.7,10.5,67,10,70.3,9.8z"/>
      <path color="${color}" d="M16.5,51.3c0.6-1.7,1.2-3.4,2-5.1c-3.8-3.4-7.5-7-11-10.8c-2.1,6.1-2.8,12.5-2.3,18.7C9.6,51.1,13.4,50.2,16.5,51.3z"/>
      <path color="${color}" d="M9,31.6c3.5,3.9,7.2,7.6,11.1,11.1c0.8-1.6,1.7-3.1,2.6-4.6c0.1-0.2,0.3-0.4,0.4-0.6c-2.9-3.3-3.1-9.2-0.6-17.6   c0.8-2.7,1.8-5.3,2.7-7.4c-5.2,3.4-9.8,8-13.3,13.7C10.8,27.9,9.8,29.7,9,31.6z"/>
      <path color="${color}" d="M15.4,54.7c-2.6-1-6.1,0.7-9.7,3.4c1.2,6.6,3.9,13,8,18.5C13,69.3,13.5,61.8,15.4,54.7z"/>
      <path color="${color}" d="M39.8,57.6C54.3,66.7,70,73,86.5,76.4c0.6-0.8,1.1-1.6,1.7-2.5c4.8-7.7,7-16.3,6.8-24.8c-13.8-9.3-31.3-8.4-45.8-7.7   c-9.5,0.5-17.8,0.9-23.2-1.7c-0.1,0.1-0.2,0.3-0.3,0.4c-1,1.7-2,3.4-2.9,5.1C28.2,49.7,33.8,53.9,39.8,57.6z"/>
      <path color="${color}" d="M26.2,88.2c3.3,2,6.7,3.6,10.2,4.7c-3.5-6.2-6.3-12.6-8.8-18.5c-3.1-7.2-5.8-13.5-9-17.2c-1.9,8-2,16.4-0.3,24.7   C20.6,84.2,23.2,86.3,26.2,88.2z"/>
      <path color="${color}" d="M30.9,73c2.9,6.8,6.1,14.4,10.5,21.2c15.6,3,32-2.3,42.6-14.6C67.7,76,52.2,69.6,37.9,60.7C32,57,26.5,53,21.3,48.6   c-0.6,1.5-1.2,3-1.7,4.6C24.1,57.1,27.3,64.5,30.9,73z"/>
    </g>
    </svg>`,
    [color]
  );

  useEffect(() => {
    const image = new Image();
    const context = ref.current.getContext("2d");

    image.src = `data:image/svg+xml;base64,${window.btoa(svg)}`;
    image.onload = () => {
      context.drawImage(image, 0, 0);
    };
  }, [svg]);

  return <canvas ref={ref} width="200" height="200" />;
};

Demo