three.js 关键帧动画

效果:

代码:

<template><div><el-container><el-main><div class="box-card-left"><div id="threejs" style="border: 1px solid red"></div><div class="box-right"><el-button type="primary" @click="start">循环播放</el-button><el-button type="primary" @click="start_once">播放一次</el-button><el-button type="primary" @click="start_clamp">保持播放结束效果</el-button><el-button type="primary" @click="stop">结束动画</el-button><el-button type="primary" @click="pausedFn">暂停</el-button><el-button type="primary" @click="time_scale">2倍速循环播放</el-button><el-button type="primary" @click="time_duration">控制动画播放特定时间开始(2秒)</el-button><div style="margin-top: 20px;"></div><el-progress:percentage="percentage":format="format"></el-progress><el-button-group><el-button icon="el-icon-minus" @click="decrease">播放速度</el-button><el-button icon="el-icon-plus" @click="increase">播放速度</el-button></el-button-group><el-slider v-model="value1" @change="change"></el-slider>动画播放(拖动任意时间状态)</div></div></el-main></el-container></div>
</template>
<script>
// 引入轨道控制器扩展库OrbitControls.js
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
// 效果制作器
import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer.js";
// 渲染通道
import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass.js";
// 发光描边OutlinePass
import { OutlinePass } from "three/examples/jsm/postprocessing/OutlinePass.js";
import {CSS2DObject,CSS2DRenderer,
} from "three/examples/jsm/renderers/CSS2DRenderer.js";export default {data() {return {value1: 0,percentage: 20,name: "",scene: null,camera: null,renderer: null,effectComposer: null,mesh: null,geometry: null,group: null,material: null,texture: null,position: null,outlinePass: null,clock: null,mixer: null,clip_action: null,request_animation_frame: null,canvasWidth: 1000,canvasHeight: 800,color: [],meshArr: [],};},created() {},mounted() {this.name = this.$route.query.name;this.init();},methods: {goBack() {this.$router.go(-1);},// 动画播放(拖动任意时间状态)change(e) {console.log("e:", e);this.clip_action.paused = true;this.clip_action.clampWhenFinished = true;this.clip_action.time = 0.1 * e;},format(percentage) {return percentage / 10 + "倍";},increase() {this.percentage += 10;if (this.percentage > 100) {this.percentage = 100;}this.clip_action.timeScale = this.percentage / 10;},decrease() {this.percentage -= 10;if (this.percentage < 0) {this.percentage = 0;}this.clip_action.timeScale = this.percentage / 10;},init() {//  创建场景对象this.scene = new this.$three.Scene();// 创建立方几何体对象this.geometry = new this.$three.BoxGeometry(60, 50, 90);// 创建材质对象this.material = new this.$three.MeshBasicMaterial({color: 0xaabbdd,});// 创建网格对象this.mesh = new this.$three.Mesh(this.geometry, this.material);this.scene.add(this.mesh);this.clock = new this.$three.Clock();this.animation();// 调用play方法// clip_action.play();// 创建相机对象this.camera = new this.$three.PerspectiveCamera(60, 1, 0.01, 2000);this.camera.position.set(300, 300, 300);this.camera.lookAt(0, 0, 0);// 创建网格辅助对象const axesHelper = new this.$three.AxesHelper(100);this.scene.add(axesHelper);const gridHelper = new this.$three.GridHelper(300,20,0xffaaaa,0xaabbcc);this.scene.add(gridHelper);// 创建渲染器对象this.renderer = new this.$three.WebGLRenderer();this.renderer.setSize(1000, 800);this.renderer.render(this.scene, this.camera);window.document.getElementById("threejs").appendChild(this.renderer.domElement);const controls = new OrbitControls(this.camera, this.renderer.domElement);controls.addEventListener("change", () => {this.renderer.render(this.scene, this.camera);});},// 创建关键帧的方法animation() {// 给模型定义namethis.mesh.name = "Box";// 定义时间范围const time = [0, 3, 6, 8, 10]; // 对应时间轴上的0,3,6秒// 定义0,3,6秒对应的坐标值const values = [0, 0, 0, 100, 0, 0, 0, 0, 100, 0, 100, 0, 0, 0, 0];// 创建关键帧 KeyframeTrack(params: String, timeRange: Array, valueRange: Array)// params 模型的属性,timeRange: 时间范围,valueRange: 值范围const position_kf = new this.$three.KeyframeTrack("Box.position",time,values);// 设置在2-6秒内颜色变化,颜色三个数一组表示 rgb格式的/*** .setRGB ( r, g, b ) thisr — 红色通道值在1和0之间。g — 绿色通道值在1和0之间。b — 蓝色通道值在1和0之间。设置颜色的RGB值。*/const color_kf = new this.$three.KeyframeTrack("Box.material.color",[2, 6],[1, 0.2, 0.3, 0.1, 0.8, 0.3]);// 创建关键帧动画对象  AnimationClip(name:String, time:Number, value: Array)const clip = new this.$three.AnimationClip("clip_name", 10, [position_kf,color_kf,]);// 创建动画播放器this.mixer = new this.$three.AnimationMixer(this.mesh);this.clip_action = this.mixer.clipAction(clip);},renderFun() {this.renderer.render(this.scene, this.camera);const frameT = this.clock.getDelta();// 更新播放器相关的时间(如果不更新,则没有动画效果)if (this.mixer) {this.mixer.update(frameT);}this.request_animation_frame = window.requestAnimationFrame(this.renderFun);},start() {this.clip_action.loop = this.$three.LoopRepeat;this.clip_action.paused = false;// play() 控制动画播放,默认循环播放this.clip_action.play();this.renderFun();},start_once() {this.clip_action.loop = this.$three.LoopOnce;// play() 控制动画播放,默认循环播放this.clip_action.play();this.renderFun();},start_clamp() {// 物体状态停留在动画结束的时候this.clip_action.clampWhenFinished = true;this.clip_action.loop = this.$three.LoopOnce;// play() 控制动画播放,默认循环播放this.clip_action.play();this.renderFun();},stop() {// play() 控制动画播放,默认循环播放this.clip_action.stop();// // 物体状态停留在动画结束的时候this.clip_action.clampWhenFinished = true;// this.renderFun();},pausedFn() {console.log(this.clip_action.paused);if (this.clip_action.paused) {this.clip_action.paused = false;} else {this.clip_action.paused = true;}this.renderFun();},time_scale() {this.clip_action.timeScale = 2;this.clip_action.play();this.renderFun();},time_duration() {// 控制动画播放特定时间段;需要设置为非循环模式、同时设置动画播放完定留在结束状态,// 设置为非循环模式this.clip_action.loop = this.$three.LoopOnce;this.clip_action.clampWhenFinished = true;this.clip_action.time = 2; // 动画开始时间// this.clip_action.duration = 2; // 动画结束时间this.clip_action.play();this.renderFun();},},
};
</script>
//
<style lang="less" scoped>
.box-card-left {display: flex;align-items: flex-start;flex-direction: row;width: 100%;.box-right {img {width: 500px;user-select: none;}}
}
</style>

 

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

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

相关文章

金和OA jc6 GetAttOut SQL注入漏洞复现

0x01 产品简介 金和OA协同办公管理系统软件(简称金和OA),本着简单、适用、高效的原则,贴合企事业单位的实际需求,实行通用化、标准化、智能化、人性化的产品设计,充分体现企事业单位规范管理、提高办公效率的核心思想,为用户提供一整套标准的办公自动化解决方案,以帮助…

语义解析:如何基于SQL去实现自然语言与机器智能连接的桥梁

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 &#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 语义解析 定义 作用 语义解析的应用场景 场景一&#xff1a; 场景二&#xff1a; 总结语…

【LeetCode】winter vacation training

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;【LeetCode】winter vacation training 目录 &#x1f449;&#x1f3fb; 有效的字母异位词&#x…

129基于matlab的粒子群算法、遗传算法、鲸鱼算法、改进鲸鱼算法优化最小二乘支持向量机(lssvm)的gam正则化参数和sig2RBF函数的参数

基于matlab的粒子群算法、遗传算法、鲸鱼算法、改进鲸鱼算法优化最小二乘支持向量机&#xff08;lssvm&#xff09;的gam正则化参数和sig2RBF函数的参数。输出适应度曲线&#xff0c;测试机和训练集准确率。程序已调通&#xff0c;可直接运行。 129 matlabLSSVM优化算法 (xiaoh…

【排序】对各种排序的总结

文章目录 前言1. 排序算法的复杂度及稳定性分析2. 排序算法的性能测试2.1 重复率较低的随机值排序测试2.2 重复率较高的随机值排序测试 前言 本篇是基于我这几篇博客做的一个总结&#xff1a; 《简单排序》&#xff08;含&#xff1a;冒泡排序&#xff0c;直接插入排序&#x…

RabbitMQ(六)消息的持久化

目录 一、简介1.1 定义1.2 消息丢失的场景 二、交换机的持久化方式一&#xff1a;直接 new方式二&#xff1a;channel.exchangeDeclare()方式三&#xff1a;ExchangeBuilder【推荐】 三、队列的持久化方式一&#xff1a;直接 new方式二&#xff1a;channel.queueDeclare()方式三…

怎么样检查自己系统上的Python环境中是否有某个包(扩展库)?

比如我们这里想看下有没有库pytz 很简单&#xff0c;进入Python的命令行&#xff0c;然后输入下面的命令&#xff1a; import pytz如果有这个库&#xff0c;则不会报错&#xff0c;否则会报错。 Windows的测试结果如下&#xff1a; Centos的测试结果如下&#xff1a;

Hive分区表实战 - 多分区字段

文章目录 一、实战概述二、实战步骤&#xff08;一&#xff09;创建学校数据库&#xff08;二&#xff09;创建省市分区的大学表&#xff08;三&#xff09;在本地创建数据文件1、创建四川成都学校数据文件2、创建四川泸州学校数据文件3、创建江苏南京学校数据文件4、创建江苏苏…

字节8年经验之谈!一文从0到1带你入门接口测试【建议收藏】

扫盲内容&#xff1a; 1.为什么要做接口测试&#xff1f; 2.怎样做接口测试&#xff1f; 3.接口测测试点是什么&#xff1f; 4.接口测试都要掌握哪些知识&#xff1f; 5.其他相关知识&#xff1f; 一.为什么要做接口测试&#xff1f; ①.越底层发现bug&#xff0c;它的修…

5G之味,在烟火长沙

今年夏天&#xff0c;有一部电影叫做《长沙夜生活》。影片讲述了长沙大排档中的一些故事。网红大排档的老板娘、厨师、顾客&#xff0c;他们的邂逅、热爱、留下、离开、和解、团圆&#xff0c;都发生在一段夜色里&#xff0c;发生在充满烟火气的长沙城。 有没有想过这样一个问题…

线性表入门

王有志&#xff0c;一个分享硬核Java技术的互金摸鱼侠加入Java人的提桶跑路群&#xff1a;共同富裕的Java人 从今天开始就进入到数据结构的部分了&#xff0c;整体分为3个部分&#xff1a;线性表&#xff0c;树和图&#xff0c;从认识每种数据结构到它们的高级应用。今天我们先…

C# Linq+ValueTuple(元祖),成为Linq高手!

文章目录 前言简单使用:能被2整除ValueTuple使用:两数相加等于4不使用元祖使用元祖排序 基于类的LinqGroupByJoinDistinct去重普通去重选择去重 集合去重ExceptIntersectUnion 总结 前言 Linq是C# 最强语法之一&#xff0c;和委托,get set并列(在我的心中)。我很早就听说了Lin…

基于JavaWeb+BS架构+SpringBoot+Vue智能停车计费系统的设计和实现

基于JavaWebBS架构SpringBootVue智能停车计费系统的设计和实现 文末获取源码Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 文末获取源码 Lun文目录 1 绪 论 1 1.1 研究背景 1 1.2 研究意义 1 1.3 系统主要功能 1 1.4 拟解决…

Blazor快速开发框架Known-V2.0.0

Known2.0 Known是基于Blazor的企业级快速开发框架&#xff0c;低代码&#xff0c;跨平台&#xff0c;开箱即用&#xff0c;一处代码&#xff0c;多处运行。 官网&#xff1a;http://known.pumantech.comGitee&#xff1a; https://gitee.com/known/KnownGithub&#xff1a;ht…

Ubuntu22.04开机左上角下划线闪烁不开机

按下CtrlAltF2&#xff0c;打开TTY系统&#xff0c;然后通过用户名和密码登录&#xff0c;随后使用 sudo apt --fix-broken install 根据提示排除错误信息&#xff0c;然后使用apt安装lightdm安装就行。 tips:当使用EasyConnect的时候&#xff0c;你可能参考了下面这篇文章知…

130基于MATLAB并结合IBD算法的盲迭代反卷积法进行图像复原

基于MATLAB并结合IBD算法的盲迭代反卷积法进行图像复原 ,输出复原前后图像&#xff0c;PSF频谱结果。程序已调通&#xff0c;可直接运行。 130 matlab盲迭代反卷积IBD (xiaohongshu.com)

【Kafka-3.x-教程】-【三】Kafka-Broker、Kafka-Kraft

【Kafka-3.x-教程】专栏&#xff1a; 【Kafka-3.x-教程】-【一】Kafka 概述、Kafka 快速入门 【Kafka-3.x-教程】-【二】Kafka-生产者-Producer 【Kafka-3.x-教程】-【三】Kafka-Broker、Kafka-Kraft 【Kafka-3.x-教程】-【四】Kafka-消费者-Consumer 【Kafka-3.x-教程】-【五…

【Redis】Redis持久化方式

Redis 中有两种持久化方式&#xff0c;分别为 RDB 和 AOF。 RDB RDB 全称 Redis Database Backup file&#xff0c;也叫做 Redis 数据快照。简单来说就是把 Redis 中的数据记录到磁盘中。当 Redis 实例故障重启后&#xff0c;从磁盘读取快照文件&#xff0c;恢复数据。 RDB有…

ESP32S3+HX8347+RGB运行LVGL例程

之前用3线SPI驱动的HX8347屏其实是一个RGB屏&#xff0c;SPI只是用来给RGB屏幕的做配置的&#xff0c;当然也可以用来驱动屏幕&#xff0c;但是3线SPI驱动能力终究有限。本文谈一下用RGB方式来驱动。 RGB接线比较多&#xff0c;为此做了个转接板&#xff1a; 一、源码 1、scre…

超维空间M1无人机使用说明书——53、ROS无人机二维码识别与降落——V2升级版本

引言&#xff1a;使用二维码引导无人机实现精准降落&#xff0c;首先需要实现对二维码的识别和定位&#xff0c;可以参考博客的二维码识别和定位内容。本小节主要是通过获取拿到的二维码位置&#xff0c;控制无人机全向的移动和降落&#xff0c;本小节再V1版本的基础上增加了动…