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

three.js(四):react + three.js

绘制多个立方体

1.搭建react+ts 项目

npx create-react-app basics-demo --template typescript
  • react+ts 的用法可参考此链接: https://react-typescript-cheatsheet.netlify.app/docs/basic/setup

2.安装three依赖

npm install three @types/three --save

3.安装路由

npm install react-router@6 react-router-dom@6
  • react-router-v6 的用法可参考此链接:https://juejin.cn/post/7088526716049555492

4.用路由组件包裹APP。

  • index.tsx
import { BrowserRouter } from "react-router-dom";
import { createRoot } from "react-dom/client";
import App from "./App";const container = document.getElementById("root") as HTMLElement;
const root = createRoot(container);
root.render(<BrowserRouter><App /></BrowserRouter>
);

5.构建项目页面

  • src/view/Basics.tsx
import React from "react";const Basics: React.FC = (): JSX.Element => {return (<nav style={{ width: "60%", margin: "auto" }}><h2>three.js 基础示例</h2></nav>);
};export default Basics;
  • src/view/RenderStructure.tsx
import React from "react";const RenderStructure: React.FC = (): JSX.Element => {return <div>RenderStructure 渲染结构</div>;
};export default RenderStructure;

6.用useRoutes hook 搭建路由。

  • App.tsx
import React from "react";
import { useRoutes } from "react-router-dom";
import "./App.css";
import Basics from "./view/Basics";
import RenderStructure from "./view/RenderStructure";const App: React.FC = (): JSX.Element => {const routing = useRoutes([{path: "/",element: <Basics />,},{path: "RenderStructure",element: <RenderStructure />,]);return <>{routing}</>;
};export default App;

7.建立导航栏

  • src/view/Basics.tsx
import React from "react";
import { Link } from "react-router-dom";const Basics: React.FC = (): JSX.Element => {return (<nav style={{ width: "60%", margin: "auto" }}><h2>three.js 基础示例</h2><ul><li><Link to="/RenderStructure">RenderStructure 渲染结构</Link></li></ul></nav>);
};
export default Basics;

8.在RenderStructure.tsx 页面导入立方体

  • src/view/RenderStructure.tsx
import React, { useRef, useEffect } from "react";
import { BoxGeometry, DirectionalLight, Mesh, MeshNormalMaterial, MeshPhongMaterial, PerspectiveCamera, Scene, WebGLRenderer } from "three";const { innerWidth, innerHeight } = window;const scene = new Scene();
const camera = new PerspectiveCamera(75, innerWidth / innerHeight, 0.1, 1000);
camera.position.z = 5;const renderer = new WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);const geometry = new BoxGeometry();
const material = new MeshNormalMaterial();
const cube = new Mesh(geometry, material);
scene.add(cube);function animate() {requestAnimationFrame(animate);cube.rotation.x += 0.01;cube.rotation.y += 0.01;renderer.render(scene, camera);
}const RenderStructure: React.FC = (): JSX.Element => {const divRef = useRef<HTMLDivElement>(null);useEffect(() => {const { current } = divRef;if (current) {current.innerHTML = "";current.append(renderer.domElement);animate();}}, []);return <div ref={divRef}></div>;
};export default RenderStructure;
  • 在上面的代码中,没有直接建立 ,而是在WebGLRenderer 对象的实例化方法里建立的,在其源码可以找到相关逻辑:
function WebGLRenderer( parameters = {} ) {const _canvas = parameters.canvas !== undefined ? parameters.canvas : createCanvasElement()……this.domElement = _canvas;……
}
  • 通过WebGLRenderer 对象建立了canvas后,再在react的函数组件的useEffect hook 中,将canvas 添加到div 中。
const RenderStructure: React.FC = (): JSX.Element => {const divRef = useRef<HTMLDivElement>(null);useEffect(() => {const { current } = divRef;current && current.append(renderer.domElement);animate();}, []);return <div ref={divRef}></div>;
};
  • 当前这个立方体的材质是MeshNormalMaterial,并不受光照影响

9.给立方体换个MeshPhongMaterial 材质,再添加光源

const geometry = new BoxGeometry();
const material = new MeshPhongMaterial({ color: 0x44aa88 });
const cube = new Mesh(geometry, material);
scene.add(cube);const color = 0xffffff;
const intensity = 1;
const light = new DirectionalLight(color, intensity);
light.position.set(-1, 2, 4);
scene.add(light);
  • 当前的渲染结构如下:
    在这里插入图片描述
  • 效果如下:
    在这里插入图片描述

