three.js 细一万倍教程 从入门到精通(一)
目录
一、three.js开发环境搭建
1.1、使用parcel搭建开发环境
1.2、使用three.js渲染第一个场景和物体
1.3、轨道控制器查看物体
二、three.js辅助设置
2.1、添加坐标轴辅助器
2.2、设置物体移动
2.3、物体的缩放与旋转
缩放
旋转
2.4、应用requestAnimationFrame
2.5、通过Clock跟踪时间处理动画
2.6、Gsap动画库基本使用与原理
2.7、Gsap控制动画属性与方法
2.8、根据尺寸变化实现自适应画面
阻尼效果
自适应画面
2.9、调用js接口控制画布全屏和退出全屏
2.10、应用图形用户界面更改变量
一、three.js开发环境搭建
1.1、使用parcel搭建开发环境
第一步:创建空项目

第二步:终端输入
npm init
直接一路回车。

第三步:安装parcel
npm install parcel-bundler
接着,通过修改你的package.json来添加这些任务脚本
"scripts": {"dev": "parcel src/index.html","build": "parcel build src/index.html"
},
第四步:创建src/index.html

第五步:终端输入命令
npm install parcel-bundler -dev
第六步:创建静态文件,引入静态文件

第七步:编写style.css代码
* {margin: 0;padding: 0;
}body {background-color: skyblue;
}
第八步:安装threejs依赖
npm install three --save
第九步:编写main.js代码,看threejs是否安装成功
import * as THREE from "three"console.log(THREE);
第十步:启动项目

1.2、使用three.js渲染第一个场景和物体
import * as THREE from "three"// 1、创建场景
const scene = new THREE.Scene()// 2、创建相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);// 3、设置相机位置
camera.position.set(0, 0, 10);
scene.add(camera)// 添加物体
// 创建几何体
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
// 材质
const cubeMaterial = new THREE.MeshBasicMaterial({color: 0xffff00});
// 根据几何体和材质创建物体
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
// 将物体添加到场景中
scene.add(cube)// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);// 使用渲染器,通过相机将场景渲染进来
renderer.render(scene, camera);

1.3、轨道控制器查看物体
import * as THREE from "three"
// 导入轨道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'// 1、创建场景
const scene = new THREE.Scene()// 2、创建相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);// 3、设置相机位置
camera.position.set(0, 0, 10);
scene.add(camera)// 添加物体
// 创建几何体
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
// 材质
const cubeMaterial = new THREE.MeshBasicMaterial({color: 0xffff00});
// 根据几何体和材质创建物体
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
// 将物体添加到场景中
scene.add(cube)// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);// 使用渲染器,通过相机将场景渲染进来
// renderer.render(scene, camera);// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);function render() {renderer.render(scene, camera);// 渲染下一帧的时候就会调用render函数requestAnimationFrame(render)
}render();

可以拖动了。
二、three.js辅助设置
2.1、添加坐标轴辅助器
// 添加坐标轴辅助器 5代表轴的线段长度
const axesHelper = new THREE.AxesHelper(5)
scene.add(axesHelper)

红色代表X轴,绿色代表Y轴,蓝色代表Z轴。
2.2、设置物体移动
// 修改物体的位置
// 参数分别为 x,y,z
cube.position.set(5, 2, 0)
当然你也可以使用直接点的形式:
cube.position.x = 5
cube.position.y = 2

小案例:模拟物体从左到右循环运动
function render() {cube.position.x += 0.01if (cube.position.x > 5) {cube.position.x = 0}renderer.render(scene, camera);// 渲染下一帧的时候就会调用render函数requestAnimationFrame(render)
}
2.3、物体的缩放与旋转
缩放
// 缩放
// 参数 x轴是3倍,y轴是两倍
cube.scale.set(3, 2, 1)

旋转
//旋转
// 参数都为弧度,Math.PI / 4代表绕X轴旋转45度
cube.rotation.set(Math.PI / 4, 0, 0)

