在Three.js中动画 简单案例

news2024/11/27 22:41:57

      在Three.js中,动画是指在场景中创建和控制对象的运动和变化。模型是指通过Three.js加载的3D对象,可以是几何体、网格或复杂的模型文件(如.obj或.gltf)。动画可以存在于模型中,也可以单独定义。

编辑关键帧:
关键帧动画是通过关键帧KeyframeTrack和剪辑AnimationClip两个API来完成,实际开发中如果需要制作一个复杂三维模型的帧动画,比如一个人走路、跑步等动作,一般情况是美术通过3dmax、blender等软件编辑好,不需要程序员用代码实现。

播放关键帧
通过操作AnimationAction和混合器AnimationMixer两个API播放已有的帧动画数据。

混合器THREE.AnimationMixer()的参数是案例代码中编写的两个网格模型的父对象group,实际开发中参数Group也可以是你加载外部模型返回的模型对象。

播放关键帧动画的时候,注意在渲染函数render()中执行mixer.update(渲染间隔时间)告诉帧动画系统Threejs两次渲染的时间间隔,获得时间间隔可以通过Threejs提供的一个时钟类Clock实现。

总结
1.需要一个父级的组,在其中加入网格对象,命名网格对象
2.编辑关键帧
(1) 运用KeyframeTrack和剪辑AnimationClip两个API
(2) new THREE.KeyframeTrack可以在关键帧中设置位置,颜色,缩放等属性,用时间点和变化的数值
(3) 设置播放时间duration
(4)创建剪辑clip对象,命名,持续时间,关键帧。
3.播放关键帧
操作AnimationAction和混合器AnimationMixer两个API播放
(1) new THREE.AnimationMixer(group);播放组中所有子对象的帧动画
(2)clip作为参数,通过混合器clipAction方法返回一个操作对象AnimationAction
(3)通过操作Action设置播放方式,调节播放速度,是否循环
(4)开始播放
4.渲染
(1)创建时钟对象
(2)执行渲染操作,请求再次渲染,渲染下一帧,更新混合器相关时间。

效果
 

源码: 



<template>
  <div ref="container"></div>
</template>


<script setup lang="ts">
//导入资源
import { ref, onMounted, onUnmounted } from 'vue';
import * as THREE from 'three';

//引入加载器
import {RGBELoader} from "three/examples/jsm/loaders/RGBELoader";
import {OrbitControls} from "three/examples/jsm/controls/OrbitControls";
import {GLTFLoader} from "three/examples/jsm/loaders/GLTFLoader";

const container =  ref(null);
let scene = undefined;
let camera = undefined;
let renderer = undefined;
let controls = undefined; //控制器
const model = ref(null);
const mixer = ref(null);
const clock = ref(null);

//加载完毕后执行
onMounted(() => {

    //渲染器
    renderer = new THREE.WebGLRenderer({
      antialias:true,
    // alpha:true
    });
    renderer.setSize( window.innerWidth, window.innerHeight );
    container.value.appendChild(renderer.domElement);

    //场景
    scene = new THREE.Scene();
    scene.background = new THREE.Color( 0xf0f0f0 );

    //相机
    camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 10000 );
    camera.position.set(15,15,15);
    //  camera.lookAt(new THREE.Vector3(0,0,0));
    camera.lookAt( scene.position );
    scene.add(camera);

    //灯光
    var light = new THREE.DirectionalLight( 0xffffff, 1 );
    light.position.set( 3, 1, 1 ).normalize();//向量属性向量转换为单位向量,方向设置为和原向量相同,长度为1
    light.intensity=1.5;//强度
    scene.add(light);


    //动画网格模型
    var material1 = new THREE.MeshLambertMaterial({
      color:0x0000ff
    });
    var geometry1 = new THREE.BoxGeometry(5,2,3);
    var mesh1 = new THREE.Mesh(geometry1, material1);
    mesh1.name="Box";
    mesh1.position.set(0,2,0);

    var material2 = new THREE.MeshLambertMaterial({
      color:0x00ff00
    });
    var geometry2 = new THREE.SphereGeometry(1, 50, 50);
    var mesh2 = new THREE.Mesh(geometry2, material2);
    mesh2.name="Sphere";
    mesh2.position.set(0,5,0);

    var group = new THREE.Group();
    group.add(mesh1,mesh2);
    scene.add(group);

    controls = new OrbitControls(camera, renderer.domElement);
    controls.update();


    //编辑group子对象网格模型mesh1和mesh2的帧动画数据
    //创建名为Box对象的关键帧数据
    var times = [0, 10];//关键帧事件数组,离散时间点序列
    var values = [0,0,0,10,0,0]//与时间点对应的值组成的数组
    //创建位置关键帧对象:0时刻对应位置0,0,0,10时刻对应位置150,0,0
    var posTrack = new THREE.KeyframeTrack('Box.position', times, values);
    //创建燕娥关键帧对象:10时刻对应颜色1,0,0    20时刻对应颜色0,0, 1
    var colorKF = new THREE.KeyframeTrack('Box.material.color', [10, 20], [1, 0, 0, 0, 0, 1]);
    // 创建名为Sphere对象的关键帧数据,从0-20时间段,尺寸scale缩放3倍
    var scaleTrack = new THREE.KeyframeTrack('Sphere.scale', [0, 20], [1, 1, 1, 3, 3, 3]);

    //duration 决定了默认的播放时间,一般取所有帧动画的最大事件
    //duration偏小,帧动画数据无法播放完,偏大,播放完帧动画会继续空播放

    var duration = 20;

    //多个帧动画座位元素创建一个剪辑clip对象,命名“default”,持续时间20
    var clip = new THREE.AnimationClip("default", duration, [posTrack, colorKF, scaleTrack]);

    // 播放编辑好的关键帧

    //group作为混合器的参数,可以播放group中所有子对象的帧动画
    var mixer = new THREE.AnimationMixer(group);
    //剪辑clip作为参数,通过混合器clipAction方法返回一个操作对象AnimationAction
    var AnimationAction = mixer.clipAction(clip);
    //通过操作Action设置播放方式
    AnimationAction.timeScale = 20;//默认1,可以调节播放速度
    // AnimationAction.loop = THREE.LoopOnce; //不循环播放
    AnimationAction.play();//开始播放

    //创建一个时钟对象Clock
    var clock = new THREE.Clock();

    // 渲染场景
    const animate = () => {
      requestAnimationFrame(animate);
      renderer.render(scene, camera);

      //clock.getDelta()方法获得两帧的时间间隔
      //更新混合器相关时间
      mixer.update(clock.getDelta());
    };

  animate();

})
</script>



