【小沐学Web3D】three.js 加载三维模型(Svelte.js)

1、简介

1.1 Three.js

Three.js 是一个功能强大的 3D 图形库,用于在网页上创建和显示交互式 3D 图形。它基于 WebGL,提供了简单易用的 API,帮助开发者快速构建复杂的 3D 场景。

npm install three

1.2 Svelte.js

https://svelte.dev/
Svelte 是一个用于构建 Web 应用的工具。像其他用户界面框架一样,它允许你以声明式的方式使用组件构建应用,这些组件结合了标记、样式和行为。

npx sv create myapp
cd myapp
npm install
npm run dev
# or
npm run dev -- --open

Svelte 是一种新兴的前端 JavaScript 框架,它通过编译时优化来提供高性能的用户界面。与其它框架不同的是,Svelte 在构建阶段而非运行时执行大部分优化工作,这意味着最终生成的应用程序体积更小、性能更好。

2、测试

2.1 初始化环境

Svelte 依赖于 Node.js 和 npm 进行包管理和编译,可通过在终端或命令提示符中运行node -v和npm -v命令来检查是否已安装。

node -v
npm -v

在这里插入图片描述
ite 是一个快速的前端构建工具,能为 Svelte 项目提供便捷的开发体验。在终端或命令提示符中执行命令npm create vite@latest my-svelte-app,其中my-svelte-app是项目名称,可根据自己的需求修改。

npm create vite@latest my-svelte-app

在这里插入图片描述
执行命令后,会提示选择框架,使用方向键选中 Svelte 选项后回车;
在这里插入图片描述
接着再选择 JavaScript 或 TypeScript,一般初学者可先选择 JavaScript。
在这里插入图片描述
然后进入项目目录cd my-svelte-app,再运行npm install命令安装项目所需的依赖。
在这里插入图片描述

cd my-svelte-app
npm install
npm run dev
# or
npm run dev -- --open 

在这里插入图片描述

安装完依赖后,使用npm run dev命令启动开发服务器,服务器启动后会在终端输出一个本地服务器地址,通常是http://localhost:5173,打开浏览器访问该地址,即可看到默认的 Svelte 项目页面。
在这里插入图片描述

2.2 直接主页面展示

  • App.svelte:
<script>
  import { onMount} from 'svelte';
  import * as THREE from 'three';

  let container;
  let scene, camera, renderer;
  let cube;

  // 初始化场景
  function init() {
    if (!container) return; // 如果 container 未挂载,则返回

    // 创建场景
    scene = new THREE.Scene();
    scene.background = new THREE.Color(0x000000);

    // 创建相机
    camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);
    camera.position.z = 5;

    // 创建渲染器
    renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize(container.clientWidth, container.clientHeight);
    renderer.setPixelRatio(window.devicePixelRatio);
    container.appendChild(renderer.domElement); // 将渲染器的 container 添加到 div 中

    // 创建立方体
    const geometry = new THREE.BoxGeometry();
    const material = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: false });
    cube = new THREE.Mesh(geometry, material);
    scene.add(cube);

    // 添加光源
    const ambientLight = new THREE.AmbientLight(0x404040); // 环境光
    scene.add(ambientLight);

    const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5); // 平行光
    directionalLight.position.set(1, 1, 1);
    scene.add(directionalLight);

    // 开始动画
    animate();
  }

  // 动画函数
  function animate() {
    requestAnimationFrame(animate);
    
    // 旋转立方体
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;

    renderer.render(scene, camera);
  }

  // 处理窗口大小变化
  function onWindowResize() {
    if (!container) return; // 如果 container 未挂载,则返回
    if (!camera || !renderer) return; // 如果相机或渲染器未初始化,则返回

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

  // 监听窗口大小变化
  window.addEventListener('resize', onWindowResize);

  // 当组件挂载到DOM时初始化
  onMount(() => {
    init();
  });

</script>

<div bind:this={container} style="width: 100%; height: 100vh;"></div>

再次刷新http://localhost:5173:
在这里插入图片描述
修改app.css如下:

:root {
  font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
  line-height: 1.5;
  font-weight: 400;

  color-scheme: light dark;
  color: rgba(255, 255, 255, 0.87);
  background-color: #242424;

  font-synthesis: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  margin: 0;
  min-width: 320px;
}

#app {
  margin: 0 auto;
  text-align: center;
}

再次刷新http://localhost:5173:
在这里插入图片描述
欧克!!!

2.3 创建子页面展示

  • App.svelte:
<script>
  import Cube from './Cube.svelte';
</script>

<main>
  <h1>Three.js 立方体示例</h1>
  <Cube />
</main>

<style>
  main {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100vh;
    background-color: #f0f0f0;
  }

  h1 {
    margin-bottom: 20px;
  }
</style>
  • Cube.svelte:
<script>
    import * as THREE from 'three';
    import { onMount } from 'svelte';

    let container;

    onMount(() => {
        if (!container) {
            console.error('Container not found!');
            return;
        }

        try {
            const scene = new THREE.Scene();
            const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);
            camera.position.z = 5;

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

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

            const ambientLight = new THREE.AmbientLight(0x404040);
            scene.add(ambientLight);
            const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
            directionalLight.position.set(0, 1, 0);
            scene.add(directionalLight);

            function animate() {
                requestAnimationFrame(animate);
                cube.rotation.x += 0.01;
                cube.rotation.y += 0.01;
                renderer.render(scene, camera);
            }
            animate();

            window.addEventListener('resize', () => {
                camera.aspect = container.clientWidth / container.clientHeight;
                camera.updateProjectionMatrix();
                renderer.setSize(container.clientWidth, container.clientHeight);
            });

        } catch (error) {
            console.error('Error initializing Three.js:', error);
        }
    });
</script>

<div bind:this={container} style="width: 100%; height: 100vh;"></div>

运行,在浏览器查看如下:
在这里插入图片描述

结语

如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭
如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O???
如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡)
感谢各位童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值