Javascript 如何使用THREE.js在平面上绘制SVG元素?

Javascript 如何使用THREE.js在平面上绘制SVG元素?,javascript,canvas,svg,three.js,webgl,Javascript,Canvas,Svg,Three.js,Webgl,我试图在THREE.js场景中创建现有svg元素的副本。我使用将svg转换为图像,然后基于图像创建一个带有纹理的平面,并将其添加到场景中。然而,飞机是黑色的。如果我使用纯色而不是纹理,它会正确渲染,因此我的纹理有问题 var legend = document.querySelector("svg.ViewLegend"); var svgData = new XMLSerializer().serializeToString(legend);

我试图在THREE.js场景中创建现有svg元素的副本。我使用将svg转换为图像,然后基于图像创建一个带有纹理的平面,并将其添加到场景中。然而,飞机是黑色的。如果我使用纯色而不是纹理,它会正确渲染,因此我的纹理有问题

        var legend = document.querySelector("svg.ViewLegend");
        var svgData = new XMLSerializer().serializeToString(legend);

        var canvas = document.createElement("canvas");
        canvas.width = 512;
        canvas.height = 64;
        var ctx = canvas.getContext("2d");

        var img = document.createElement("img");
        img.setAttribute("src", "data:image/svg+xml;base64," + btoa(svgData));

        img.onload = function () {
            ctx.drawImage(img, 0, 0);

            var texture = new THREE.Texture(canvas);
            texture.needsUpdate = true;

            var material = new THREE.MeshBasicMaterial({
                map: texture,
            });
            material.map.minFilter = THREE.LinearFilter;
            //If I use the material below, it works correctly
            //var material = new THREE.MeshPhongMaterial({color: 0xCC0000});
            var geometry = new THREE.PlaneBufferGeometry(512, 64, 1, 1);
            var mesh = new THREE.Mesh(geometry, material);

            scene.add(mesh);
        };

我相信你需要做:

var canvas = document.createElement("canvas");
var svgSize = svg.getBoundingClientRect();
canvas.width = svgSize.width;
canvas.height = svgSize.height;
var ctx = canvas.getContext("2d");

var img = document.createElement("img");
img.setAttribute("src", "data:image/svg+xml;base64," + window.btoa(unescape(encodeURIComponent(svgData))) );

img.onload = function() {
  ctx.drawImage(img, 0, 0);

  var texture = new THREE.Texture(canvas);
  texture.needsUpdate = true;

  var geometry = new THREE.SphereGeometry(3, 50, 50, 0, Math.PI * 2, 0, Math.PI * 2);
  var material = new THREE.MeshBasicMaterial({ map: texture });
  material.map.minFilter = THREE.LinearFilter;
  mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);
};

创建小提琴:

运气不好不幸的是,这确实很棘手。当我用我的svg而不是你的svg时,你的小提琴绝对有效,但只有在Chrome中。我使用的是FF,它在那里也能正常工作是很重要的。请看一下FF中更新的fiddle:我继续调查svg的各个部分,以找出哪个节点导致渲染器出现故障。原来问题出在我的svg节点上。它没有指定
宽度
高度
属性。如果我设置它们,一切都会正常。谢谢,没有你的帮助我要花更多的时间@如果svg有图像URL,则gaitat不起作用。有人能解决这个问题吗?