当前位置: 首页 > news >正文

threejs中的小案例

背景

大家先看一下这个东西 小米su7, 是不是超级炫酷,这里博主在react中使用threejs做了一个半成品,可以先观赏一下

threejs的小案例,汽车动画

技术栈

  • react@18.*
  • three@0.169.0
  • sass@1.77.*
  • typescript@5.*

先导片:

在我的react项目中对threejs的初次使用

实现功能

demo/index.tsx: 组件的所有代码

import React, { useRef, useState } from "react";
import * as THREE from "three";import Stats from "three/addons/libs/stats.module.js";import { OrbitControls } from "three/addons/controls/OrbitControls.js";import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
import { DRACOLoader } from "three/addons/loaders/DRACOLoader.js";
import { RGBELoader } from "three/addons/loaders/RGBELoader.js";
import { useMount } from "hooks/useMount";
import "./index.scss";export default function seventhUseThreejs() {const [bodyColor, setBodyColor] = useState<string>("#ff0000");const [detailColor, setDetailColor] = useState<string>("#ffffff");const [glassColor, setGlassColor] = useState<string>("#ffffff");const cameraRef = useRef<any>(null);const rendererRef = useRef<any>(null);const sceneRef = useRef<any>(null);const gridRef = useRef<any>(null);const wheelsRef = useRef<any[]>([]);const statsRef = useRef<any>(null);const controlsRef = useRef<any>(null);useMount(() => {init();});function init() {const container = document.getElementById("three_demo7") as HTMLElement;rendererRef.current = new THREE.WebGLRenderer({ antialias: true });const renderer = rendererRef.current;renderer.setPixelRatio(window.devicePixelRatio);renderer.setSize(window.innerWidth, window.innerHeight);renderer.setAnimationLoop(animate);renderer.toneMapping = THREE.ACESFilmicToneMapping;renderer.toneMappingExposure = 0.85;container.appendChild(renderer.domElement);window.addEventListener("resize", onWindowResize);statsRef.current = new Stats();container.appendChild(statsRef.current.dom);//cameraRef.current = new THREE.PerspectiveCamera(40,window.innerWidth / window.innerHeight,0.1,100,);cameraRef.current.position.set(4.25, 1.4, -4.5);controlsRef.current = new OrbitControls(cameraRef.current, container);const controls = controlsRef.current;controls.maxDistance = 9;controls.maxPolarAngle = THREE.MathUtils.degToRad(90);controls.target.set(0, 0.5, 0);controls.update();sceneRef.current = new THREE.Scene();const scene = sceneRef.current;scene.background = new THREE.Color(0x333333);scene.environment = new RGBELoader().load("textures/venice_sunset_1k.hdr");scene.environment.mapping = THREE.EquirectangularReflectionMapping;scene.fog = new THREE.Fog(0x333333, 10, 15);gridRef.current = new THREE.GridHelper(20, 40, 0xffffff, 0xffffff);const grid = gridRef.current;grid.material.opacity = 0.2;grid.material.depthWrite = false;grid.material.transparent = true;scene.add(grid);// materialsconst bodyMaterial = new THREE.MeshPhysicalMaterial({color: 0xff0000,metalness: 1.0,roughness: 0.5,clearcoat: 1.0,clearcoatRoughness: 0.03,});const detailsMaterial = new THREE.MeshStandardMaterial({color: 0xffffff,metalness: 1.0,roughness: 0.5,});const glassMaterial = new THREE.MeshPhysicalMaterial({color: 0xffffff,metalness: 0.25,roughness: 0,transmission: 1.0,});const bodyColorInput = document.getElementById("body-color",) as HTMLInputElement;bodyColorInput.addEventListener("input", function () {bodyMaterial.color.set(this.value);});const detailsColorInput = document.getElementById("details-color",) as HTMLInputElement;detailsColorInput.addEventListener("input", function () {detailsMaterial.color.set(this.value);});const glassColorInput = document.getElementById("glass-color",) as HTMLInputElement;glassColorInput.addEventListener("input", function () {glassMaterial.color.set(this.value);});// Carconst shadow = new THREE.TextureLoader().load("models/ferrari_ao.png");const dracoLoader = new DRACOLoader();dracoLoader.setDecoderPath("draco/gltf/");const loader = new GLTFLoader();loader.setDRACOLoader(dracoLoader);loader.load("models/ferrari.glb", function (gltf: any) {const carModel = gltf.scene.children[0];carModel.getObjectByName("body").material = bodyMaterial;carModel.getObjectByName("rim_fl").material = detailsMaterial;carModel.getObjectByName("rim_fr").material = detailsMaterial;carModel.getObjectByName("rim_rr").material = detailsMaterial;carModel.getObjectByName("rim_rl").material = detailsMaterial;carModel.getObjectByName("trim").material = detailsMaterial;carModel.getObjectByName("glass").material = glassMaterial;wheelsRef.current.push(carModel.getObjectByName("wheel_fl"),carModel.getObjectByName("wheel_fr"),carModel.getObjectByName("wheel_rl"),carModel.getObjectByName("wheel_rr"),);// shadowconst mesh = new THREE.Mesh(new THREE.PlaneGeometry(0.655 * 4, 1.3 * 4),new THREE.MeshBasicMaterial({map: shadow,blending: THREE.MultiplyBlending,toneMapped: false,transparent: true,}),);mesh.rotation.x = -Math.PI / 2;mesh.renderOrder = 2;carModel.add(mesh);scene.add(carModel);});}function onWindowResize() {const camera = cameraRef.current;camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();rendererRef.current.setSize(window.innerWidth, window.innerHeight);}function animate() {controlsRef.current.update();const time = -performance.now() / 1000;for (let i = 0; i < wheelsRef.current.length; i++) {wheelsRef.current[i].rotation.x = time * Math.PI * 2;}gridRef.current.position.z = -time % 1;rendererRef.current.render(sceneRef.current, cameraRef.current);statsRef.current.update();}const handleChange = (e: any) => {console.log(e);setBodyColor(e.target.value);};return (<><div id="three_demo7"></div><div className="colorPickerContainer"><span className="colorPicker"><inputid="body-color"type="color"value={bodyColor}onChange={handleChange}></input>车身颜色</span><span className="colorPicker"><inputid="details-color"type="color"value={detailColor}onChange={e => setDetailColor(e.target.value)}></input>轮毂颜色</span><span className="colorPicker"><inputid="glass-color"type="color"value={glassColor}onChange={e => setGlassColor(e.target.value)}></input>玻璃颜色</span></div></>);
}

demo/index.scss

#three_demo7 {div {top: 45px !important;}
}
.colorPickerContainer {position: absolute;top: 60px;left: 50%;transform: translateX(-50%);color: #fff;display: flex;gap: 20px;.colorPicker {display: flex;gap: 8px;}
}

