ThreeJS:补间动画与Tween.JS

补间动画

        补间动画指的是做FLASH动画时,在两个关键帧中间需要做“补间动画”,才能实现图画的运动;插入补间动画后两个关键帧之间的插补帧是由计算机自动运算而得到的。

——摘自《百度百科:补间动画_百度百科》

Tween.js

        Tween.js的GitHub项目地址:GitHub - tweenjs/tween.js: JavaScript/TypeScript animation engine,

        官网文档地址:tween.js 用户指南 | tween.js。

        利用ThreeJS自带的Tween.js可以很方便的实现补间动画,直接导入即可使用,

import { Tween } from 'three/examples/jsm/libs/tween.module.js'; //Tween.js

Tween基本使用

//TODO:添加1个球体
const ball1 = new THREE.SphereGeometry(1);
const ballMaterial = new THREE.MeshBasicMaterial({color:0xffff00});
const ballMesh1 = new THREE.Mesh(ball1,ballMaterial);
ballMesh1.geometry.scale(0.5,0.5,0.5);
ballMesh1.position.set(0,0,0);scene.add(ballMesh1);

        假设现在创建了一个小球,我们要使用Tween为其设置动画效果,

//TODO:Tween.js补间动画
const tween = new TWEEN.Tween(ballMesh1.position);
tween.to({x:4},1000).onUpdate(function(vector3Position){//监听位置变化console.log(vector3Position);});
//设置重复次数-[2次]
tween.repeat(2);
//设置重复次数-[无数次]
// tween.repeat(Infinity);
//设置循环往复
tween.yoyo(true);
//设置延迟执行时间
tween.delay(1000);//在animate循环渲染函数中调用updateTween
function updateTween(){tween.update();
}

        以上代码,就可实现ballMesh小球沿着X轴,循环往复运动2次的动画效果。

Tween缓动函数

缓动函数:用于表示自定义参数随时间变化的速率。

        Tween.js提供的缓动函数可参考:Tween.js / graphs,

        通过使用缓动函数,可以模拟物体的匀变速运动(加速/减速)运动。

        例如,使用缓动函数Quadratic.In,来模拟物体的匀加速运动,修改上述代码如下,

//TODO:Tween.js补间动画
const tween = new TWEEN.Tween(ballMesh1.position);
tween.to({x:4},1000).onUpdate(function(vector3Position){//监听位置变化console.log(vector3Position);});
//设置重复次数-[2次]
// tween.repeat(2);
//设置重复次数-[无数次]
tween.repeat(Infinity);
//设置循环往复
tween.yoyo(true);
//设置延迟执行时间-【可以避免动画的跳动现象】
tween.delay(100);
//设置缓动函数
tween.easing(TWEEN.Easing.Quadratic.In);function updateTween(){TWEEN.update();
}

Tween链接补间

        当你按顺序排列不同的补间时,事情会变得更有趣,例如在上一个补间结束的时候立即启动另外一个补间。我们称此为链接补间,它是通过 chain 方法完成的。因此,要使 tweenB 在 tweenA 完成后开始:

tweenA.chain(tweenB)

        或者,可以创造一个无限的链式,tweenA 完成时开始 tweenBtweenB 完成时开始 tweenA

tweenA.chain(tweenB)
tweenB.chain(tweenA)

        在其他情况下,你可能希望将多个补间链接到另一个补间,使它们(链接的补间)都同时开始动画:

tweenA.chain(tweenB, tweenC)

Warning 调用 tweenA.chain(tweenB) 实际上修改了 tweenA,所以 tweenB 总是在 tweenA 完成时启动。 chain 的返回值只是 tweenA,不是一个新的 tween。

        例如:我们使用chain链接补间的方式,实现上面的循环往复运动,

//TODO:Tween.js补间动画
const tween = new TWEEN.Tween(ballMesh1.position);
tween.to({x:4},1000).onUpdate(function(vector3Position){//监听位置变化console.log(vector3Position);});
//设置缓动函数
tween.easing(TWEEN.Easing.Quadratic.In);const tweenBack = new TWEEN.Tween(ballMesh1.position);
tweenBack.to({x:0,},1000);
//设置缓动函数
tween.easing(TWEEN.Easing.Quadratic.Out);//创建补间动画
tween.chain(tweenBack);
tweenBack.chain(tween);//启动动画tween
tween.start();function updateTween(){TWEEN.update();
}

        通过以上代码,也可以实现yoyo()的效果。

Tween动画生命周期回调函数

        利用Tween.js构建的动画包含:开始、更新、停止、完成几个生命周期阶段,Tween.js也提供了对应的生命周期回调函数,如下图所示,

Tween.js最佳性能实践

        虽然 Tween.js 试图靠自己发挥性能,但没有什么能阻止你以反性能的方式使用它。 以下是一些在使用 Tween.js 时(或通常在 Web 中制作动画时)可以避免拖慢项目速度的方法。

使用高性能的 CSS

        当你尝试为页面中元素的位置设置动画时,最简单的解决方案是为 top 和 left 样式属性设置动画,如下所示:

var element = document.getElementById('myElement')
var tween = new TWEEN.Tween({top: 0, left: 0}).to({top: 100, left: 100}, 1000).onUpdate(function (object) {element.style.top = object.top + 'px'element.style.left = object.left + 'px'
})

        但这确实效率低下,因为更改这些属性会强制浏览器在每次更新时重新计算布局,这是一项非常消耗性能的操作。你应该使用 transform,它不会使布局无效,并且在可能的情况下也会进行硬件加速,如下所示:

var element = document.getElementById('myElement')
var tween = new TWEEN.Tween({top: 0, left: 0}).to({top: 100, left: 100}, 1000).onUpdate(function (object) {element.style.transform = 'translate(' + object.left + 'px, ' + object.top + 'px);'
})

        如果你想了解更多关于高性能的 CSS,看看这篇文章。

        但是,如果你的动画需求就这么简单,最好只使用 CSS 动画或过渡(在适用的情况下),这样浏览器就可以尽可能地进行优化。 当你的动画需要涉及复杂的操作时,Tween.js 是非常有用,也就是说,你需要将多个补间同步在一起,在一个完成后开始,循环多次,具有不是使用 CSS 而是使用 Canvas 渲染的图形或 WebGL 等等。

对垃圾收集器(别名 GC)

        如果你使用 onUpdate 回调,你需要非常小心你放在它上面的东西。 这个函数每秒会被调用很多次,所以如果你在每次更新时都做代价高昂的操作,你可能会阻塞主线程并导致可怕的卡顿,或者——如果你的操作涉及内存分配,你最终会得到 垃圾收集器运行过于频繁,也会导致卡顿。 所以不要做这两件事。 保持你的 onUpdate 回调非常轻量级,并确保在开发时也使用内存分析器。

疯狂的补间

        这是你可能不经常使用的东西,但你可以在 Tween.js 之外使用补间方程式。 毕竟,它们只是函数。 因此,你可以使用它们来计算平滑曲线作为输入数据。 

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

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

相关文章

xCode升级后: Library ‘iconv2.4.0’ not found

报错信息: targets 选中 xxxNotification: Build Phases ——> Link Binary With Libraries 中,移除 libiconv.2.4.0.tbd libiconv.2.4.0.dylib 这两个库(只有一个的移除一个就好)。 然后重新添加 libiconv.tbd 修改完…

(代码以上传,超级详细)面试必备算法题----Leeecode290单词规律

文章目录 概要题目要求测试and提交结果技术细节 概要 来自Leecode ​ 代码已上传)仓库,需要测试实例和其他题型解决,可以去自行浏览 点击这里进入仓库领取代码喔!顺便点个star给原子加油吧! ​ 题目要求 使用哈希表 …

GD32F103RCT6/GD32F303RCT6(9)高级定时器互补PWM波输出实验

本文章基于兆易创新GD32 MCU所提供的2.2.4版本库函数开发 后续项目主要在下面该专栏中发布: 手把手教你嵌入式国产化_不及你的温柔的博客-CSDN博客 感兴趣的点个关注收藏一下吧! 电机驱动开发可以跳转: 手把手教你嵌入式国产化-实战项目-无刷电机驱动&am…

【设计模式】之观察者模式

系列文章目录 【设计模式】之装饰器模式【设计模式】之工厂模式(三种)【设计模式】之工厂模式(三种) 前言 今天给大家介绍另一种设计模式--观察者模式,有了解webscoket实现原理的小伙伴应该对这个设计模式不陌生。不清…

微服务核心01-Maven【项目管理工具】基础

一、Maven 简介 1.1 传统项目管理: 1.2 Maven 的作用 项目构建:提供标准的、跨平台的自动化项目构建方式。依赖管理:管理项目依赖的资源(jar 包),避免资源间的版本冲突问题统一开发结构:提供标…

Web LLM 攻击实验:利用 LLM API 实现 SQL 注入

前言 Web LLM 攻击 各组织都在急于集成大型语言模型 (LLM),以改善其在线客户体验。这使他们面临 Web LLM 攻击,这些攻击利用模型对攻击者无法直接访问的数据、API 或用户信息的访问权限。例如,攻击可能: 检索 LLM 有权访问的数…

【valse 2024】会议内容汇总(持续更新)

系列文章目录 提示:更新中,一周左右更新完毕。需要具体课件的可私信 文章目录 系列文章目录开幕式主旨报告-1:大模型时代的机遇和挑战主旨报告-2:以深度学习框架为牵引促进自主 AI生态发展主旨报告-3:从洞穴的影子到智能的光辉--连接和交互方式的改变塑造…

别出心裁的自动化网页数据采集:Chrome插件和mitmproxy

别出心裁的自动化网页数据采集:Chrome插件和mitmproxy 前言 在信息时代,数据已成为决策的关键。传统的数据采集方法往往依赖于手动操作或简单的自动化脚本,这限制了数据的时效性和精确性。为了克服这些限制,本文介绍了一种结合C…

文件批量移动:按路径名称指引,高效文件管理与批量归类实战

在数字化时代,文件批量移动成为了一项至关重要的技能,它能够帮助我们高效地管理和归类大量的文件。通过按路径名称指引进行文件批量移动,我们可以使文件组织更加有序,提高文件检索的速度,从而提升工作效率。 一、明确路…

多线程学习Day09

10.Tomcat线程池 LimitLatch 用来限流,可以控制最大连接个数,类似 J.U.C 中的 Semaphore 后面再讲 Acceptor 只负责【接收新的 socket 连接】 Poller 只负责监听 socket channel 是否有【可读的 I/O 事件】 一旦可读,封装一个任务对象&#x…

【建议收藏】CSP-J/S信奥赛,小白报名教程!

✅ 信奥介绍 信息学奥赛是五大学科(数学、物理、化学、生物、信息学)奥林匹克竞赛中唯一一个可以贯穿小学、初中、高中的特长生项目。由中国计算机学会主办,主要考察信息学,即编程的相关知识和能力。 ✅ 报名流程 👉登…

智能绘画系统源码系统 后台自由设置会员套餐 带网站的安装包以及安装部署教程

在当今数字化与智能化快速发展的时代,艺术与技术正以前所未有的速度相互融合。为了满足广大绘画爱好者和专业艺术家的需求,我们精心打造了一款智能绘画系统源码系统。该系统不仅具备高度的智能化特性,还提供了丰富的后台管理功能,…

CTF-密码学基础

概述 密码学(Cryptolopy):是研究信息系统安全保密的科学 密码学研究的两个方向: 密码编码学(Cryptography):主要研究对信息进行编码,实现对信息的隐蔽密码分析学(Cryptanalytics):主要研究加密信息的破译或消息的伪造…

多客陪玩系统源码APP小程序H5陪玩开发伴游源码游戏陪玩平台源码陪玩平台开发约单源码线下陪玩接单平台app小程序H5源码游戏陪玩app小程序H5开发

出售成品陪玩app小程序H5源码,免费搭建部署和售后服务,并提供源码二开、定制开发等相关服务。 一、陪玩app源码的功能介绍 1、语音聊天: 陪玩app小程序H5源码用户随时创建语音聊天室,实现多用户上麦功能,提高互动聊天体验。 2、游…

【Qt 开发基础体系】字符串类应用和常用的数据类型

文章目录 1. Qt 字符串类应用1.1 操作字符串1.2 QString::append()函数1.3 QString::sprintf()函数1.4 QString::arg()函数 2. 查询字符串2.1 函数 QString::startsWith()2.2 函数 QString::contains()2.3 函数 QString::toInt()2.4 函数 QString::compare()2.5 将 QString 转换…

攻克《模版进阶》 全方位了解

目录 前言: 非类型模板参数 按需实例化 模板的特化 概念: 函数模板特化: 类模板特化: 1、全特化 2、偏特化 3、类模板特化应用示例 模板分离编译 什么是分离编译 模板的分离编译 解决方法 总结 前言: 我…

PostgreSQL和openGauss优化器对一个关联查询的SQL优化改写

PostgreSQL和openGauss数据库优化器在merge join关联查询的SQL优化改写 PostgreSQL 查询计划openGauss 查询计划拓展对比 看腻了文章就来听听视频讲解吧:https://www.bilibili.com/video/BV1oH4y137P7/ 数据库类型数据库版本PostgreSQL16.2openGauss6.0 创建测试表…

Python语言基础与由来介绍【自我维护版】

各位大佬好 ,这里是阿川的博客 , 祝您变得更强 个人主页:在线OJ的阿川 大佬的支持和鼓励,是我成长路上最大的动力 阿川水平有限,如有错误,欢迎大佬指正 本篇博客是在已有的博客的基础上进行的维护。 主要…

知识付费系统怎么搭建_轻松拥有知识付费平台

在信息爆炸的时代,知识的获取已不再局限于传统的课堂和书籍。随着科技的进步和互联网的普及,我们迎来了一个全新的知识获取方式——知识付费。今天,就让我们一起探讨如何搭建一个专属于您的知识付费系统,开启智慧的大门&#xff0…

常见C语言基础说明二:位运算问题

一. 简介 前面一篇文章学习了 常见的 C语言基础题,文章如下: 常见C语言基础题说明一-CSDN博客 本文继续上一篇C语言基础题的学习。 二. C语言中 -> 位运算问题 1. 数据在计算机中的存储方式 当前的计算机系统使用的基本上是二进制系统&#…