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

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&#xff1a;C中的字符串如何存储 在C中&#xff0c;字符串可以通过多种方式存储&#xff0c;但最常见和推荐使用的方式是通过 std::string 类&#xff0c;该类位于 <string> 头文件中。std::string 是一个类模板的实例&#xff0c;通常用于存储字符数组&#x…...

掌握C语言文件操作:从入门到精通的完整指南!

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C语言学习 贝蒂的主页&#xff1a;Betty‘s blog 1. 什么是文件 文件其实是指一组相关数据的有序集合。这个数据集有一个名称&a…...

JavaEE作业-实验二

目录 1 实验内容 2 实验要求 3 思路 4 核心代码 5 实验结果 1 实验内容 实现两个整数求和的WEB程序 2 实验要求 ①采用SpringMVC框架实现 ②数据传送到WEB界面采用JSON方式 3 思路 ①创建一个SpringMVC项目&#xff0c;配置好相关的依赖和配置文件。 ②创建一个Con…...

2月8号作业

Sqlite3系统命令 .quit 退出数据库 .exit 退出数据库 .help 显示帮助信息&#xff0c;获取所有系统命令 .table 查看当前数据库下的所有表格 .schema 查看表的结构 Sqlite3语句 创建表格&#xff1a; create table 表名 (字段名 数据类型, 字段名 数据类型); create table if…...

08:K8S资源对象管理|服务与负载均衡|Ingress

K8S资源对象管理&#xff5c;服务与负载均衡&#xff5c;Ingress DaemonSet控制器污点策略容忍容忍污点 其他资源对象Job资源对象 有限生命周期CronJob资源对象 集群服务服务自动发现headless服务 实现服务定位与查找 服务类型 Ingress插件 发布服务的方式 DaemonSet控制器 Da…...

HarmonyOS 横屏调试与真机横屏运行

我们有些程序 需要横屏才能执行出效果 我们在预览器上 点击如下图指向出 就进入一个横屏调试了 但 我们真机运行 依旧是竖着的 我们如下图 找到 module.json5 在 abilities 下面 第一个对象 最下面 加上 "orientation": "landscape"然后 我们再真机运…...

Javaweb基础-tomcat,servlet

一.配置文件基础&#xff1a; properties配置文件&#xff1a; 由键值对组成 键和值之间的符号是等号 每一行都必须顶格写&#xff0c;前面不能有空格之类的其他符号 xml配置文件&#xff1a;&#xff08;xml语法HTML语法HTML约束&#xff09;xml约束-DTD / Schema DOM4…...

HCIA-HarmonyOS设备开发认证V2.0-3.2.轻量系统内核基础-中断管理

目录 一、中断基础概念二、中断管理使用说明三、中断管理模块接口四、代码分析&#xff08;待续...&#xff09;坚持就有收获 一、中断基础概念 在程序运行过程中&#xff0c;出现需要由 CPU 立即处理的事务时&#xff0c;CPU 暂时中止当前程序的执行转而处理这个事务&#xf…...

【开源】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绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十 下载地址 模型介绍 DreamShaper 是一个分格多样的大模型&#xff0c;可以生成写实、原画、2.5D 等…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

Spring数据访问模块设计

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

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

嵌入式学习笔记DAY33(网络编程——TCP)

一、网络架构 C/S &#xff08;client/server 客户端/服务器&#xff09;&#xff1a;由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序&#xff0c;负责提供用户界面和交互逻辑 &#xff0c;接收用户输入&#xff0c;向服务器发送请求&#xff0c;并展示服务…...

Unity UGUI Button事件流程

场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器

一、原理介绍 传统滑模观测器采用如下结构&#xff1a; 传统SMO中LPF会带来相位延迟和幅值衰减&#xff0c;并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF)&#xff0c;可以去除高次谐波&#xff0c;并且不用相位补偿就可以获得一个误差较小的转子位…...

9-Oracle 23 ai Vector Search 特性 知识准备

很多小伙伴是不是参加了 免费认证课程&#xff08;限时至2025/5/15&#xff09; Oracle AI Vector Search 1Z0-184-25考试&#xff0c;都顺利拿到certified了没。 各行各业的AI 大模型的到来&#xff0c;传统的数据库中的SQL还能不能打&#xff0c;结构化和非结构的话数据如何和…...