小案例:模拟物体从左到右循环运动,并按X轴旋转
function render() {cube.position.x += 0.01cube.rotation.x += 0.01if (cube.position.x > 5) {cube.position.x = 0}renderer.render(scene, camera);// 渲染下一帧的时候就会调用render函数requestAnimationFrame(render)
}

2.4、应用requestAnimationFrame
首先,我们的render函数有个默认的参数time,代表每一帧的时间,如果你打印会发现每一帧的时间都不太匀速,比如我们上面这个案例,x轴长度为5,假如我打算1秒运动长度1,匀速就是5秒完成,但打印结果并不是匀速的。

// 匀速
function render(time) {let t = time / 1000 % 5;cube.position.x = t * 1if (cube.position.x > 5) {cube.position.x = 0}renderer.render(scene, camera);// 渲染下一帧的时候就会调用render函数requestAnimationFrame(render)
}
2.5、通过Clock跟踪时间处理动画
// 设置时钟
const clock = new THREE.Clock();function render() {// 获取时钟运行的总时长let time = clock.getElapsedTime();console.log("时钟运行总时长:", time);let deltaTime = clock.getDelta();console.log("两次获取时间的间隔时间:", deltaTime)let t = time % 5;cube.position.x = t * 1if (cube.position.x > 5) {cube.position.x = 0}renderer.render(scene, camera);// 渲染下一帧的时候就会调用render函数requestAnimationFrame(render)
}
2.6、Gsap动画库基本使用与原理
npm install gsap
动画库的作用就解决了我们上面手动计算处理动画的问题。
// 设置动画
// x轴上移动到5的位置,所花费时间5秒
gsap.to(cube.position, {x: 5, duration: 5, ease: "power1.out"})
// 绕x轴上旋转到360度,所花费时间5秒
gsap.to(cube.rotation, {x: 2 * Math.PI, duration: 5})function render() {renderer.render(scene, camera);// 渲染下一帧的时候就会调用render函数requestAnimationFrame(render)
}
ease属性(速率):
power1.out:起始阶段平滑地加速,然后以逐渐减速的方式结束。
power1.in:起始阶段缓慢加速,然后以较快的速度向目标值靠近。
power1.inOut:在动画开始和结束时,属性的变化速度较慢,然后在动画的中间阶段达到最快的变化速度。
2.7、Gsap控制动画属性与方法
// 设置动画
// x轴上移动到5的位置,所花费时间5秒
let animate1 = gsap.to(cube.position, {x: 5,duration: 5,ease: "power1.inOut",repeat: -1, // 设置重复的次数,无限次循环-1yoyo: true, // 往返运动delay: 2, // 延迟2秒运动onStart: () => {console.log("动画开始")},onComplete: () => {console.log("动画完成")}
})
// 绕x轴上旋转到360度,所花费时间5秒
gsap.to(cube.rotation, {x: 2 * Math.PI, duration: 5})// 点击动画,暂停或恢复
window.addEventListener("click", () => {if(animate1.isActive()) {animate1.pause(); // 暂停} else {animate1.resume(); // 恢复运动}
})

2.8、根据尺寸变化实现自适应画面
阻尼效果
// 设置控制器阻尼,让控制器更有真实效果,必须在动画循环里调用update()
controls.enableDamping = true;function render() {controls.update();renderer.render(scene, camera);// 渲染下一帧的时候就会调用render函数requestAnimationFrame(render)
}
自适应画面
// 监听画面变化,更新渲染画面
window.addEventListener("resize", () => {// 更新摄像头camera.aspect = window.innerWidth / window.innerHeight;// 更新摄像机的投影矩阵camera.updateProjectMatrix();// 在更新渲染器renderer.setSize(window.innerWidth, window.innerHeight)// 设置渲染器的像素比renderer.setPixelRatio(window.devicePixelRatio);
})
尽管你更改分辨率,这段代码都会保持画面原样。
2.9、调用js接口控制画布全屏和退出全屏
// 双击控制屏幕进入全屏,退出全屏
window.addEventListener("dblclick", () => {const fullScreenElement = document.fullscreenElement; // 页面是否处于全屏if (!fullScreenElement){renderer.domElement.requestFullscreen(); // 全屏} else {document.exitFullscreen(); // 退出全屏}
})
2.10、应用图形用户界面更改变量
很多时候我们调试3D图像很麻烦,普遍都是改完代码然后看页面效果,而dat.gui就大大简化了我们的操作问题。
npm install -save dat.gui
// 导入dat.gui
import * as dat from 'dat.gui'const gui = new dat.GUI();
gui.add(cube.position, "x").min(0).max(5).name("移动X轴坐标").onChange((value) => {console.log("值被修改:", value)
}).onFinishChange((value) => {console.log("完全停下来触发:", value)
})

相关文章:
three.js 细一万倍教程 从入门到精通(一)
目录 一、three.js开发环境搭建 1.1、使用parcel搭建开发环境 1.2、使用three.js渲染第一个场景和物体 1.3、轨道控制器查看物体 二、three.js辅助设置 2.1、添加坐标轴辅助器 2.2、设置物体移动 2.3、物体的缩放与旋转 缩放 旋转 2.4、应用requestAnimationFrame …...
电路设计(16)——纪念馆游客进出自动计数显示器proteus仿真
1.设计要求 设计、制作一个纪念馆游客进出自动计数显示器。 某县,有一个免费参观的“陶渊明故里纪念馆”,游客进出分道而行,如同地铁有确保单向通行的措施。在入口与出口处分别设有红外检测、声响、累加计数器装置,当游人进&#…...
Python数学建模之回归分析
1.基本概念及应用场景 回归分析是一种预测性的建模技术,数学建模中常用回归分析技术寻找存在相关关系的变量间的数学表达式,并进行统计推断。例如,司机的鲁莽驾驶与交通事故的数量之间的关系就可以用回归分析研究。回归分析根据变量的…...
单片机学习笔记---DS18B20温度传感器
目录 DS18B20介绍 模拟温度传感器的基本结构 数字温度传感器的应用 引脚及应用电路 DS18B20的原理图 DS18B20内部结构框图 暂存器内部 单总线介绍 单总线电路规范 单总线时序结构 初始化 发送一位 发送一个字节 接收一位 接收一个字节 DS18B20操作流程 指令介…...
【网络】WireShark过滤 | WireShark实现TCP三次握手和四次挥手
目录 一、开启WireShark的大门 1.1 WireShark简介 1.2 常用的Wireshark过滤方式 二、如何抓包搜索关键字 2.1 协议过滤 2.2 IP过滤 编辑 2.3 过滤端口 2.4 过滤MAC地址 2.5 过滤包长度 2.6 HTTP模式过滤 三、ARP协议分析 四、WireShark之ICMP协议 五、TCP三次握…...
开源免费的Linux服务器管理面板分享
开源免费的Linux服务器管理面板分享 一、1Panel1.1 1Panel 简介1.2 1Panel特点1.3 1Panel面板首页1.4 1Panel使用体验 二、webmin2.1 webmin简介2.2 webmin特点2.3 webmin首页2.4 webmin使用体验 三、Cockpit3.1 Cockpit简介3.2 Cockpit特点3.3 Cockpit首页3.4 Cockpit使用体验…...
leetcode算法-位运算
位运算,直接在二进制上进行的按位操作,位运算的种类如下: 1.按位异或^:异或的含义是操作的两位不同,则结果为1,相同则结果为0,所以两个相同的数异或,结果应该是0,3^3的结果是0,3^4的…...
「MySQL」约束
概述 分类 约束描述关键字非空约束限制该字段的数据不能为 nullNOT NULL唯一约束保证该字段的所有数据都是唯一、不重复的UNIQUE主键约束主键是一行数据的唯一标识,要求非空且唯一PRIMARY KEY默认约束保存数据时,如果未指定该字段的值,则采…...
C语言:详解操作符(下)
上一篇链接:C语言:详解操作符(上)摘要: 在上篇文章中,我们已经讲过位操作符等涉及二进制的操作符,这些有助于帮助我们后期理解数据如何在计算机中运算并存储,接下来本篇将更多的讲述…...
Vue3.0(六):VueX 4.x详解
Vuex4状态管理 什么是状态管理 在开发中,我们的应用程序需要处理各种各样的数据,这些数据需要保存在应用程序的某一个位置,对于这些数据的管理,就是 状态管理目前前端项目越来越复杂,多组件共享同一数据的状态很常见…...
突破编程_C++_面试(基础知识(13))
面试题45:C中的字符串如何存储 在C中,字符串可以通过多种方式存储,但最常见和推荐使用的方式是通过 std::string 类,该类位于 <string> 头文件中。std::string 是一个类模板的实例,通常用于存储字符数组&#x…...
掌握C语言文件操作:从入门到精通的完整指南!
✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:C语言学习 贝蒂的主页:Betty‘s blog 1. 什么是文件 文件其实是指一组相关数据的有序集合。这个数据集有一个名称&a…...
JavaEE作业-实验二
目录 1 实验内容 2 实验要求 3 思路 4 核心代码 5 实验结果 1 实验内容 实现两个整数求和的WEB程序 2 实验要求 ①采用SpringMVC框架实现 ②数据传送到WEB界面采用JSON方式 3 思路 ①创建一个SpringMVC项目,配置好相关的依赖和配置文件。 ②创建一个Con…...
2月8号作业
Sqlite3系统命令 .quit 退出数据库 .exit 退出数据库 .help 显示帮助信息,获取所有系统命令 .table 查看当前数据库下的所有表格 .schema 查看表的结构 Sqlite3语句 创建表格: create table 表名 (字段名 数据类型, 字段名 数据类型); create table if…...
08:K8S资源对象管理|服务与负载均衡|Ingress
K8S资源对象管理|服务与负载均衡|Ingress DaemonSet控制器污点策略容忍容忍污点 其他资源对象Job资源对象 有限生命周期CronJob资源对象 集群服务服务自动发现headless服务 实现服务定位与查找 服务类型 Ingress插件 发布服务的方式 DaemonSet控制器 Da…...
HarmonyOS 横屏调试与真机横屏运行
我们有些程序 需要横屏才能执行出效果 我们在预览器上 点击如下图指向出 就进入一个横屏调试了 但 我们真机运行 依旧是竖着的 我们如下图 找到 module.json5 在 abilities 下面 第一个对象 最下面 加上 "orientation": "landscape"然后 我们再真机运…...
Javaweb基础-tomcat,servlet
一.配置文件基础: properties配置文件: 由键值对组成 键和值之间的符号是等号 每一行都必须顶格写,前面不能有空格之类的其他符号 xml配置文件:(xml语法HTML语法HTML约束)xml约束-DTD / Schema DOM4…...
HCIA-HarmonyOS设备开发认证V2.0-3.2.轻量系统内核基础-中断管理
目录 一、中断基础概念二、中断管理使用说明三、中断管理模块接口四、代码分析(待续...)坚持就有收获 一、中断基础概念 在程序运行过程中,出现需要由 CPU 立即处理的事务时,CPU 暂时中止当前程序的执行转而处理这个事务…...
【开源】JAVA+Vue+SpringBoot实现就医保险管理系统
目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 科室档案模块2.2 医生档案模块2.3 预约挂号模块2.4 我的挂号模块 三、系统展示四、核心代码4.1 用户查询全部医生4.2 新增医生4.3 查询科室4.4 新增号源4.5 预约号源 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVue…...
Stable Diffusion 模型下载:DreamShaper XL(梦想塑造者 XL)
本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十 下载地址 模型介绍 DreamShaper 是一个分格多样的大模型,可以生成写实、原画、2.5D 等…...
别再只怪MOS管了!BMS过压保护设计,PCB走线才是隐藏的‘刺客’
别再只怪MOS管了!BMS过压保护设计,PCB走线才是隐藏的‘刺客’ 在电池管理系统(BMS)的设计中,过压保护失效往往被简单归咎于MOS管的选型或钳位二极管的设计。然而,一个真实的案例揭示了更深层的问题…...
AI嵌入式系统测试:融合经典方法与数据驱动验证的工程实践
1. 项目概述:当嵌入式遇见AI,测试的“变”与“不变”干了十几年嵌入式,从8位单片机玩到多核异构处理器,从裸机编程干到复杂的RTOS,我原以为测试这件事,左不过就是单元测试、集成测试、系统测试那几板斧&…...
不只是YOLOv5!详解Windows‘页面文件太小’错误的通用解决思路与内存优化技巧
不只是YOLOv5!详解Windows‘页面文件太小’错误的通用解决思路与内存优化技巧 当你在深夜赶工一个重要的机器学习项目,或是渲染一段4K视频时,突然弹出一个冰冷的错误提示:"页面文件太小,无法完成操作"。这一…...
LangGraph 是什么?为什么它越来越像 AI Agent 时代的“操作系统”
文章目录一、为什么普通的“聊天式 AI”不够用了?1. 状态容易丢2. 流程难控制3. 执行失败后很难恢复4. 决策过程不透明二、LangGraph 到底是什么?1. 编排2. 运行时三、为什么很多人会说:LangGraph 像 Agent Server 的“操作系统”?…...
实验室御用MedPeer科研绘图工具实测
我之前总觉得科研绘图是“科研人的附加技能”——不会用AI就得啃PS,不会用PS就得找外包,要么耗时间要么烧钱,还经常踩坑:要么用了非授权素材被期刊卡版权,要么画出来的图风格混乱被导师吐槽,直到被同门安利…...
合同系统业务功能
合同管理系统的核心是实现合同全生命周期管控,其生命周期主要分为五大环节:签订前管理、审批流程管理审批管理、合同签订、合同信息与文本管理、合同履约执行。 不同环节对应不同的功能需求,需结合企业业务特点灵活适配,以下是各环…...
JeecgBoot 低代码平台:协同工作与 Flowable 流程审批,如何选?
JeecgBoot 低代码平台两模块引困惑很多团队在接入 JeecgBoot 低代码平台后,面对 "协同工作" 和 "Flowable 流程审批" 两个模块时常常陷入困惑:两个都是处理审批流程的,到底用哪个?能混着用吗?设计…...
从拍照到HDR:用OpenCV玩转多曝光融合,让你的摄像头拍出大片感(C++实战)
从拍照到HDR:用OpenCV玩转多曝光融合,让你的摄像头拍出大片感(C实战) 当你在逆光环境下拍摄时,是否经常遇到这样的困境——要么天空过曝变成一片惨白,要么前景欠曝沦为剪影?传统相机的动态范围有…...
利用Taotoken多模型能力为内容生成平台提供弹性AI服务
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 利用Taotoken多模型能力为内容生成平台提供弹性AI服务 应用场景类,设想一个内容生成平台需要根据任务复杂度选择不同能…...
技术人的职业健康:保护身体,持续前行
技术人的职业健康:保护身体,持续前行 引言 作为一名技术人,我们常常长时间坐在电脑前,忽略了身体健康。今天就来分享一下职业健康的重要性和保护方法。 常见健康问题 颈椎问题 长时间低头看电脑会导致颈椎问题: 症状&a…...