10. 添加两个立方体,几何体和材质可被多个Mesh 对象共享

const geometry = new BoxGeometry();
const material = new MeshPhongMaterial({ color: 0x44aa88 });const cubes = [-2, 0, 2].map((num) => makeInstance(num));
scene.add(...cubes);function makeInstance(x: number) {const cube = new Mesh(geometry, material);cube.position.x = x;return cube;
}function animate() {requestAnimationFrame(animate);cubes.forEach((cube) => {cube.rotation.x += 0.01;cube.rotation.y += 0.01;});renderer.render(scene, camera);
}
  • 当前的渲染结构如下:
    在这里插入图片描述
  • 效果如下:
    在这里插入图片描述

相关文章:

three.js(四):react + three.js

绘制多个立方体 1.搭建reactts 项目 npx create-react-app basics-demo --template typescriptreactts 的用法可参考此链接&#xff1a; https://react-typescript-cheatsheet.netlify.app/docs/basic/setup 2.安装three依赖 npm install three types/three --save3.安装路…...

IDEA全局统一设置Maven

原来每次打开新建的项目都需要经过 File-> Settings 重新配置maven&#xff0c;这样很不爽 然而经过 File-> New Projects Setup -> Settings for New Projects 后&#xff0c;再如上图配置后就全局设置好了...

CSS中的margin与padding

目录 一、margin 1.概念及作用 2.基本语法 3.margin的用法 二、padding 1.介绍 2.基本语法及要求 3. 用法 4.内边距和元素宽度 讲这些之前&#xff0c;先看一张图&#xff0c;便于理解 一、margin 1.概念及作用 CSS margin 属性用于在任何定义的边框之外&#xff0c;…...

匿名内部类、Lambda、方法引用 的总结

在今天的项目中看到这样一行代码 Integer syncCount consumer.consumerInfo( Collections.singletonList(KafkaTopicConst.Event_BMS_SYSLOG_ROLE),consumer::handle); 直接傻眼&#xff0c;无法理解consumer::handle这种用法&#xff0c;因此总结如下 consumer::handle这种写…...

本地docker registry 搭建

#!/bin/bash DOCKER_REGISTRY_ROOT/data0/docker/registry DOMAINexample.host.com #生成证书&#xff1a;https://goharbor.io/docs/2.6.0/install-config/configure-https/ mkdir $DOCKER_REGISTRY_ROOT/certs cd $DOCKER_REGISTRY_ROOT/certs openssl genrsa -out ca.key 40…...

阿里云将关停代销业务

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 阿里云自从逐渐分拆独立之后&#xff0c;做了很多调整。最近它又做了一个大动作&#xff1a;据DoNews消息&#xff0c;阿里云将会在今年9月30日之前&#xff0c;全面关停代销业务。 这件事实际上…...

【ES6】JavaScript的Proxy:理解并实现高级代理功能

在JavaScript中&#xff0c;Proxy是一种能够拦截对对象的读取、设置等操作的机制。它们提供了一种方式&#xff0c;可以在执行基本操作之前或之后&#xff0c;对这些操作进行自定义处理。这种功能在许多高级编程场景中非常有用&#xff0c;比如实现数据验证、日志记录、权限控制…...

[Pandas] 求百分比并添加百分(%)号

