如何用 PixiJS 渲染 SVG?
Posted
技术标签:
【中文标题】如何用 PixiJS 渲染 SVG?【英文标题】:How to render SVG with PixiJS? 【发布时间】:2015-10-21 02:33:02 【问题描述】:我正在尝试使用 SVG 图像制作游戏,以实现可扩展性并通过程序从它们中制作物理对象(请参阅 matter.js 了解如何)。
我遇到的问题是,如果我加载 2 个不同的 SVG 纹理然后渲染它们,第二个在它下面有第一个分层。
光栅图像不会发生这种情况,画布选项不会发生这种情况,只有 WebGL 会发生这种情况。
有没有办法阻止这种情况,还是我做错了 SVG?
var renderer = PIXI.autoDetectRenderer(
window.innerWidth,
window.innerHeight,
backgroundColor : 0xffffff,
resolution:2
);
// add viewport and fix resolution doubling
document.body.appendChild(renderer.view);
renderer.view.style.width = "100%";
renderer.view.style.height = "100%";
var stage = new PIXI.Container();
//load gear svg
var texture = PIXI.Texture.fromImage('https://upload.wikimedia.org/wikipedia/commons/thumb/0/0b/Gear_icon_svg.svg/2000px-Gear_icon_svg.svg.png');
var gear = new PIXI.Sprite(texture);
//position and scale
gear.scale = x:0.1,y:0.1;
gear.position = x:window.innerWidth / 2,y:window.innerHeight / 2;
gear.anchor = x:0.5,y:0.5;
//load heart svg
var texture2 = PIXI.Texture.fromImage('https://upload.wikimedia.org/wikipedia/commons/thumb/4/42/Love_Heart_SVG.svg/2000px-Love_Heart_SVG.svg.png');
var heart = new PIXI.Sprite(texture2);
//position and scale
heart.scale = x:0.1,y:0.1;
heart.position = x:window.innerWidth/4,y:window.innerHeight / 2;
heart.anchor = x:0.5,y:0.5;
//add to stage
stage.addChild(gear);
stage.addChild(heart);
// start animating
animate();
function animate()
gear.rotation += 0.05;
// render the container
renderer.render(stage);
requestAnimationFrame(animate);
<script src="https://github.com/pixijs/pixi.js/releases/download/v4.8.2/pixi.min.js"></script>
【问题讨论】:
你找到解决办法了吗? 这听起来像是浏览器和/或 pixi.js 的错误。您是否仍然看到这种行为? 不清楚你的意思是“我遇到的问题是如果我加载 2 个不同的 SVG 纹理然后渲染它们,第二个在它下面有第一个分层。”你能看穿你的svg吗?它是透明的svg吗?你能添加一个突出显示问题的屏幕截图吗? 我不明白你为什么要使用 SVG 作为纹理。为什么不直接导入该 SVG 内部的 .png 呢?在 WebGL 中没有矢量图像的概念。 我相信问题提供的示例是使用 PNG,而不是 SVG。查看传递给PIXI.Texture.fromImage()
的 URL。 URL 以2000px-Gear_icon_svg.svg.png
和2000px-Love_Heart_SVG.svg.png
结尾。这些是 PNG 文件,而不是 SVG 文件。所以......无论这里发生什么行为,我怀疑它与 SVG 与 PNG 无关。我也不明白为什么行为不正确。
【参考方案1】:
所以我认为你有点混淆了概念。
SVG 是一回事,WebGL 是另一回事。 SVG 由浏览器渲染,您可以放大或缩小它们,而不会损失质量/分辨率或任何您想要调用的内容。
然而,这个特性在 WebGL 中是不可能的,因为 WebGL 会光栅化图像。有点像截取屏幕截图并将其放在 Photoshop 上的图层中。您可以操作该图像,但如果不开始查看像素,您将无法对其进行缩放。
简短的回答是,您不能在 WebGL 中使用 SVG,希望让您的图形“缩放”。
关于你上面的例子,结果是预期的。
您正在加载 2 个 png 纹理并覆盖它们。
【讨论】:
您可以将 SVG 转换为纹理,但是当您提供给 WebGL 时,您仍然提供的是图像。 jpg,png不是svg。如果那是您的重点,是的,您可以将 svg 转换为 jpg 并将该 jpg 反馈回来。但是您不能在需要图像的地方提供 svg。也不是字符串或其他数据类型,并期望它能够工作 PIXI 可以做到这一点,但例如 three.js 不能。因此,他们在幕后将 SVG 转换为图像。但是 GPU 不接受 svgs,这是我唯一的观点。这是讨论添加功能的问题。 github.com/pixijs/pixi.js/issues/4128【参考方案2】:嗯,这个例子似乎运行得很好!
var beeSvg = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/106114/bee.svg";
beeTexture = new PIXI.Texture.fromImage(beeSvg, undefined, undefined, 1.0);
var bee = new PIXI.Sprite(beeTexture)
查看更多信息:https://codepen.io/osublake/pen/ORJjGj
【讨论】:
在 translatez 旁边的第 86 行添加scale(5)
看看它是否仍然是矢量图形
这显然会将您的 SVG 渲染为光栅。以上是关于如何用 PixiJS 渲染 SVG?的主要内容,如果未能解决你的问题,请参考以下文章