【ThreeJS Basics 1-5】动画 Animations

news2025/2/23 10:16:09

文章目录

  • Three JS 中的动画
  • window.requestAnimationFrame(fn)
  • 基本代码
  • 修改显示器刷新率的对比
  • 基础的动画尝试
  • 不同帧率导致动画速率不同
    • 解决方案一:DeltaTime
    • 解决方案2:Clock
    • 方法3: 动画库 Gsap
    • 如何选择方案?


Three JS 中的动画

了解如何生成动画,才能去创造出更丰富的场景,所以动画是很基本的知识!!首先需要了解一个JavaScript 的动画函数

window.requestAnimationFrame(fn)

window.requestAnimationFrame() 方法会告诉浏览器你希望执行一个动画。它要求浏览器在下一次重绘之前,调用用户提供的回调函数。

先来一组基础代码

基本代码

import * as THREE from 'three'
import gsap from 'gsap'

/**
 * Base
 */
// Canvas
const canvas = document.querySelector('canvas.webgl')

// Scene
const scene = new THREE.Scene()

/**
 * Base
 */
const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 })
const mesh = new THREE.Mesh(geometry, material)
scene.add(mesh)

/**
 * Sizes
 */
const sizes = {
    width: 800,
    height: 600
}

/**
 * Camera
 */
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height)
camera.position.z = 3
scene.add(camera)

/**
 * Renderer
 */
const renderer = new THREE.WebGLRenderer({
    canvas: canvas
})
renderer.setSize(sizes.width, sizes.height)

/**
 * Animate
 */
gsap.to(mesh.position, { duration: 1, delay: 1, x: 2 })

const tick = () =>
{
    // Render
    renderer.render(scene, camera)

    // Call tick again on the next frame
    window.requestAnimationFrame(tick)
}

tick()

此时运行项目,打开控制台就会看到一直再打印 tick

修改显示器刷新率的对比

我尝试修改显示器的刷新频率试一下,我从 170hz 调整到 60hz,可以看到控制台打印的速率明显变慢

请添加图片描述

以下是 60Hz 的样子,比起 170Hz,打印的速度慢了一些

在这里插入图片描述
说明 window.requestAnimationFrame(tick) 会根据刷新率的高低来处理回调函数的频率


基础的动画尝试

可以通过这个回调函数来试着做位移,旋转的动画

在这里插入图片描述
在这里插入图片描述

/**
 * Animate
 */
// gsap.to(mesh.position, { duration: 1, delay: 1, x: 2 })

const tick = () =>
{
    console.log('tick')

    // update objects
    mesh.rotation.x -= 0.01
    renderer.render(scene, camera)
    // Call tick again on the next frame
    window.requestAnimationFrame(tick)
}

tick()

不过,如果你的显示器帧率越高,那么这些动画的速度是越快的,因为在一秒钟内你有更多的 tick 函数的调用

不同帧率导致动画速率不同

我们来打印一下

/**
 * Animate
 */
// gsap.to(mesh.position, { duration: 1, delay: 1, x: 2 })

let time = Date.now()

const tick = () =>
{
    // console.log('tick')
    let currentTime = Date.now()
    let deltaTime = currentTime - time
    time = Date.now()

    console.log('deltaTime:>>', deltaTime)

    // update objects
    mesh.rotation.x -= 0.01
    renderer.render(scene, camera)
    // Call tick again on the next frame
    window.requestAnimationFrame(tick)
}

tick()

这个是 170Hz
在这里插入图片描述

这个是 60Hz
在这里插入图片描述
那么如何让不同刷新率的显示器,显示相同速度的动画呢?

解决方案一:DeltaTime


/**
 * Animate
 */
// gsap.to(mesh.position, { duration: 1, delay: 1, x: 2 })

let time = Date.now()

const tick = () =>
{
    // console.log('tick')
    let currentTime = Date.now()
    let deltaTime = currentTime - time
    time = Date.now()

    console.log('deltaTime:>>', deltaTime)

    // update objects
    mesh.rotation.x -= 0.001 * deltaTime
    renderer.render(scene, camera)
    // Call tick again on the next frame
    window.requestAnimationFrame(tick)
}

tick()

让我们来实验一下

在这里插入图片描述
在这里插入图片描述
看起来是有效果的!

