【问题标题】:How to draw SVG element on a plane with THREE.js?如何使用 THREE.js 在平面上绘制 SVG 元素?
【发布时间】:2016-05-04 20:22:57
【问题描述】:

我正在尝试在 THREE.js 场景中创建现有 svg 元素的副本。我使用this example 将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);
        };

【问题讨论】:

    标签: javascript canvas svg three.js webgl


    【解决方案1】:

    我相信你需要这样做:

    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);
    };
    

    在以下位置创建小提琴:http://jsfiddle.net/3Lg911vs/4/

    【讨论】:

    • 不幸的是没有运气
    • 嗯,确实很棘手。当我把我的 svg 而不是你的,但仅限于 Chrome 时,你的小提琴绝对有效。我正在使用 FF,它也必须在那里工作。您能否看看您在 FF 中更新的小提琴:jsfiddle.net/7h5hbpww
    • 我继续调查逐渐删除我的 svg 的一部分以找出导致渲染器失败的节点。原来问题出在我的 svg 节点上。它没有指定widthheight 属性。如果我设置它们,一切正常。谢谢,如果没有你的帮助,我会花更多的时间!
    • @gaitat 如果 svg 有图像 URL,则不起作用。有人对这种情况有任何解决方法吗?
    猜你喜欢
    • 2018-07-28
    • 1970-01-01
    • 2012-06-17
    • 2018-10-24
    • 2015-12-24
    • 1970-01-01
    • 2018-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多