Saya sedang membangun prototipe SPA dengan Angular dan Three.Js untuk mempelajari kedua teknologi tersebut. Saya memiliki beberapa templat Angular yang dapat dipilih melalui navigasi, dan menunjukkan berbagai elemen 3D yang berputar.

Elemen kubus menunjukkan perilaku aneh; ketika Anda menavigasi ke tab lain dan kemudian menavigasi kembali, kecepatan rotasinya meningkat. Ini tidak terjadi dengan elemen 3D lainnya, dan saya tidak tahu mengapa.

Berikut ini tautan ke proyek.

// CUBE ROTATION VALUES
var cubeRotationX = .005;
var cubeRotationY = .005;

// CUBE SIZE VALUE
var cubeSize = 1;

// LOAD A CUBE
var geometry = new THREE.BoxGeometry( cubeSize, cubeSize, cubeSize );
var material = new THREE.MeshPhongMaterial  ( { color: 0xEDEDED, } );
var cube = new THREE.Mesh( geometry, material );

// CUBE CHANGE SIZE FUNCTION
function changeCubeSize() {
    cubeSize = document.getElementById('size-selector').value;
}

// CUBE TOGGLE FUNCTION
function toggleCubeRotation() {
    if (cubeRotationX > 0) {
        cubeRotationX = 0;
        cubeRotationY = 0;
    } else {
        cubeRotationX = 0.005;
        cubeRotationY = 0.005;
    }
}

// RENDER
    function render() {
        requestAnimationFrame( render );
        cube.rotation.x += cubeRotationX;
        cube.rotation.y += cubeRotationY;
        renderer.setSize( width, height );
        renderer.render( scene, camera );
    }

Jelas, ketika menavigasi menjauh dari, dan kemudian kembali ke, halaman kubus, Angular menjalankan kode ini lagi.

Setelah pengujian, saya dapat mengonfirmasi bahwa cubeRotationX dan cubeRotationY adalah nilai yang benar (0,005). Jadi tampaknya loop tersebut berasal dari cubeRotationX dan cubeRotationY yang ditambahkan beberapa kali ke cube.rotation.x dan cube.rotation.y, tetapi loop terjadi BAHKAN JIKA saya secara khusus melarang kedua baris ini berjalan lebih dari sekali:

if (typeof code_happened === 'undefined') {
        window.code_happened = true;
        render();
    } else {
        function reRender() {
            requestAnimationFrame( render );
            renderer.setSize( width, height );
            renderer.render( scene, camera );
        }
        reRender();
       }

Serius, saya tahu ini adalah sesuatu yang sederhana, tetapi saya tidak bisa seumur hidup saya mengetahuinya. Bantuan apa pun sangat dihargai.

0
j_d 31 Mei 2015, 23:34
Apakah Anda perlu menelepon cancelAnimationFrame suatu saat?
 – 
2pha
1 Juni 2015, 03:53
Itu ide, saya akan memeriksanya.
 – 
j_d
2 Juni 2015, 20:45
Ya, itu berhasil. Bersulang!
 – 
j_d
3 Juni 2015, 01:21

1 menjawab

Jawaban Terbaik

Seperti yang disarankan oleh 2pha, dalam hal ini yang perlu terjadi adalah menelepon

cancelAnimationFrame( id );

Bagi siapa pun yang bekerja dengan templat ThreeJs dan Angular di masa mendatang, saya cukup mengubah fungsi "hanya-jalankan-sekali" seperti ini:

if (typeof code_happened === 'undefined') {
        window.code_happened = true;
        render();
    } else {
        function reRender() {
            cancelAnimationFrame( cubeRender );
            cubeRender = requestAnimationFrame( render );
            renderer.setSize( width, height );
            renderer.render( scene, camera );
        }
        reRender();
       }

Dengan cara ini, ketika kembali ke halaman, render yang ada akan dibatalkan dan yang baru dibuat. Mungkin lebih baik untuk mengakhiri render setelah meninggalkan template, tetapi sejauh yang saya tahu, ThreeJs tidak merender di latar belakang.

0
j_d 3 Juni 2015, 01:24