<template>
  <div ref="container"></div>
</template>
<script lang="ts">
import { defineComponent, ref, onMounted, onBeforeUnmount } from 'vue'
import * as THREE from 'three'

export default defineComponent({
  name: 'ThreeScene',
  setup() {
    const container = ref<HTMLDivElement>()

    let scene: THREE.Scene
    let camera: THREE.PerspectiveCamera
    let renderer: THREE.WebGLRenderer

    const init = () => {
      // create scene
      scene = new THREE.Scene()

      // create camera
      camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
      camera.position.set(0, 0, 5)
      scene.add(camera)

      // create renderer
      renderer = new THREE.WebGLRenderer()
      renderer.setSize(window.innerWidth, window.innerHeight)
      container.value?.appendChild(renderer.domElement)

      // add geometry
      const geometry = new THREE.BoxGeometry()
      const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 })
      const cube = new THREE.Mesh(geometry, material)
      scene.add(cube)

      // render loop
      const animate = () => {
        requestAnimationFrame(animate)
        cube.rotation.x += 0.01
        cube.rotation.y += 0.01
        renderer.render(scene, camera)
      }
      animate()
    }

    const onResize = () => {
      camera.aspect = window.innerWidth / window.innerHeight
      camera.updateProjectionMatrix()
      renderer.setSize(window.innerWidth, window.innerHeight)
    }

    onMounted(() => {
      init()
      window.addEventListener('resize', onResize)
    })

    onBeforeUnmount(() => {
      window.removeEventListener('resize', onResize)
      container.value?.removeChild(renderer.domElement)
    })

    return {
      container,
    }
  },
})
</script>
<p>这个组件使用了 Vue3 Setup 语法糖和 TypeScript,它包含一个 'ThreeScene' 组件,它在页面中渲染了一个简单的 Three.js 场景。组件的模板只包含一个 'div' 元素,它通过 'ref' 指令绑定到了 'container' 变量上。</p>
<p>在组件的 'setup' 函数中,我们创建了三个变量 'scene'、'camera' 和 'renderer',它们都是在组件的 'init' 函数中初始化的。在 'init' 函数中,我们创建了一个 Three.js 场景、摄像机、渲染器,并且在场景中添加了一个绿色的立方体。我们还编写了一个渲染循环,它会在每一帧更新立方体的旋转并且重新渲染场景。</p>
<p>为了确保场景可以自适应窗口大小,我们在组件的 'onResize' 函数中更新了摄像机的 aspect 值,并且重新设置了渲染器的大小。我们在组件的 'onMounted' 生命周期钩子中初始化了场景、渲染器和渲染循环,并且在 'window' 对象上监听了 'resize' 事件。在组件的 'onBeforeUnmount' 生命周期钩子中,我们移除了 'resize' 事件监听器,并且从 'container' 元素中移除渲染器的 DOM 元素。最后,我们通过 'return' 语句将 'container' 变量暴露给了组件的模板。</p>
Vue3 Setup 语法糖和 TypeScript 封装 Three.js 组件

原文地址: https://www.cveoy.top/t/topic/mPUR 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录