导入数据 import pandas as pddf pd.DataFrame(data{orders: [2130,5102,3256,1297,1918,786],repeat_orders: [73,158,89,30,49,18]}) df df[repetition_rate] df[repeat_orders] / df[orders] df df[repetition_rate] df[repetition_rate].apply(lambda x: format(x, .2…...

《算法竞赛·快冲300题》每日一题:“凑二十四”

《算法竞赛快冲300题》将于2024年出版&#xff0c;是《算法竞赛》的辅助练习册。 所有题目放在自建的OJ New Online Judge。 用C/C、Java、Python三种语言给出代码&#xff0c;以中低档题为主&#xff0c;适合入门、进阶。 文章目录 题目描述题解C代码Java代码Python代码 “ 凑…...

git reset --hard HEAD

git reset --hard HEAD 是用于将你的工作目录重置回最后一次提交状态的命令。- git reset 是 git 的一个命令&#xff0c;用于重置你当前的 HEAD 到指定的状态。 --hard 标志告诉 git 要完全重置工作目录和暂存区&#xff0c;去匹配最后一次提交。在这个过程中&#xff0c;所有…...

机器人编程怎么入门?

机器人已经在我们中间存在了二三十年。如今&#xff0c;机器人在我们的文化中比以往任何时候都更加根深蒂固。大多数机器人机器用于各种装配线&#xff0c;或在世界各地的矿山或工业设施中执行密集的物理操作。 还有一些家用机器人&#xff0c;工程师正在对机器人进行编程&…...

广州华锐互动:VR垃圾分类虚拟科普系统让学习过程更加丰富有趣

在我们的日常生活中&#xff0c;垃圾分类已成为一项重要的公民责任。然而&#xff0c;由于缺乏对垃圾分类的深入理解和相关知识&#xff0c;许多人在实践中往往感到困惑和挫败。为了解决这个问题&#xff0c;一种创新的解决方案应运而生&#xff1a;垃圾分类VR虚拟仿真教学系统…...

手机盖板IR油墨透光率检测仪T03

手机盖板作为手机最外层玻璃面板&#xff0c;其加工一般有落料、倒边、抛光、镀膜、丝印等多道加工工序组成&#xff0c;其中任何一个工序出现差错&#xff0c;都有可能导致手机盖板产生缺陷&#xff0c;例如漏油、透光、IR孔不良、视窗划伤、油墨区划伤、內污、边花等&#xf…...

ChatGPT⼊门到精通(6):ChatGPT 提问设计

前⾔ 学会提问就是为了让AI给出⾼质量的答案。 你所学到的技能⼀切为了⽣成⾼质量的答案。 本教程适合&#xff1a;普通ChatGPT的⽤户、专业prompt⼯程师 你将收获&#xff1a;prompt 技巧的全⾯指导 、prompt⼯程师必备技能、prompt技术⼯程⾼质量答 案完全指南 提⽰词 Prom…...

如何使用 Tailwind CSS 设计高级自定义动画

使用Tailwind CSS掌握动画技术&#xff0c;为用户带来难忘的体验 开篇 动画已经成为网页设计的重要组成部分&#xff0c;使开发人员能够创建引人入胜和互动的用户体验。 Tailwind CSS&#xff0c;一款流行的实用型CSS框架&#xff0c;提供了一套强大的工具&#xff0c;可以轻松…...

【C语言】循环语句详解

✨个人主页&#xff1a; Anmia.&#x1f389;所属专栏&#xff1a; C Language &#x1f383;操作环境&#xff1a; Visual Studio 2019 版本 目录 1.什么是循环结构&#xff1f; 2.while循环 while流程图 while语句中的break和continue break continue 3.for循环 for流…...

SpringBoot项目配置文件数据库用户名密码加密

1、需求 在使用SpringBoot开发过程中&#xff0c;会将一些敏感信息配置到SpringBoot项目的配置文件中(不考虑使用配置中心的情况 )&#xff0c;例如数据库的用户名和密码、Redis的密码等。为了保证敏感信息的安全&#xff0c;我们需要将此类数据进行加密配置。 2、操作步骤 …...

5个IT事件管理的最佳实践

什么是IT事件&#xff1f; IT事件是一个影响很大的紧急问题&#xff0c;通常会影响整个组织或其主要部分。重大事件几乎总是导致组织的服务变得不可用&#xff0c;这导致组织的业务受到打击&#xff0c;并最终影响其财务状况。以下是5个重大IT事件管理的最佳实践&#xff1a; …...

双核和双路服务器的区别

服务器术语里&#xff0c;大家经常会听到1U、2U&#xff0c;单路、双路&#xff0c;机架式、塔式及刀片式等常用名词。其中&#xff0c;机架式、塔式及刀片式是 指服务器的外形&#xff0c;U是指服务器的高度&#xff0c;路是指服务器的处理器数量。 部分朋友会问&#xff0c;我…...

学习JAVA打卡第四十七天

日期的格式化 程序可能希望按照某种习惯来输出时间。例如时间的顺序&#xff1a;年/月/日或年/月/日/时/分/秒。可以直接使用String类调用format方法对日期进行格式化。 Format方法 Format方法&#xff1a; format&#xff08;格式化模式,日期列表&#xff09; 按照“格式…...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

centos 7 部署awstats 网站访问检测

一、基础环境准备&#xff08;两种安装方式都要做&#xff09; bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

腾讯云V3签名

想要接入腾讯云的Api&#xff0c;必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口&#xff0c;但总是卡在签名这一步&#xff0c;最后放弃选择SDK&#xff0c;这次终于自己代码实现。 可能腾讯云翻新了接口文档&#xff0c;现在阅读起来&#xff0c;清晰了很多&…...