动态更改 svg 的颜色并在three.js 中作为纹理应用 [英] Change color of an svg dynamically and apply as texture in three.js

查看:29
本文介绍了动态更改 svg 的颜色并在three.js 中作为纹理应用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用three.js创建一个配置器,但我需要更改产品的颜色,虽然我可以使用svg作为纹理,但更改svg的填充属性并轻松更新纹理,但效果不佳

i´m trying to create a configurator with three.js but im at the point that i need to change the color of the product dinamycally, i though that i can use an svg as texture, change the fill property of the svg and update the texture easily, but im not having good results

目前我拥有的是

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

-A 3D model with an svg applied as texture with a TextureLoader, but the svg is placed in a external file ("images/texture.svg")(also three.js is reducing the size of the texture, but i think its a mapping problem)

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

-The svg is separated in layers, so i can manually change the color and apply it

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

But im trying to make it dynamic, you choose a color and it automatically updates the svg applied as texture

有什么想法吗?

谢谢!

推荐答案

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

I forked someone else's fiddle to show the solution. I added a click function which modifies the SVG and redraws the material on the model.

http://jsfiddle.net/L4pepnj7/

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

Click anywhere on the example to change the color of the circle in the SVG.

将 SVG 转换为编码的 URI 的操作需要在一个恒定循环中进行,但您可以在渲染器自行处理时将颜色更改放入单击事件中.我在现有的 fiddle 中添加了一个名为clickBody"的函数,它改变了其中一个 SVG 元素的颜色.

The operation which converts the SVG to an encodedURI is to intensive to have in a constant loop, but you can put the color change in a click event while the renderer is doing it's own thing. I added a function called "clickBody" to the existing fiddle which changes the color of one of the SVG elements.

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

这篇关于动态更改 svg 的颜色并在three.js 中作为纹理应用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