#Nuxt3 & Threejs

4 messages · Page 1 of 1 (latest)

paper stream
#

Hello, I have implemented a 3d model with threejs but when I use NuxtLink to change the page and then come back to the page of my model it disappears. What should I do?

paper stream
#
<template>
    <div ref="container" class="w-full sm:h-[30rem] lg:block hidden relative overflow-hidden">
        <canvas id="canvas" ref="canvas"></canvas>
    </div>
</template>

<script setup lang="ts">
import { onMounted, ref, onBeforeUnmount } from 'vue';
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';

const container: { value: HTMLElement | null } = ref(null);
const canvas: { value: HTMLCanvasElement | null } = ref(null);

onMounted(() => {
    if (container.value && canvas.value) {
        setupWebGL(container.value, canvas.value);
    }
});

function setupWebGL(container: HTMLElement, canvas: HTMLCanvasElement) {
    const scene = new THREE.Scene();

    const light = new THREE.AmbientLight(0xffffff, 2.8)
    scene.add(light)

    const camera = new THREE.PerspectiveCamera(
        20,
        container.clientWidth / container.clientHeight,
        0.1,
        200
    );
    camera.position.set(-4, 3, 6);

    const renderer = new THREE.WebGLRenderer({
        canvas,
        antialias: true,
        preserveDrawingBuffer: true,
        alpha: true,
    });
    renderer.setSize(container.clientWidth, container.clientHeight);

    const controls = new OrbitControls(camera, renderer.domElement);
    controls.autoRotate = true;
    controls.enablePan = false;
    controls.enableZoom = false;
    controls.maxPolarAngle = Math.PI / 2;
    controls.minPolarAngle = Math.PI / 2;

    const loader = new GLTFLoader();
    loader.load(
        '/models/planet.gltf',
        (gltf) => {
            gltf.scene.traverse((child) => {
                if (child instanceof THREE.Mesh) {
                    child.material = new THREE.MeshStandardMaterial({
                        color: child.material.color,
                        map: child.material.map,
                    });
                }
            });

            const earthMesh = gltf.scene;
            earthMesh.scale.set(1.25, 1.25, 1.25);
            scene.add(earthMesh);
            animate();
        },
        undefined,
        (error) => {
            console.error('An error occurred while loading the model:', error);
        }
    );

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

    function onWindowResize() {
        camera.aspect = container.clientWidth / container.clientHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(container.clientWidth, container.clientHeight);
    }

    window.addEventListener('resize', onWindowResize);

    onBeforeUnmount(() => {
        window.removeEventListener('resize', onWindowResize);
    });
}
</script>

<style scoped>
    .earth-container {
        width: 100%;
        height: 500px;
        overflow: hidden;
        position: relative;
    }
</style>
#

The problem remains when I change the page with NuxtLink because otherwise the template loads well when I reload the page. Unfortunately I haven't found any resources on the internet to help me 🥺 .

broken crypt