3D个人简历网站 5.天空、鸟、飞机

1.显示天空

models下新建文件Sky.jsx

Sky.jsx

// 从 React 库中导入 useRef 钩子,用于创建可变的 ref 对象
import { useRef } from "react";
// 从 @react-three/drei 库中导入 useGLTF 钩子,用于加载 GLTF 格式的 3D 模型
import { useGLTF } from "@react-three/drei";
// 从 @react-three/fiber 库中导入 useFrame 钩子,用于在每一帧渲染时执行代码
import { useFrame } from "@react-three/fiber";// 导入天空 3D 模型的 GLB 文件
import skyScene from "../assets/3d/sky.glb";// 3D 模型来源注释,表明模型来自 Sketchfab 网站
// 3D Model from: https://sketchfab.com/3d-models/phoenix-bird-844ba0cf144a413ea92c779f18912042
/*** Sky 组件,用于渲染可旋转的天空 3D 模型* @param {boolean} isRotating - 控制天空模型是否旋转的布尔值* @returns {JSX.Element} 包含天空 3D 模型的 React 元素*/
export function Sky({ isRotating }) {// 使用 useGLTF 钩子加载天空 3D 模型,返回包含模型信息的对象const sky = useGLTF(skyScene);// 使用 useRef 钩子创建一个 ref 对象,用于引用天空模型的 DOM 元素const skyRef = useRef();// 注释说明动画名称可在 Sketchfab 网站找到,以及使用 delta 确保动画帧率独立// Note: Animation names can be found on the Sketchfab website where the 3D model is hosted.// It ensures smooth animations by making the rotation frame rate-independent.// 'delta' represents the time in seconds since the last frame./*** 在每一帧渲染时更新天空模型的旋转状态*/useFrame((_, delta) => {// 如果 isRotating 为 true,则更新天空模型的 y 轴旋转角度if (isRotating) {// 调整旋转速度,delta 确保旋转速度不受帧率影响skyRef.current.rotation.y += 0.25 * delta; }});/*** 渲染天空 3D 模型组件* 返回一个包含天空 3D 模型的 mesh 元素*/return (// 创建一个 mesh 元素,用于承载 3D 模型,并通过 ref 关联到 skyRef<mesh ref={skyRef}>{/* 使用 primitive 元素直接嵌入从 GLTF 文件加载的复杂 3D 模型或场景。object 属性指定要嵌入的 3D 对象,这里使用从 GLTF 文件加载的场景。*/}<primitive object={sky.scene} /></mesh>);
}

models下新建文件index.jsx

index.jsx

export { Sky } from "./Sky";
export { Island } from "./Island";

删除Island.jsx末尾文件"export default Island"语句

在Home.jsx中添加Sky相关代码显示天空效果

Home.jsx

