#three.js #color-picker
#three.js #средство выбора цвета
Вопрос:
Я пытаюсь изменить цвет 3D-объекта, где он пересекается, с помощью средства выбора цвета.Я пытаюсь с помощью dat.gui.Я хочу изменить цвет 3D-детали, на которую нажимается, и изменить выбранный из палитры цветов.Я попробовал несколько возможных способов, но это не сработало.Пожалуйста, обратитесь к коду, который я опробовал. Помогите мне с каким-нибудь решением и обратите мое внимание на то, где я ошибаюсь. Спасибо.
<!DOCTYPE html>
<html lang="en">
<head>
<title>color</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #000;
color: #fff;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<script src="three.js"></script>
<script src="OrbitControls.js"></script>
<script src="Detector.js"></script>
<script src="stats.min.js"></script>
<script src="loaders/MTLLoader.js"></script>
<script src="loaders/OBJLoader.js"></script>
<script type='text/javascript' src='DAT.GUI.min.js'></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container, stats;
var camera, controls, scene, renderer,effectController;
var raycaster;
var objects = [];
var selectedObject,selectedPos;
var rotation;
var pos,quat;
var INTERSECTED;
var guiColor;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.z = 15;
controls = new THREE.OrbitControls( camera );
scene = new THREE.Scene();
scene.background = new THREE.Color( 0x555000 );
scene.add( camera );
// light
var dirLight = new THREE.DirectionalLight( 0xffffff );
dirLight.position.set( 200, 200, 1000 ).normalize();
camera.add( dirLight );
camera.add( dirLight.target );
var mtlLoader = new THREE.MTLLoader(); mtlLoader.setBaseUrl('assets/'); mtlLoader.setPath('assets/'); mtlLoader.load('anno.mtl', function (materials) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials);
objLoader.setPath('assets/');
objLoader.load('anno.obj', function (object) {
scene.add( object );
objects.push( object );
});
});
// renderer
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
/* Controls */
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.enableZoom = false;
raycaster = new THREE.Raycaster();
gui = new dat.GUI();
parameters =
{
color: "#ff0000",
};
gui.add( parameters, 'reset' ).name("Reset");
guiColor = gui.addColor( parameters, 'color' ).name('Color');
container = document.createElement( 'div' );
document.body.appendChild( container );
container.appendChild( renderer.domElement );
stats = new Stats();
container.appendChild( stats.dom );
window.addEventListener( 'resize', onWindowResize, false );
renderer.domElement.addEventListener("click", onclick, false);
}
var mouse = new THREE.Vector2();
function onclick(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 1;
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObjects(objects, true);
if (intersects.length > 0) {
INTERSECTED = intersects[0].object;
if ( INTERSECTED amp;amp; INTERSECTED.material.emissive != null ){
guiColor.onChange(function(){
INTERSECTED.material.emissive.setHex(parameters.color)
});
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
renderer.render( scene, camera );
stats.update();
}
</script>
</body>
</html>
Ответ №1:
Я создал небольшую демонстрационную версию с вашим кодом и базовым рабочим решением. Я хотел бы выделить три важных изменения:
- Вы можете использовать
onChange()
обработчик событий, чтобы узнать, когда изменилось определенноеdat.gui
свойство. Демонстрационная версия использует эту функцию для обновления цвета выбранного объекта. - Я переработал вашу логику raycasting во что-то более простое. Я видел, что вы скопировали некоторый код из официальных
three.js
примеров, но нового кода должно быть достаточно для вашего случая. Кроме того, также лучше обновитьMaterial.color
вместоMaterial.emissive
. - Если вы установили
OrbitControls.enableDamping
значениеtrue
, вам необходимо обновить элементы управления в цикле анимации.
https://jsfiddle.net/btuzd23o/2/
three.js R103