Javascript 在onclick事件期间重新定位摄影机(轨道控制)
我正在学习Javascript,重点是threeJS,并希望实现一个特定功能: 设置: 我在三个JS中创建了一个场景,其中包含一个.glb模型,多个精灵(标记)位于模型周围。光线投射器确定精灵元素是否悬停 我想添加的功能: 单击精灵时,相机应以能够捕捉精灵正下方模型零件的特写镜头的方式定位自身。最佳情况:此转换使用Tween.JS(或类似)实现平滑外观,并在再次单击特写场景时将摄影机位置重置回单击精灵之前的位置 我的尝试: 我将three.interactive添加到我的项目中,因为它似乎是向场景中的特定对象添加事件的最简单方法。我在第一个Sprite对象上附加了onclick事件,到目前为止它仍然有效。 在本例中,我使用延迟console.log获得的坐标设置Javascript 在onclick事件期间重新定位摄影机(轨道控制),javascript,three.js,Javascript,Three.js,我正在学习Javascript,重点是threeJS,并希望实现一个特定功能: 设置: 我在三个JS中创建了一个场景,其中包含一个.glb模型,多个精灵(标记)位于模型周围。光线投射器确定精灵元素是否悬停 我想添加的功能: 单击精灵时,相机应以能够捕捉精灵正下方模型零件的特写镜头的方式定位自身。最佳情况:此转换使用Tween.JS(或类似)实现平滑外观,并在再次单击特写场景时将摄影机位置重置回单击精灵之前的位置 我的尝试: 我将three.interactive添加到我的项目中,因为它似乎是向场
camera.controls.set(x,y,z)
,这使我能够打开文档,根据需要定位摄像机并复制新的x,y,z值
sprite.addEventListener("click", (event) => {
camera.position.set(-4,1,2);
});
单击指定的精灵不会移动相机。但结果与前一幕并不相同。我相信这是由于一些全球位置的价值,我还不了解
THREE.js文件(非常感谢一般反馈,这里是新手)
//CREATE SCENE
const scene = new THREE.Scene();
//CREATE CAMERA
const camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 2000);
//CREATE RENDERER
const renderer = new THREE.WebGLRenderer({antialias: true, alpha: true});
renderer.toneMapping = THREE.CineonToneMapping;
renderer.toneMappingExposure = 1.0;
renderer.shadowMap.enabled = true;
renderer.setClearColor( 0xFFF8F3, 0);
renderer.setSize(window.innerWidth,window.innerHeight);
//PIN RENDERER TO DIV ID "model"
document.getElementById("model").appendChild(renderer.domElement);
//INTERACTIVE MANAGER THROUGH THREE INTERACTIVE
const interactionManager = new THREE.InteractionManager(
renderer,
camera,
renderer.domElement
);
//ADD LIGHT TO SCENE
let light = new THREE.HemisphereLight(0x949494, 0x616161, 1)
scene.add(light);
let directionallight_1 = new THREE.DirectionalLight(0xFFFFFF, 1);
directionallight_1.castShadow = true;
scene.add(directionallight_1);
directionallight_1.position.set(15,3,-6.5)
let spotLight_1 = new THREE.SpotLight(0xFDF1DF, 1);
spotLight_1.position.set(-15,-3,6.5)
scene.add(spotLight_1);
let spotLight_2 = new THREE.SpotLight(0xFDF1DF, 1);
spotLight_2.position.set(15,-3,-6.5)
scene.add(spotLight_2);
//LOAD 3D MODEL
let loader = new THREE.GLTFLoader();
let obj;
loader.load("src/assets/models/plugger/new_Plugger.glb", function (gltf) {
obj = gltf.scene;
scene.add(gltf.scene);
obj.position.set(0, -0.85, 0);
});
//LOAD SPRITE
const map = new THREE.TextureLoader().load( './src/assets/svg/map-marker-alt-solid.svg' );
//UNIQUE MATERIAL FOR EACH SPRITE TO DISTINGUISH THEM DURING RAYCASTING
const material_1 = new THREE.SpriteMaterial( { map: map } );
const material_2 = new THREE.SpriteMaterial( { map: map } );
const material_3 = new THREE.SpriteMaterial( { map: map } );
const material_4 = new THREE.SpriteMaterial( { map: map } );
//CREATE SPRITE
const sprite = new THREE.Sprite( material_1 );
sprite.position.set(-1.500, 0.753, -1.600);
sprite.scale.set(0.200,0.266,0.200);
sprite.material.transparent = true;
sprite.material.opacity = 1;
sprite.name = "sprite_1";
sprite.castShadow = true;
interactionManager.add(sprite);
sprite.addEventListener("click", (event) => {
camera.position.set(-4,0.18,1.98);
});
scene.add( sprite );
//LOAD ORBIT CONTROLS
const controls = new THREE.OrbitControls( camera, renderer.domElement );
//controls.update() must be called after any manual changes to the camera's transform
camera.position.set( -4.44, 2.25, 3.50)
controls.enableZoom = true;
controls.enableRotate = true;
controls.rotateSpeed = 1.0;
controls.maxPolarAngle = Math.PI * 0.5;
controls.minPolarAngle = 0.8;
controls.update();
//RESIZE SCENE ON WINDOW-RESIZE
window.addEventListener( 'resize', onWindowResize, false );
function onWindowResize(){
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
//ANIMATE THE SCENE + MISC. FUNCTIONS
let animate = function(callback) {
function loop(time) {
callback(time);
let raycaster = new THREE.Raycaster();
let direction = new THREE.Vector3()
.copy(mouse)
.unproject(camera)
.sub(camera.position)
.normalize();
raycaster.setFromCamera(mouse,camera);
raycaster.set(camera.position, direction);
scene.children.forEach(function (child) {
if (child instanceof THREE.Sprite)
child.material.opacity = 1.0;
});
let intersects = raycaster.intersectObjects(scene.children, true);
intersects.forEach(function (element) {
let object = element.object;
if (object instanceof THREE.Sprite)
object.material.opacity = 0.5;
})
interactionManager.update();
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
}
// RENDER THE SCENE
animate(() => {
renderer.render(scene,camera);
});