……
// 从 ../models/Island 路径导入 Island 组件,此组件用于渲染 3D 岛屿模型
import { Island, Sky } from "../models"……/*** Home 组件,作为应用的主页组件。* 该组件会依据屏幕尺寸对 Island 组件的缩放、位置和旋转进行调整,* 并且在 Canvas 中渲染 Island 组件,同时处理异步加载状态。* @returns {JSX.Element} 渲染后的 JSX 元素*/
const Home = () => {/*** 根据屏幕尺寸调整 Island 组件的缩放、位置和旋转。* @returns {Array} 包含屏幕缩放比例、位置和旋转值的数组*/// 定义一个状态变量 isRotating,用于控制 Sky 组件的旋转状态const [isRotating, setIsRotating] = React.useState(false)const adjustIslandForScreenSize = () => {
……{/* 渲染 Island 组件,设置其位置、缩放和旋转属性 */}<Islandposition={islandPosition}scale={islandScale}rotation={islandRotation}/>{/* 渲染 Sky 组件,设置其旋转状态 */}<Sky isRotating={isRotating}/>
……

效果图

2.飞翔的鸟

models下添加文件Bird.jsx

Bird.jsx

// 从 react 库中导入 useEffect 和 useRef 钩子
// useEffect 用于处理副作用,如数据获取、订阅等
// useRef 用于创建可变的 ref 对象,可在组件的整个生命周期内保持值
import { useEffect, useRef } from "react";
// 从 @react-three/fiber 库中导入 useFrame 钩子
// useFrame 用于在每一帧渲染时执行代码,常用于实现动画效果
import { useFrame } from "@react-three/fiber";
// 从 @react-three/drei 库中导入 useAnimations 和 useGLTF 钩子
// useGLTF 用于加载 GLTF 格式的 3D 模型
// useAnimations 用于管理 3D 模型的动画
import { useAnimations, useGLTF } from "@react-three/drei";// 导入鸟类 3D 模型的 GLB 文件
import birdScene from "../assets/3d/bird.glb";// 3D 模型来源注释,表明模型来自 Sketchfab 网站
// 3D Model from: https://sketchfab.com/3d-models/phoenix-bird-844ba0cf144a413ea92c779f18912042
/*** Bird 组件,用于渲染会移动和播放动画的鸟类 3D 模型* @returns {JSX.Element} 包含鸟类 3D 模型的 React 元素*/
export function Bird() {// 使用 useRef 钩子创建一个 ref 对象,用于引用鸟类 3D 模型的 DOM 元素const birdRef = useRef();// 使用 useGLTF 钩子加载鸟类 3D 模型和动画数据// scene 为加载后的 3D 模型场景// animations 为模型包含的动画数组const { scene, animations } = useGLTF(birdScene);// 使用 useAnimations 钩子获取动画动作对象// actions 是一个包含动画动作的对象,可用于控制动画的播放、暂停等const { actions } = useAnimations(animations, birdRef);// 使用 useEffect 钩子,在组件挂载时执行一次// 作用是播放名为 "Take 001" 的动画useEffect(() => {// 播放 "Take 001" 动画actions["Take 001"].play();}, []);// 使用 useFrame 钩子,在每一帧渲染时执行代码useFrame(({ clock, camera }) => {// 使用正弦函数模拟鸟类上下波动的飞行效果// clock.elapsedTime 表示从时钟启动到现在经过的时间// 通过正弦函数计算出一个波动值,乘以 0.2 并加上 2,更新鸟类模型的 Y 坐标birdRef.current.position.y = Math.sin(clock.elapsedTime) * 0.2 + 2;// 检查鸟类模型的 X 坐标是否超过相机 X 坐标加 10 的位置if (birdRef.current.position.x > camera.position.x + 10) {// 若超过,将鸟类模型旋转 180 度(沿 Y 轴),改变飞行方向为向后birdRef.current.rotation.y = Math.PI;} else if (birdRef.current.position.x < camera.position.x - 10) {// 若小于相机 X 坐标减 10 的位置,将鸟类模型旋转角度重置为 0,改变飞行方向为向前birdRef.current.rotation.y = 0;}// 根据鸟类模型的旋转角度更新其 X 和 Z 坐标// 如果旋转角度为 0,说明鸟类向前飞行if (birdRef.current.rotation.y === 0) {// 向前移动,X 坐标增加 0.01,Z 坐标减少 0.01birdRef.current.position.x += 0.01;birdRef.current.position.z -= 0.01;} else {// 向后移动,X 坐标减少 0.01,Z 坐标增加 0.01birdRef.current.position.x -= 0.01;birdRef.current.position.z += 0.01;}});return (// 创建一个 mesh 元素,用于承载 3D 模型// ref 关联到 birdRef,方便后续操作模型// position 设置模型的初始位置// scale 设置模型的缩放比例<mesh ref={birdRef} position={[-5, 2, 1]} scale={[0.003, 0.003, 0.003]}>{/* 使用 primitive 元素直接嵌入从 GLTF 文件加载的复杂 3D 模型或场景object 属性指定要嵌入的 3D 对象,这里使用从 GLTF 文件加载的场景*/}<primitive object={scene} /></mesh>);
}

index.jsx增加代码鸟相关代码,考虑到后面还有其他狐狸、飞机相关文件,这里统一一起添加了

index.jsx

export { Sky } from "./Sky";
export { Bird } from './Bird'
export { Plane } from "./Plane";
export { Island } from "./Island";
export { Fox } from "./Fox"

Home.jsx中增加代码

Home.jsx

……
// 从../models 路径导入组件,
import { Bird, Island, Sky } from "../models"
……{/* 渲染 Bird 组件 */}<Bird />
……

效果图

3.飞机

models下新建文件Plane.jsx

Plane.jsx

// 从 React 中导入 useEffect 和 useRef 钩子
// useEffect 用于处理副作用,如数据获取、订阅或手动修改 DOM 等
// useRef 用于创建可变的 ref 对象,可在组件的整个生命周期内保持值
import { useEffect, useRef } from "react";
// 从 @react-three/drei 库中导入 useGLTF 和 useAnimations 钩子
// useGLTF 用于加载 GLTF 格式的 3D 模型
// useAnimations 用于管理 3D 模型的动画
import { useGLTF, useAnimations } from "@react-three/drei";// 导入飞机 3D 模型的 GLB 文件
import planeScene from "../assets/3d/plane.glb";// 3D 模型来源注释,表明模型来自 Sketchfab 网站
// 3D Model from: https://sketchfab.com/3d-models/stylized-ww1-plane-c4edeb0e410f46e8a4db320879f0a1db
/*** Plane 组件,用于渲染可控制动画的飞机 3D 模型* @param {boolean} isRotating - 控制飞机动画播放的布尔值,true 播放,false 停止* @param {Object} props - 其他传递给组件的属性* @returns {JSX.Element} 包含飞机 3D 模型的 React 元素*/
export function Plane({ isRotating, ...props }) {// 使用 useRef 钩子创建一个 ref 对象,用于引用飞机 3D 模型的 DOM 元素const ref = useRef();// 使用 useGLTF 钩子加载飞机 3D 模型和动画数据// scene 为加载后的 3D 模型场景// animations 为模型包含的动画数组const { scene, animations } = useGLTF(planeScene);// 使用 useAnimations 钩子获取动画动作对象// actions 是一个包含动画动作的对象,可用于控制动画的播放、暂停等const { actions } = useAnimations(animations, ref);// 使用 useEffect 钩子,当 isRotating 或 actions 变化时执行// 作用是根据 isRotating 的值控制飞机动画的播放或停止useEffect(() => {if (isRotating) {// 若 isRotating 为 true,播放名为 "Take 001" 的动画actions["Take 001"].play();} else {// 若 isRotating 为 false,停止名为 "Take 001" 的动画actions["Take 001"].stop();}}, [actions, isRotating]);return (// 创建一个 mesh 元素,用于承载 3D 模型// 将传递给组件的其他属性展开到 mesh 元素上// ref 关联到 ref 对象,方便后续操作模型<mesh {...props} ref={ref}>{/* 使用 primitive 元素直接嵌入从 GLTF 文件加载的复杂 3D 模型或场景object 属性指定要嵌入的 3D 对象,这里使用从 GLTF 文件加载的场景*/}<primitive object={scene} /></mesh>);
}

Home.jsx

……
// 从../models 路径导入组件,
import { Bird, Island, Sky, Plane } from "../models"
……/*** 根据屏幕尺寸调整 Plane 组件(双翼飞机)的缩放和位置。* @returns {Array} 包含飞机缩放比例和位置的数组*/const adjustBiplaneForScreenSize = () => {let screenScale, screenPosition;// If screen width is less than 768px, adjust the scale and positionif (window.innerWidth < 768) {screenScale = [1.5, 1.5, 1.5];screenPosition = [0, -1.5, 0];} else {screenScale = [3, 3, 3];screenPosition = [0, -4, -4];}return [screenScale, screenPosition];};// 调用 adjustIslandForScreenSize 函数,获取调整后的岛屿缩放、位置和旋转参数const [islandScale, islandPosition, islandRotation] = adjustIslandForScreenSize();// 定义一个状态变量 currentFocusPoint,用于存储当前的焦点点const [biplaneScale, biplanePosition] = adjustBiplaneForScreenSize();……<Bird />{/* 渲染 Plane 组件 */}{/* 渲染 Plane 组件,设置其旋转状态、位置、旋转和缩放属性 */}<PlaneisRotating={isRotating}position={biplanePosition}rotation={[0, 20.1, 0]}scale={biplaneScale}/>
……

效果图

修复部分bug,得到Home.jsx完整代码

修复后Home.jsx

// 导入 React 库和 Suspense 组件,Suspense 用于处理异步组件加载
// 当异步组件还未加载完成时,可显示一个 fallback 组件
import React, { Suspense, useState } from 'react'
// 从 @react-three/fiber 库中导入 Canvas 组件,用于创建 Three.js 渲染上下文,
// 借助该组件能在 React 应用里渲染 3D 场景
import { Canvas } from '@react-three/fiber'
// 从 ../components/Loader 路径导入 Loader 组件,该组件会在异步加载时显示加载状态
import Loader from '../components/Loader'
// 从../models 路径导入组件, 
import { Bird, Island, Sky, Plane } from "../models"// <div className='absolute top-28 left-0 right-0 z-10 flex items-center justify-center'>
//   弹出窗口
// </div>/*** Home 组件,作为应用的主页组件。* 该组件会依据屏幕尺寸对 Island 组件的缩放、位置和旋转进行调整,* 并且在 Canvas 中渲染 Island 组件,同时处理异步加载状态。* @returns {JSX.Element} 渲染后的 JSX 元素*/
const Home = () => {/*** 根据屏幕尺寸调整 Island 组件的缩放、位置和旋转。* @returns {Array} 包含屏幕缩放比例、位置和旋转值的数组*/// 定义当前阶段状态,初始值为 1const [currentStage, setCurrentStage] = useState(1);// 定义一个状态变量 isRotating,用于控制 Sky 组件和 Plane 组件的旋转状态const [isRotating, setIsRotating] = React.useState(false)/*** 根据屏幕尺寸调整 Island 组件的缩放、位置和旋转。* @returns {Array} 包含岛屿缩放比例、位置和旋转值的数组*/const adjustIslandForScreenSize = () => {// 初始化屏幕缩放比例,初始值设为 nulllet screenScale = null// 初始化 Island 组件的位置,默认值为 [0, -6.5, -43]let screenPosition = [0, -6.5, -43]// 初始化 Island 组件的旋转值,默认值为 [0.1, 4.7, 0]let rotation = [0.1, 4.7, 0]// 判断当前窗口宽度是否小于 768pxif (window.innerWidth < 768) {// 若窗口宽度小于 768px,将屏幕缩放比例设置为 [0.9, 0.9, 0.9]screenScale = [0.9, 0.9, 0.9];} else {// 若窗口宽度大于等于 768px,将屏幕缩放比例设置为 [1, 1, 1]screenScale = [1, 1, 1];}// 返回包含屏幕缩放比例、位置和旋转值的数组return [screenScale, screenPosition, rotation];}/*** 根据屏幕尺寸调整 Plane 组件(双翼飞机)的缩放和位置。* @returns {Array} 包含飞机缩放比例和位置的数组*/const adjustBiplaneForScreenSize = () => {let screenScale, screenPosition;// 如果屏幕宽度小于 768px,调整缩放和位置if (window.innerWidth < 768) {screenScale = [1.5, 1.5, 1.5];screenPosition = [0, -1.5, 0];} else {screenScale = [3, 3, 3];screenPosition = [0, -4, -4];}return [screenScale, screenPosition];};// 调用 adjustIslandForScreenSize 函数,获取调整后的岛屿缩放、位置和旋转参数const [islandScale, islandPosition, islandRotation] = adjustIslandForScreenSize();// 调用 adjustBiplaneForScreenSize 函数,获取调整后的飞机缩放和位置参数const [biplaneScale, biplanePosition] = adjustBiplaneForScreenSize();return (// 创建一个 section 元素,宽度和高度占满整个屏幕,且采用相对定位<section className='w-full h-screen relative'>{/* 创建 Three.js 渲染画布,宽度和高度占满整个屏幕,背景透明,并设置相机的近裁剪面和远裁剪面 */}<CanvasclassName='w-full h-screen bg-transparent'camera={{ near:0.1, far:1000 }}>{/* 使用 Suspense 组件处理异步加载,当 Island 组件未加载完成时,显示 Loader 组件 */}<Suspense fallback={<Loader/>}>{/* 添加定向光,为场景提供有方向的光照 */}<directionalLight/>{/* 添加环境光,为场景提供全局均匀的光照 */}<ambientLight />{/* 添加点光源,从一个点向四周发射光线 */}<pointLight />{/* 添加聚光灯,发射出类似圆锥形的光线 */}<spotLight />{/* 添加半球光,模拟天空和地面的光照效果 */}<hemisphereLight />{/* 渲染 Island 组件,传递相关状态和属性 */}<IslandisRotating={isRotating}setIsRotating={setIsRotating}setCurrentStage={setCurrentStage}position={islandPosition}rotation={[0.1, 4.7077, 0]}scale={islandScale}/>{/* 渲染 Sky 组件,设置其旋转状态 */}<Sky isRotating={isRotating} />{/* 渲染 Bird 组件 */}<Bird />{/* 渲染 Plane 组件,设置其旋转状态、位置、旋转和缩放属性 */}<PlaneisRotating={isRotating}position={biplanePosition}rotation={[0, 20.1, 0]}scale={biplaneScale}/></Suspense></Canvas></section>)
}// 导出 Home 组件,供其他文件引入使用
export default Home

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/282.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

动态规划(3)学习方法论:构建思维模型

引言 动态规划是算法领域中一个强大而优雅的解题方法,但对于许多学习者来说,它也是最难以掌握的算法范式之一。与贪心算法或分治法等直观的算法相比,动态规划往往需要更抽象的思维和更系统的学习方法。在前两篇文章中,我们介绍了动态规划的基础概念、原理以及问题建模与状…

python爬虫实战训练

前言&#xff1a;哇&#xff0c;今天终于能访问豆瓣了&#xff0c;前几天爬太多次了&#xff0c;网页都不让我访问了&#xff08;要登录&#xff09;。 先来个小练习试试手吧&#xff01; 爬取豆瓣第一页&#xff08;多页同上篇文章&#xff09;所有电影的排名、电影名称、星…

python打卡day27

函数装饰器 知识点回顾&#xff1a; 装饰器的思想&#xff1a;进一步复用函数的装饰器写法注意内部函数的返回值 日常ctrl点进某个复杂的项目&#xff0c;发现函数定义上方有一个xxx,它就是装饰器。装饰器本质上是一个 Python 函数&#xff0c;可以在不修改原函数代码的情况下&…

【python基础知识】Day 27 函数专题2:装饰器

知识点&#xff1a; 装饰器的思想&#xff1a;进一步复用函数的装饰器写法注意内部函数的返回值 装饰器教程 作业&#xff1a; 编写一个装饰器 logger&#xff0c;在函数执行前后打印日志信息&#xff08;如函数名、参数、返回值&#xff09; def logger(func):def wrapper(*ar…

15 C 语言字符类型详解:转义字符、格式化输出、字符类型本质、ASCII 码编程实战、最值宏汇总

1 字符类型概述 在 C 语言中&#xff0c;字符类型 char 用于表示单个字符&#xff0c;例如一个数字、一个字母或一个符号。 char 类型的字面量是用单引号括起来的单个字符&#xff0c;例如 A、5 或 #。 当需要表示多个字符组成的序列时&#xff0c;就涉及到了字符串。在 C 语言…

Word图片格式调整与转换工具

软件介绍 本文介绍的这款工具主要用于辅助Word文档处理。 图片排版功能 经常和Word打交道的人或许都有这样的困扰&#xff1a;插入的图片大小各异&#xff0c;排列也参差不齐。若不加以调整&#xff0c;遇到要求严格的领导&#xff0c;可能会让人颇为头疼。 而这款工具能够统…

旧 docker 版本通过 nvkind 搭建虚拟多节点 gpu 集群的坑

踩坑 参考nvkind教程安装到Setup这一步&#xff0c;由于docker版本较旧&#xff0c;–cdi.enabled 和 config 参数执行不了 手动修改 /etc/docker/daemon.json 配置文件 "features": {"cdi": true}手动修改 /etc/nvidia-container-runtime/config.toml 配…

【python基础知识】Day26 函数

一、函数的定义 函数是一段具有特定功能的、可重用的语句组&#xff0c;用函数名来表示。在需要使用函数时&#xff0c;通过函数名进行调用。函数也可以看作一段具有名字的子程序&#xff0c;可以在需要使用它的地方进行调用执行&#xff0c;不需要在每个执行的地方重复编写这些…

Linux云计算训练营笔记day08(MySQL数据库)

Linux云计算训练营笔记day08&#xff08;MySQL数据库&#xff09; 目录 Linux云计算训练营笔记day08&#xff08;MySQL数据库&#xff09;数据准备修改更新update删除delete数据类型1.整数类型2.浮点数类型(小数)3.字符类型4.日期5.枚举: 表头的值必须在列举的值里选择拷贝表复…

浪潮云边协同:赋能云计算变革的强力引擎

在数字化浪潮以排山倒海之势席卷全球的当下&#xff0c;第五届数字中国建设峰会在福州盛大开幕。这场以“创新驱动新变革&#xff0c;数字引领新格局”为主题的行业盛会&#xff0c;宛如一座汇聚智慧与力量的灯塔&#xff0c;吸引了国内外众多行业精英齐聚一堂&#xff0c;共同…

【Ubuntu】安装BitComet种子下载器

环境 Ubuntu 24.04.2 下载依赖库 环境比较新&#xff0c;此软件需要依赖很多旧的库&#xff0c;逐个安装下载&#xff1a; 1.libicu70 http://nz.archive.ubuntu.com/ubuntu/pool/main/i/icu/libicu70_70.1-2_amd64.deb2.libjavascriptcoregtk-4.0-18 http://security.ubu…

编译OpenSSL时报错,Can‘t locate IPC/Cmd.pm in @INC perl环境

Unix / Linux / macOS $ ./Configure $ make $ make test1、make Can‘t locate IPC/Cmd.pm in INC [ Downloads ] - /source/index.html https://www.openssl.org/source/ yum -y install perl-IPC-Cmd 2.make test Can’t locate Test/More.pm in INC perl环境 yum -…