<style scoped>

</style>

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

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

相关文章

OV2210 小封装过压/过流保护芯片 适用于小电流的便携产品

OV2210 是一款过压过流保护芯片&#xff0c;芯片内置高耐压保护 MOSFET &#xff0c;最高耐压达 30V &#xff0c;芯 片过压保护电压固定为 6.2V &#xff0c;过流保护固定为 1.5A &#xff0c;芯片会持续检测输入电压和电流&#xff0c;一旦发生过压和过流&#xff0c;立…

Geotrust证书

GeoTrust是著名的证书颁发机构DigiCert的品牌。GeoTrustSSL产品在Internet上提供从基本域名验证到扩展验证SSL标准支持的最高级验证的安全性。 GeoTrust OV&#xff08;组织验证&#xff09;证书验证域所有权和组织的存在。在颁发证书之前&#xff0c;会检查该组织在公共数据库…

【C语言学习】22 -文件管理

文章目录 1 remove()1.1 函数原型1.2 参数1.3 返回值1.4 示例 1 remove() 1.1 函数原型 remove()&#xff1a;删除文件&#xff0c;函数原型如下&#xff1a; int remove(const char *filename);1.2 参数 remove()函数只有一个参数filename&#xff1a; 参数filename是一个…

软件测试突破技术瓶颈之python接口自动化- DDT数据驱动测试

简单介绍 ​ DDT&#xff08;Date Driver Test&#xff09;&#xff0c;所谓数据驱动测试&#xff0c;简单来说就是由数据的改变从而驱动自动化测试的执行&#xff0c;最终引起测试结果的改变。通过使用数据驱动测试的方法&#xff0c;可以在需要验证多组数据测试场景中&#x…

手机也能搭建个人博客?安卓Termux+Hexo搭建属于你自己的博客网站

文章目录 前言 1.安装 Hexo2.安装cpolar3.远程访问4.固定公网地址 前言 Hexo 是一个用 Nodejs 编写的快速、简洁且高效的博客框架。Hexo 使用 Markdown 解析文章&#xff0c;在几秒内&#xff0c;即可利用靓丽的主题生成静态网页。 下面介绍在Termux中安装个人hexo博客并结合…

【Python3】【力扣题】242. 有效的字母异位词

【力扣题】题目描述&#xff1a; 【Python3】代码&#xff1a; 1、解题思路&#xff1a;若字符串长度相同&#xff0c;依次遍历元素&#xff0c;比较两个字符串的该元素个数是否相同。【耗时长】 知识点&#xff1a;len(...)&#xff1a;获取序列&#xff08;字符串、列表等&…

Mysql 不同存储引擎数据文件的形式详解

目录 MyISAM MERGE InnoDB Memory Archive CSV BLACKHOLE MySQL 中的每一个数据表在磁盘上至少被表示为一个文件&#xff0c;即存放着该数据表结构定义的 .frm 文件。不同的存储引擎还有其它用来存放数据和索引信息的文件。 从 MySQL 8.0 版本开始&#xff0c;frm 表结构…

