最终获取 .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]);
};