解决方案2:Clock

// Clock
const clock = new THREE.Clock()

const tick = () =>
{
    const elapsedTime = clock.getElapsedTime()
    console.log('elapsedTime:>>', elapsedTime)

    // update objects
    mesh.rotation.x = elapsedTime * Math.PI * 0.5
    renderer.render(scene, camera)
    // Call tick again on the next frame
    window.requestAnimationFrame(tick)
}

tick()

这个是对比图

在这里插入图片描述

在这里插入图片描述
再来试试正弦函数

在这里插入图片描述

在这里插入图片描述

方法3: 动画库 Gsap

gsap 自己就会调用动画帧,所以不用告诉 gsap 自行更新

在这里插入图片描述
但是渲染的结果(也就是 Render) 还是要自己维护,所以render 要放到回调里。

如何选择方案?

  • 根据你的项目,你的熟练度
  • 以及项目体积,性能的权衡

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2303869.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WSL进阶使用指南

WSL2通过 Hyper-V 技术创建了一个轻量级的虚拟机(VM),在这个虚拟机之上可以运行一个真正的 Linux 内核,这给希望同时使用 Windows 和 Linux 的开发人员提供了无缝高效的体验。本文会介绍一些使用WSL的知识,帮助你更好地…

我是如何从 0 到 1 找到 Web3 工作的?

作者:Lotus的人生实验 关于我花了一个月的时间,从 0 到 1 学习 Web3 相关的知识和编程知识。然后找到了一个 Web3 创业公司实习的远程工作。 👇👇👇 我的背景: 计算机科班,学历还可以(大厂门槛水平) 毕业工…

如何通过外链提升网站SEO排名?

外链的作用非常明显,它不仅能提高网站的排名,还能增加网站的曝光量。Google排名的算法会考虑到网站的外链数量、质量和多样性。简单来说,更多的高质量外链意味着你的网站更有可信度,更容易被搜索引擎优待。 但是,过度…

DeepSeek服务器繁忙 多种方式继续优雅的使用它

前言 你的DeepSeek最近是不是总是提示”服务器繁忙,请稍后再试。”,尝试过了多次重新生成后,还是如此。之前DeepSeek官网连续发布2条公告称,DeepSeek线上服务受到大规模恶意攻击。该平台的对话框疑似遭遇了“分布式拒绝服务攻击”&#xff0…

量子计算的基本运算:Hadamard 门、CNOT 门、Pauli 门详解

量子计算是现代计算科学的前沿领域,它与经典计算机在处理信息的方式上有着本质的区别。量子计算机利用量子比特(qubit)的叠加态和量子纠缠等特性来进行计算,从而在某些特定任务上超越传统计算机。量子计算的核心运算单元是量子门,它们通过作用于量子比特来操控量子状态。本…

mysql之Innodb数据页

Innodb数据页结构 InnoDB数据页结构一、数据页基础概念二、数据页核心结构1. 头部控制区2. 数据存储区3. 尾部与目录区 三、关键机制详解1. 记录链表与删除优化2. 页目录与二分查找3. 空间复用与碎片管理4. 数据页的合并与分裂 四、应用与性能影响1. 索引效率2. 插入优化3. 事务…

基于 PyQt5 的聊天机器人程序(AI)

这是一个基于 PyQt5 的聊天机器人程序,通过 API 接入硅基流动(Silicon Flow)或其他的聊天服务,支持用户与聊天机器人进行交互。 API 设置:通过菜单栏的“设置”选项,用户可以修改 API 地址和 API 密钥。 设…

[实现Rpc] 服务端 | RpcRouter实现 | Builder模式

目录 项目服务端独用类的实现 1. RpcRouter类的实现 ServiceDescribe SDescribeFactory ⭕ Builder模式 1. 动机 2. 模式定义 3. 要点总结 4. 代码感受 ServiceManager RpcRouter 4. 代码感受 ServiceManager RpcRouter 前文我们就将 Rpc 通用类都实现完啦&#…

红外人体传感器选型和电路解析

红外人体传感器选型和电路解析 背景:想要制作一套IoT系统,基于HA构建上层管理,蓝牙和蓝牙MESH构建无线网络,以及多种传感器和控制器作为底层,其中人体红外传感器作为一个重要的选项,需要考虑好。 红外人体传…