Python进行多线程爬取数据通用模板

首先&#xff0c;我们需要导入所需的库&#xff0c;包括requests和BeautifulSoup。requests库用于发送HTTP请求&#xff0c;BeautifulSoup库用于解析HTML文档。 import requests from bs4 import BeautifulSoup然后&#xff0c;我们需要定义一个函数来发送HTTP请求并返回响应。…

日常问题定位-网口不通

发现协商的Advertised link modes没有结果 自动协商不成功&#xff0c;手动协商无报错 可以通了

芯片洁净间的等级是如何划分的

芯片生产是一个非常精细且需要无尘的环境&#xff0c;这种环境通常被称为超净室或洁净室。洁净室是一个专门设计的封闭空间&#xff0c;其中空气中的颗粒物已被高度复杂的过滤系统限制或去除。通常&#xff0c;在大学的实验室中&#xff0c;我们最常接触的是百级间&#xff0c;…

教育照明灯具品牌,专业教育护眼台灯推荐

LED灯作为一种新型的照明产品&#xff0c;具有节能、环保、寿命长等优点&#xff0c;受到越来越多的人们的青睐。但是&#xff0c;市面上的LED灯品牌琳琅满目&#xff0c;让人眼花缭乱。那么&#xff0c;LED灯什么牌子好呢&#xff1f;下面我们来推荐五大品牌。 1.书客护眼台灯…

国内外常见PLC发展现状分析

在聊PLC的市场格局和国产发展现状之前&#xff0c;我们先来简单了解一下PLC的作用。所谓PLC&#xff0c;你可以把它当成是一台小型电脑&#xff0c;只不过这台电脑是专用于工业领域&#xff0c;用来控制各种机械或生产的过程。比如说我们身上穿的衣服&#xff0c;都是由机器缝制…

爱上C语言:操作符详解(上)

&#x1f680; 作者&#xff1a;阿辉不一般 &#x1f680; 你说呢&#xff1a;生活本来沉闷&#xff0c;但跑起来就有风 &#x1f680; 专栏&#xff1a;爱上C语言 &#x1f680;作图工具&#xff1a;draw.io(免费开源的作图网站) 如果觉得文章对你有帮助的话&#xff0c;还请…

Ubuntu22.04 下 NFS 相关问题与完整配置(客户机 MacOS)

categories: [Linux-Shell] tags: Linux NFS 写在前面 最近折腾一下 NFS, 先白嫖一顿华子云的 1 个月服务器, 2C4G 感觉不错了, 但NFS 配置起来还是有点难度, 主要还是随机分配的端口配置方面比较恶心. server环境: 华为云 2C4G Ubuntu22.04 client环境: MacOS M1 with brew …

vue3+vite+ts使用Element+Plus

1.安装ElementPlus npm install element-plus --save 2.在index.html中加入 <head><!-- Import style --><link rel"stylesheet" href"//unpkg.com/element-plus/dist/index.css" /><!-- Import Vue 3 --><script src"…

代码随想录算法训练营第四十八天 | LeetCode 121. 买卖股票的最佳时机、122. 买卖股票的最佳时机 II

代码随想录算法训练营第四十八天 | LeetCode 121. 买卖股票的最佳时机、122. 买卖股票的最佳时机 II 文章链接&#xff1a;买卖股票的最佳时机 买卖股票的最佳时机 II 视频链接&#xff1a;买卖股票的最佳时机 买卖股票的最佳时机 II 1. LeetCode 121. 买卖股票的最佳时机 1.1…

centos7下安装主从仲裁三台结构的MongoDB 7.0.4

安装手册英文版在这里 https://www.mongodb.com/docs/v7.0/tutorial/install-mongodb-on-red-hat/ 我的安装过程 1&#xff09;基础安装 1、创建 /etc/yum.repos.d/mongodb-org-7.0.repo文件 下面的代码复制到这个文件中&#xff0c;保存 [mongodb-org-7.0] nameMongoDB Re…

RBF、GMM、FUZZY

感觉这三种方法有联系&#xff0c;RBF用多个加权高斯拟合值函数&#xff0c;GMM用多个加权高斯拟合联合分布函数&#xff0c;GMM的加权相比于概率更像FUZZY里的隶属度&#xff0c;并且FUZZY的不同规则实现的就是一定程度的聚类。 一、RBF 资料&#xff1a;https://blog.csdn…

JAVA使用Grafana和Loki抓取聚合日志

Grafana和Loki抓取聚合日志 适用范围配置常见问题参考文章 适用范围 Grafana是日志看板Loki是Grafana的一个插件用于收集日志promtail是Loki配套的抓取工具&#xff0c;放在目标服务器抓取日志 配置 日志服务器安装Grafana&#xff0c;傻瓜式下一步日志服务器启动Loki&#…