将 SVG 颜色放入画布元素之前无法更改它

问题描述 投票:0回答:1
javascript reactjs typescript svg html5-canvas
1个回答
0
投票

最终获取 .svg 文件,使用 DOMParser 解析 SVG 字符串,使用 setAttribute 函数添加填充属性,并将解析后的 SVG 恢复为字符串。然后将其作为 DataURL 添加到 Image 对象的 src 属性中。

export const useRenderIcon = (
    previewCanvas: React.RefObject<HTMLCanvasElement>,
    selectedColor: Color,
    selectedSVG: Svg
): void => {
    const [fetchedSvg, setFetchedSvg] = useState<string>("");

    useEffect(() => {
        fetch(selectedSVG.uri)
            .then(response => response.text())
            .then(data => {
                const domParser = new DOMParser();
                const parsedSvg = domParser.parseFromString(data, "image/svg+xml");

                if (selectedColor.type === "Light") {
                    parsedSvg.getElementsByTagName("svg")[0].setAttribute("fill", "white");
                } else {
                    parsedSvg.getElementsByTagName("svg")[0].setAttribute("fill", "black");
                }

                return parsedSvg.toString();
            })
            .then(data => setFetchedSvg(data));
    }, [selectedColor, selectedSVG]);

    useEffect(() => {
        if (previewCanvas.current) {
            const ctx = previewCanvas.current.getContext("2d");

            if (ctx) {
                // draw icon background color
                ctx.fillStyle = selectedColor.color;
                ctx.fillRect(0, 0, previewCanvas.current.width, previewCanvas.current.height);

                // draw icon svg
                const offset = previewCanvas.current.width - PREVIEW_SVG_SIZE;
                const svgIconImage = new Image();

                svgIconImage.setAttribute("src", `data:image/svg+xml,${fetchedSvg}`);
                svgIconImage.setAttribute("width", `${PREVIEW_SVG_SIZE}`);

                svgIconImage.onload = () => {
                    ctx.imageSmoothingEnabled = false;
                    ctx.drawImage(
                        svgIconImage,
                        offset / window.devicePixelRatio,
                        offset / window.devicePixelRatio,
                        PREVIEW_SVG_SIZE,
                        PREVIEW_SVG_SIZE
                    );
                };
            }
        }
    }, [previewCanvas, selectedColor, selectedSVG, fetchedSvg]);
};
© www.soinside.com 2019 - 2024. All rights reserved.