html不正确加载,nuxt 3 on已登机

发布于 2025-02-07 06:43:20 字数 3603 浏览 2 评论 0原文

我在实施NUXT 3和3J时遇到了麻烦。

<template>
  <div>
    <canvas ref="webgl" class="canvas"></canvas>
  </div>
</template>

<script setup>
import * as THREE from "three";

import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader.js";
const webgl = ref(null);

var renderer;
onMounted(async () => {
  await nextTick();
  console.log();
  if (process.client) {
    const canvas = document.querySelector(".canvas");
    //const canvas = webgl.value; Silent error but does not work
    console.log(canvas);
    //Getting canvas element

    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(32, 1, 0.1, 1000).translateZ(15);

    renderer = new THREE.WebGLRenderer({
      canvas,
      alpha: true,
      antialias: true,
    });

    // Creating a renderer
    renderer.setClearColor(0x000000, 0);
    renderer.setSize(canvas.clientWidth, canvas.clientHeight, false);
    renderer.setPixelRatio(window.devicePixelRatio);

    // Avoid pixelation on resize
    window.onresize = () => {
      renderer.setSize(canvas.clientWidth, canvas.clientHeight, false);
    };

    // Creating loader for custom GLTF models
    const loader = new GLTFLoader();
    const dracoLoader = new DRACOLoader();
    dracoLoader.setDecoderPath("https://www.gstatic.com/draco/v1/decoders/");
    loader.setDRACOLoader(dracoLoader);

    const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444, 0.9);
    hemiLight.position.set(0, 0, 15);
    scene.add(hemiLight);

    let model;
    loader.load(
      // resource URL
      "/models/molecule.glb",
      // called when the resource is loaded
      function (gltf) {
        model = gltf.scene;
        model.position.set(0, -0.4, -1);
        if (model) model.rotation.x += 90;
        scene.add(model);
      },
      // called while loading is progressing
      function (xhr) {
        console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
      },
      // called when loading has errors
      function (error) {
        console.log("An error happened", error);
      }
    );
    let x = 0;

    // start the loop
    renderer.setAnimationLoop(() => {
      if (model) {
        // --- Simple Rotation Animation
        // model.rotation.y += 0.002;
        // if (model.rotation.y >= 360) model.rotation.y = 0;
        // if (model.rotation.z >= 0) model.rotation.z -= 0.002;
        // else if (model.rotation.z <= 0) model.rotation.z += 0.002;
        // else {
        //   model.rotation.z += 0.0002;
        // }
        // --- Floating Animation
        x = x + 2;
        model.position.y = Math.cos(x * 0.01) * 0.3;
        model.rotation.z = Math.sin(x * 0.01) * 0.2;
        model.rotation.x = Math.sin(x * 3.14 * 0.01) * 0.02 + 90;
      }
      renderer.render(scene, camera);
    });
  }
});

onUnmounted(() => {
  renderer.setAnimationLoop(null);
});
</script>

<style scoped>
.canvas {
  width: 100%;
  height: 100%;
  z-index: 1;
}
</style>

我使用此代码将3D模型加载到VUE组件中,该组件包装了HTML画布。然后将其动画并安装在页面上。

如果我正常加载页面,则所有内容都可以正常工作,并且显示了带有模型的动画。但是,如果我导航到另一个页面并返回(通过VUE/NUXT路由器),

我会收到以下错误:

好像HTML帆布根本不存在。即使我在安装组件后声明它……

我也尝试使用模板参考,但随后该模型没有加载,也没有错误。

哦,为了记录,我正在以SSR模式运行该应用程序。

如果您能帮助我,我将永远感激不尽。 提前致谢!

I am having trouble with an implementation of Nuxt 3 and Threejs.

<template>
  <div>
    <canvas ref="webgl" class="canvas"></canvas>
  </div>
</template>

<script setup>
import * as THREE from "three";

import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader.js";
const webgl = ref(null);

var renderer;
onMounted(async () => {
  await nextTick();
  console.log();
  if (process.client) {
    const canvas = document.querySelector(".canvas");
    //const canvas = webgl.value; Silent error but does not work
    console.log(canvas);
    //Getting canvas element

    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(32, 1, 0.1, 1000).translateZ(15);

    renderer = new THREE.WebGLRenderer({
      canvas,
      alpha: true,
      antialias: true,
    });

    // Creating a renderer
    renderer.setClearColor(0x000000, 0);
    renderer.setSize(canvas.clientWidth, canvas.clientHeight, false);
    renderer.setPixelRatio(window.devicePixelRatio);

    // Avoid pixelation on resize
    window.onresize = () => {
      renderer.setSize(canvas.clientWidth, canvas.clientHeight, false);
    };

    // Creating loader for custom GLTF models
    const loader = new GLTFLoader();
    const dracoLoader = new DRACOLoader();
    dracoLoader.setDecoderPath("https://www.gstatic.com/draco/v1/decoders/");
    loader.setDRACOLoader(dracoLoader);

    const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444, 0.9);
    hemiLight.position.set(0, 0, 15);
    scene.add(hemiLight);

    let model;
    loader.load(
      // resource URL
      "/models/molecule.glb",
      // called when the resource is loaded
      function (gltf) {
        model = gltf.scene;
        model.position.set(0, -0.4, -1);
        if (model) model.rotation.x += 90;
        scene.add(model);
      },
      // called while loading is progressing
      function (xhr) {
        console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
      },
      // called when loading has errors
      function (error) {
        console.log("An error happened", error);
      }
    );
    let x = 0;

    // start the loop
    renderer.setAnimationLoop(() => {
      if (model) {
        // --- Simple Rotation Animation
        // model.rotation.y += 0.002;
        // if (model.rotation.y >= 360) model.rotation.y = 0;
        // if (model.rotation.z >= 0) model.rotation.z -= 0.002;
        // else if (model.rotation.z <= 0) model.rotation.z += 0.002;
        // else {
        //   model.rotation.z += 0.0002;
        // }
        // --- Floating Animation
        x = x + 2;
        model.position.y = Math.cos(x * 0.01) * 0.3;
        model.rotation.z = Math.sin(x * 0.01) * 0.2;
        model.rotation.x = Math.sin(x * 3.14 * 0.01) * 0.02 + 90;
      }
      renderer.render(scene, camera);
    });
  }
});

onUnmounted(() => {
  renderer.setAnimationLoop(null);
});
</script>

<style scoped>
.canvas {
  width: 100%;
  height: 100%;
  z-index: 1;
}
</style>

I use this code to load a 3d model inside a vue component, which wraps an html canvas. Which then is animated and mounted on the page.

If I load the page normally, then everything works, and the animation with the model is shown. But if I navigate to another page and back (via the Vue/Nuxt router)

I get the following error:
enter image description here

As if the html canvas did not exist at all. Even though I am declaring it after the component is mounted...

I also tried using template refs, but then the model just does not load, and there is no error too.

Oh and for the record, I am running the app on SSR mode.

I will be forever grateful if you can help me.
Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文