rtthread的串口框架、485框架

一、串口接收超时中断的实现。 1. rtthread中定义的串口超时结构体 定义串口接收超时的结构体 CM_TMR0_TypeDef 为TM0的实例(实际有CM_TMR0_1 CM_TMR0_2 对应华大460的两个TMR0单元 ) channel 每个timer0有两个通道(TMR0_CHA、TMR0_CHB) clock 为FCG2_PERIPH_TMR0_1、FCG…

Embedding模型

检索的方式有那些 关键字搜索:通过用户输入的关键字来查找文本数据。 语义搜索:它的目标是理解用户查询的真实意图,不仅考虑关键词的匹配,还考虑词汇之间的语义 (文字,语音,语调...&#xff0…

最新扣子(Coze)案例教程:全自动DeepSeek 写影评+批量生成 + 发布飞书,提效10 倍!手把手教学,完全免费教程

👨‍💻群里有同学是做影视赛道的博主,听说最近DeepSeek这么火,咨询能不能用DeepSeek写影评,并整理电影数据资料,自动发布到飞书文档,把每天的工作做成一个自动化的流程。 那今天斜杠君就为大家…

Ubuntu 22.04安装K8S集群

以下是Ubuntu 22.04安装Kubernetes集群的步骤概要 一、设置主机名与hosts解析 # Master节点执行 sudo hostnamectl set-hostname "k8smaster" # Worker节点执行 sudo hostnamectl set-hostname "k8sworker1"# 所有节点的/etc/hosts中添加: ca…

Apifox 增强 AI 接口调试功能:自动合并 SSE 响应、展示DeepSeek思考过程

在现代的API接口调试中,效率和精确性对于开发者和测试人员来说至关重要。Apifox,作为一款功能强大的API管理和调试工具,近年来不断提升其用户体验和智能化功能。最近,Apifox 推出了增强版的AI接口调试功能,其中包括自动…

MATLAB基础学习相关知识

MATLAB安装参考:抖音-记录美好生活 MATLAB基础知识学习参考:【1小时Matlab速成教程-哔哩哔哩】 https://b23.tv/CnvHtO3 第1部分:变量定义和基本运算 生成矩阵: % 生成矩阵% 直接法% ,表示行 ;表示列 a [1,2,3;4,5,6;7,8,9];%…

DeepSeek赋能智慧文旅:新一代解决方案,重构文旅发展的底层逻辑

DeepSeek作为一款前沿的人工智能大模型,凭借其强大的多模态理解、知识推理和内容生成能力,正在重构文旅产业的发展逻辑,推动行业从传统的经验驱动向数据驱动、从人力密集型向智能协同型转变。 一、智能服务重构:打造全域感知的智…

蓝桥与力扣刷题(蓝桥 交换瓶子)

题目:有 N 个瓶子,编号 1 ~ N,放在架子上。 比如有 5 个瓶子: 2 1 3 5 4 要求每次拿起 2 个瓶子,交换它们的位置。 经过若干次后,使得瓶子的序号为: 1 2 3 4 5 对于这么简单的情况&#x…

腿足机器人之十一- 深度强化学习

腿足机器人之十一- 深度强化学习 机器人能力腿足机器人RL问题建模强化学习解决方案 强化学习算法库选择建议 深度学习技术已经在语音、图像、视频、文本等领域应用广泛,其和强化学习的结合使得基于深度学习的大模型能力更是上升一个台阶。因而用在腿足机器人的运动中…

纠错检索增广生成论文

一、摘要 动机:RAG严重依赖于检索文档的相关性,如果检索出错,那么LLM的输出结果也会出现问题 解决方案:提出纠正性检索增强生成(CRAG)即设计一个轻量级的检索评估器,用来评估针对某个查询检索…

多源 BFS 算法详解:从原理到实现,高效解决多源最短路问题

多源 BFS 是一种解决 边权为 1 的多源最短路问题 的高效算法。其核心思想是将所有源点视为一个“超级源点”,通过一次 BFS 遍历即可计算所有节点到最近源点的最短距离。以下从原理、实现和代码示例三个方面深入讲解: 目录 一、原理分析 1. 单源 BFS vs…