动态更改svg的颜色并在three.js

时间:2017-08-28 20:55:46

标签: javascript svg three.js

我正在尝试使用three.js创建一个配置器,但即时通讯我需要更改dinamycally产品的颜色,我虽然我可以使用svg作为纹理,更改svg的填充属性并轻松更新纹理,但我没有很好的结果

目前我所拥有的是

-Svg应用作为带有TextureLoader的纹理的3D模型,但是svg被放置在外部文件中(“images / texture.svg”)(也是三个.js正在减小纹理的大小,但是我认为它是一个映射问题)

- svg分层分开,所以我可以手动更改颜色并应用它

但我试图让它变得动态,你选择一种颜色并自动更新应用为纹理的svg

有什么想法吗?

谢谢!

1 个答案:

答案 0 :(得分:2)

我分道别人的小提琴来展示解决方案。我添加了一个单击功能,可以修改SVG并重新绘制模型上的材质。

请参阅http://jsfiddle.net/L4pepnj7/

单击示例中的任意位置以更改SVG中圆圈的颜色。

将SVG转换为encodedURI的操作是密集的以具有恒定循环,但是您可以在渲染器执行它自己的事情时将颜色更改放在单击事件中。我添加了一个名为" clickBody"改变现有小提琴,改变其中一个SVG元素的颜色。

var mesh;
var scene = new THREE.Scene();

var camera = new THREE.PerspectiveCamera(50, 500 / 400, 0.1, 1000);
camera.position.z = 10;

var renderer = new THREE.WebGLRenderer({
    antialias: true
});
renderer.setSize(500, 400);
document.body.appendChild(renderer.domElement);

var svg = document.getElementById("svgContainer").querySelector("svg");
var svgData = (new XMLSerializer()).serializeToString(svg);

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");
var material;
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);
    material = new THREE.MeshBasicMaterial({
        map: texture
    });
    material.map.minFilter = THREE.LinearFilter;
    mesh = new THREE.Mesh(geometry, material);
    scene.add(mesh);
};



var colors = ["red", "orange", "yellow", "green", "blue"];


var c = 0;

function clickBody() {
    document.getElementById("test").setAttribute("fill", colors[c]);
    var svgData = (new XMLSerializer()).serializeToString(svg);
    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);
        material.map = texture;
        material.map.needsUpdate = true;
        renderer.render(scene, camera);
    }
    c = c + 1;
    if (c == colors.length) {
        c = 0;
    }
}
document.body.addEventListener("click", clickBody)

var render = function() {
    requestAnimationFrame(render);
    mesh.rotation.y += 0.01;
    renderer.render(scene, camera);
};


render();