preface

The camera transition code found on the Internet either has a problem with the code, or it is suggested to write the trajectory coordinate to move. What I want is to be able to face the target model after moving to the target coordinate, and to adjust the Angle of the camera towards the target model. Finally, I realized this function with the knowledge of trigonometric functions accumulated by Canvas.

The preparatory work

  1. Download tween.js for the transition effect
  2. If you want to review trigonometry, check out this website www.shuxuele.com/sine-cosine…

Problem description

After testing, there was no problem when the camera moved to the target coordinate. The problem was that the camera was looking at the target from the wrong Angle, and the camera could not face the target model. The effect is shown below

Function implementation

  • Formula:
    • Math.pi / 2 = radians, which translates to degrees = 90 degrees.
    • X = math.cos (math.pi / 2) * Interval distance + target coordinates
    • Y = math.sin (math.pi / 2) * interval distance + target coordinates

It is possible to look at a 90-degree Angle without using Math.pi / 2, which means you can’t set the Angle you want to look at.

The complete code

<! DOCTYPE html><html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        body {
            margin: 0;
        }
    </style>
</head>
<body>
<div id="WebGl-output"></div>
<script src="libs/three.js"></script>
<script src="libs/OrbitControls.js"></script>
<script src="libs/tween.js"></script>
<script>
    let scene = new THREE.Scene()
    let camera = new THREE.PerspectiveCamera(45.window.innerWidth / window.innerHeight, 0.1.1000)

    let renderer = new THREE.WebGLRenderer()
    renderer.setClearColor(0x000000);
    renderer.setSize(window.innerWidth, window.innerHeight)
    renderer.shadowMap.enabled = true

    let axes = new THREE.AxesHelper(20)
    scene.add(axes)

    let planeGeometry = new THREE.PlaneGeometry(60.20.1.1)
    let planeMatrices = new THREE.MeshLambertMaterial({color: 0xAAAAAA})
    let plane = new THREE.Mesh(planeGeometry, planeMatrices)
    plane.position.set(15.0.0)
    plane.rotation.set(-0.5 * Math.PI, 0.0)
    plane.receiveShadow = true
    scene.add(plane)

    let cubeGeometry = new THREE.BoxGeometry(4.4.4)
    let cubeMatrices = new THREE.MeshLambertMaterial({
        color: 0xff0000,})let cube = new THREE.Mesh(cubeGeometry, cubeMatrices)
    cube.castShadow = true
    cube.position.set(-4.3.0)
    scene.add(cube)

    let sphereGeometry = new THREE.SphereGeometry(4.20.20)
    let sphereMatrices = new THREE.MeshLambertMaterial({
        color: 0x7777ff,})let sphere = new THREE.Mesh(sphereGeometry, sphereMatrices)
    sphere.position.set(20.4.2)
    sphere.castShadow = true
    scene.add(sphere)

    let spotLight = new THREE.SpotLight(0xffffff)
    spotLight.position.set(-40.40, -15)
    spotLight.castShadow = true
    spotLight.shadow.mapSize = new THREE.Vector2(1024.1024);
    spotLight.shadow.camera.far = 130;
    spotLight.shadow.camera.near = 40;
    scene.add(spotLight)

    camera.position.set(-30.40.30)
    camera.lookAt(scene.position)

    let ambient = new THREE.AmbientLight(0x353535);
    scene.add(ambient);

    document.getElementById('WebGl-output').append(renderer.domElement)

    let controls = new THREE.OrbitControls(camera, renderer.domElement)

    controls.target = new THREE.Vector3(0.0.0)

    const raycaster = new THREE.Raycaster()
    let mouse = new THREE.Vector2()
    let intersects = null
    renderer.domElement.addEventListener('click'.function (event) {
        mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
        mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
        raycaster.setFromCamera(mouse, camera);
        intersects = raycaster.intersectObject(scene, true);
        if (intersects.length > 0) {
            let boxMaxY = new THREE.Box3().setFromObject(intersects[0].object).max.y

            let distance = boxMaxY + 10
            let angel = Math.PI / 5

            let position = {
                x: intersects[0].object.position.x + Math.cos(angel) * distance,
                y: intersects[0].object.position.y,
                z: intersects[0].object.position.z + Math.sin(angel) * distance
            }

            let tween = new TWEEN.Tween(camera.position).to(position, 3000)
            let tween1 = new TWEEN.Tween(controls.target).to(intersects[0].object.position, 3000)

            controls.enabled = false;
            tween.onComplete(function () {
                controls.enabled = true;
            })

            tween.start()
            tween1.start()
        }
    });

    function render() {
        requestAnimationFrame(render)
        TWEEN.update()
        controls.update()
        renderer.render(scene, camera)
    }

    render()
</script>
</body>
</html>
Copy the code