Javascript 在onclick事件期间重新定位摄影机(轨道控制)

Javascript 在onclick事件期间重新定位摄影机(轨道控制),javascript,three.js,Javascript,Three.js,我正在学习Javascript,重点是threeJS,并希望实现一个特定功能: 设置: 我在三个JS中创建了一个场景,其中包含一个.glb模型,多个精灵(标记)位于模型周围。光线投射器确定精灵元素是否悬停 我想添加的功能: 单击精灵时,相机应以能够捕捉精灵正下方模型零件的特写镜头的方式定位自身。最佳情况:此转换使用Tween.JS(或类似)实现平滑外观,并在再次单击特写场景时将摄影机位置重置回单击精灵之前的位置 我的尝试: 我将three.interactive添加到我的项目中,因为它似乎是向场

我正在学习Javascript,重点是threeJS,并希望实现一个特定功能:

设置:

我在三个JS中创建了一个场景,其中包含一个.glb模型,多个精灵(标记)位于模型周围。光线投射器确定精灵元素是否悬停

我想添加的功能:

单击精灵时,相机应以能够捕捉精灵正下方模型零件的特写镜头的方式定位自身。最佳情况:此转换使用Tween.JS(或类似)实现平滑外观,并在再次单击特写场景时将摄影机位置重置回单击精灵之前的位置

我的尝试:

我将three.interactive添加到我的项目中,因为它似乎是向场景中的特定对象添加事件的最简单方法。我在第一个Sprite对象上附加了onclick事件,到目前为止它仍然有效。 在本例中,我使用延迟console.log获得的坐标设置
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);

});