我想做的是将 SVG 绘制在画布上的蓝色圆圈上。蓝色圆圈应该是背景。
但是,结果只是 SVG。
最终结果应该类似于
(注意:假装我只使用了一个圆形 SVG,而不是代码中使用的)
背景较大,SVG 插入并居中。
我怎样才能做到这一点?
const svg = `<svg xmlns="http://www.w3.org/2000/svg" fill="#ff0000" viewBox="0 0 512 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M256 0c17.7 0 32 14.3 32 32l0 10.4c93.7 13.9 167.7 88 181.6 181.6l10.4 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-10.4 0c-13.9 93.7-88 167.7-181.6 181.6l0 10.4c0 17.7-14.3 32-32 32s-32-14.3-32-32l0-10.4C130.3 455.7 56.3 381.7 42.4 288L32 288c-17.7 0-32-14.3-32-32s14.3-32 32-32l10.4 0C56.3 130.3 130.3 56.3 224 42.4L224 32c0-17.7 14.3-32 32-32zM107.4 288c12.5 58.3 58.4 104.1 116.6 116.6l0-20.6c0-17.7 14.3-32 32-32s32 14.3 32 32l0 20.6c58.3-12.5 104.1-58.4 116.6-116.6L384 288c-17.7 0-32-14.3-32-32s14.3-32 32-32l20.6 0C392.1 165.7 346.3 119.9 288 107.4l0 20.6c0 17.7-14.3 32-32 32s-32-14.3-32-32l0-20.6C165.7 119.9 119.9 165.7 107.4 224l20.6 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-20.6 0zM256 224a32 32 0 1 1 0 64 32 32 0 1 1 0-64z"/></svg>`;
var blob = new Blob(
Array.prototype.map.call(
document.querySelectorAll('script[type="text/js-worker"]'),
function (oScript) {
return oScript.textContent;
}
),
{ type: "text/javascript" }
);
const worker = new Worker(window.URL.createObjectURL(blob), {
type: "module"
});
const img = document.querySelector("img");
worker.postMessage({
width: 20,
height: 20,
svg: svg
});
worker.onmessage = (event) => {
img.src = event.data.pngUrl;
};
<script type="text/js-worker">
import { DOMParser } from 'https://cdn.skypack.dev/@xmldom/xmldom@^0.7.5'
import {
Canvg,
presets
} from 'https://cdn.skypack.dev/canvg@^4.0.0'
const preset = presets.offscreen({
DOMParser
})
self.onmessage = async (event) => {
const {
width,
height,
svg
} = event.data
const canvas = new OffscreenCanvas(width, height)
const ctx = canvas.getContext('2d')
ctx.beginPath();
ctx.arc(10, 10, 10, 0, 2 * Math.PI);
ctx.fillStyle = 'blue';
ctx.fill();
const v = await Canvg.from(ctx, svg, preset)
await v.render()
const blob = await canvas.convertToBlob()
const pngUrl = URL.createObjectURL(blob)
self.postMessage({
pngUrl
})
}
</script>
<img />
ignoreClear
选项,因此渲染时不会清除画布。
请注意,在下面的代码片段中,我对代码进行了一些重构,以不输出 png 图像,而是直接在占位符
<canvas>
元素中渲染。
const svg = `<svg xmlns="http://www.w3.org/2000/svg" fill="#ff0000" viewBox="0 0 512 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M256 0c17.7 0 32 14.3 32 32l0 10.4c93.7 13.9 167.7 88 181.6 181.6l10.4 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-10.4 0c-13.9 93.7-88 167.7-181.6 181.6l0 10.4c0 17.7-14.3 32-32 32s-32-14.3-32-32l0-10.4C130.3 455.7 56.3 381.7 42.4 288L32 288c-17.7 0-32-14.3-32-32s14.3-32 32-32l10.4 0C56.3 130.3 130.3 56.3 224 42.4L224 32c0-17.7 14.3-32 32-32zM107.4 288c12.5 58.3 58.4 104.1 116.6 116.6l0-20.6c0-17.7 14.3-32 32-32s32 14.3 32 32l0 20.6c58.3-12.5 104.1-58.4 116.6-116.6L384 288c-17.7 0-32-14.3-32-32s14.3-32 32-32l20.6 0C392.1 165.7 346.3 119.9 288 107.4l0 20.6c0 17.7-14.3 32-32 32s-32-14.3-32-32l0-20.6C165.7 119.9 119.9 165.7 107.4 224l20.6 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-20.6 0zM256 224a32 32 0 1 1 0 64 32 32 0 1 1 0-64z"/></svg>`;
var blob = new Blob(
Array.prototype.map.call(
document.querySelectorAll('script[type="text/js-worker"]'),
function (oScript) {
return oScript.textContent;
}
),
{ type: "text/javascript" }
);
const worker = new Worker(window.URL.createObjectURL(blob), {
type: "module"
});
// Use a placeholder <canvas> instead of converting to a png
const canvasEl = document.querySelector("canvas");
canvasEl.width = canvasEl.height = 20;
const canvas = canvasEl.transferControlToOffscreen();
worker.postMessage({
canvas,
svg: svg
}, [canvas]);
<script type="text/js-worker">
import { DOMParser } from 'https://cdn.skypack.dev/@xmldom/xmldom@^0.7.5'
import {
Canvg,
presets
} from 'https://cdn.skypack.dev/canvg@^4.0.0'
const preset = presets.offscreen({
DOMParser,
});
preset.ignoreClear = true;
self.onmessage = async (event) => {
const {
canvas,
svg
} = event.data
const ctx = canvas.getContext('2d')
ctx.beginPath();
ctx.arc(10, 10, 10, 0, 2 * Math.PI);
ctx.fillStyle = 'blue';
ctx.fill();
const v = await Canvg.from(ctx, svg, preset)
await v.render()
}
</script>
<canvas></canvas>