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 等…...

linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

实战设计模式之模板方法模式
概述 模板方法模式定义了一个操作中的算法骨架,并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下,重新定义算法中的某些步骤。简单来说,就是在一个方法中定义了要执行的步骤顺序或算法框架,但允许子类…...

医疗AI模型可解释性编程研究:基于SHAP、LIME与Anchor
1 医疗树模型与可解释人工智能基础 医疗领域的人工智能应用正迅速从理论研究转向临床实践,在这一过程中,模型可解释性已成为确保AI系统被医疗专业人员接受和信任的关键因素。基于树模型的集成算法(如RandomForest、XGBoost、LightGBM)因其卓越的预测性能和相对良好的解释性…...

Java中HashMap底层原理深度解析:从数据结构到红黑树优化
一、HashMap概述与核心特性 HashMap作为Java集合框架中最常用的数据结构之一,是基于哈希表的Map接口非同步实现。它允许使用null键和null值(但只能有一个null键),并且不保证映射顺序的恒久不变。与Hashtable相比,Hash…...

spring中的@KafkaListener 注解详解
KafkaListener 是 Spring Kafka 提供的一个核心注解,用于标记一个方法作为 Kafka 消息的消费者。下面是对该注解的详细解析: 基本用法 KafkaListener(topics "myTopic", groupId "myGroup") public void listen(String message)…...

(33)课54:3 张表的 join-on 连接举例,多表查询总结。数据库编程补述及游标综合例题。静态 sqL与动态sqL(可带参数)
(112)3 张表的 join-on 连接举例 : (113) 多表查询总结 : (114)数据库编程补述 : 综合例题 : 以上没有动手练习,不知道这样的语法是否…...