我要渲染多个SVG形状。
我目前正在为每个svg分别创建一个Image对象,这会导致许多不必要的HTTP请求。
Error:(293, 41) missing parameter type
val rs: ArrayMap[String] = for (e <- map) yield e._2.toString
我想使用一个包含所有SVG的sprite文件,然后像使用const imageEl = new Image();
imageEl.src = image.src;
// And then
ctx.drawImage(this.image, this.x, this.y, this.width, this.height);
在HTML
中将它们绘制到画布上一样
我该怎么做?
答案 0 :(得分:0)
您的问题尚不清楚您到底如何管理资产,因此我提醒您,但请注意这是此答案最重要的一点: 您应该只加载一次所有资产,然后再开始使用其中的任何资产。
这意味着,new Image()
调用应在应用程序的初始化步骤中进行,而drawImage()
调用应在应用程序的绘制步骤中进行,该步骤本身在anim'循环中调用。
// in 'loadAssets()' called from 'init()' only once per 'uri'
const img = new Image();
img.onload = thisLoaded;
img.src = uri;
// in 'draw()' called from 'anim()'
ctx.drawImage(img, ...
您的问题归结为能够从 元素加载这些引用。这就是Canvas2d API作为源的要求,而这实际上是这里的最大罪魁祸首。 ( drawImage 也接受svg的
大多数svg元素本身没有意义。我们用来定义它们的所有坐标都必须相对于其viewPort父级的 viewBox 。因此,几乎没有单个元素只能单独绘制。如果svg 元素能够“渲染”单个元素,那是因为这个<use>
元素本身包含在 元素中,它定义了 viewBox 。
从 元素加载的图像不能对外部资源执行任何请求。
这意味着,动态生成仅由<svg><use href="https://foo.bar#baz"></svg>
构成的多个简单svg文档将无济于事, #baz 应该是文档本身的一部分。
现在所有这些都已清除,我们可以提出一些解决方案:
在下面的示例中,svg image used由两个元素组成,一个元素的ID为rect
,另一个元素的ID为circle
。
第一个(可能是最明显的)是构建自己的 系统。
您可以先获取spritesheet svg,从js中解析,然后通过仅选择所需的元素来生成需要绘制的svg。
但是这种方法的最大问题是svg可能具有非常复杂的链接,并且检索所有目标元素并不是一件容易的事。
因此,在这里,我仅展示一个基本实现,在该实现中,我们只能定位直接元素(没有