代码中所用的资源

  1. 必须放到项目启动的根目录,比如:博主使用的create-react-app脚手架搭建的项目,public目录在打包后会原封不动的放到根目录;
  2. 资源:
    • 点这里下载

写在最后

欢迎感兴趣的一起研究和探讨!


http://www.mrgr.cn/news/57471.html

相关文章:

  • autMan奥特曼机器人-出现argument list too long报错的解决方法
  • 哈希——哈希的基本概念
  • 两个开源AI应用让Claude 3.5 直接操作你的电脑;构建和部署多智能体系统课程;简化PDF文档管理并提供智能聊天功能
  • 通过运行窗口呼出Windows功能的快捷命令集合
  • Swarm集群管理常用命令与详解
  • 在 Spring 框架中,@ComponentScan` 扫描的注解类型
  • Bros!使用 focus 和 blur 事件时别忽略了这一点!
  • CentOS 6 修改 yun 源
  • 【Linux】 su 和 sudo 的区别剖析
  • C#,自动驾驶技术,ASAM OpenDRIVE BS 1.8.0 规范摘要与C# .NET Parser
  • 农业自动气象监测站的工作原理
  • 深入解析MySQL数据库:从基础到进阶的全面剖析
  • 哥德巴赫猜想渐行渐远
  • 《1024:致敬程序员的数字乐章》
  • Mitre ATTCK攻击技术-权限维持-定时任务
  • Flutter鸿蒙next 刷新机制的高级使用【衍生详解】
  • 【.Net】【C#】Program.cs通用代码模板
  • 企业办公文件加密软件推荐!10款企业常用文件加密软件排行榜!
  • Clickhouse 笔记(一) 单机版安装并将clickhouse-server定义成服务
  • angular-electron调用java