学习threejs,使用TWEEN插件实现动画

👨‍⚕️ 主页: gis分享者
👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅!
👨‍⚕️ 收录于专栏:threejs gis工程师


文章目录

  • 一、🍀前言
    • 1.1 ☘️THREE.PLYLoader PLY模型加载器
    • 1.1 ☘️tween.js
  • 二、🍀使用TWEEN插件实现动画
    • 1. ☘️实现思路
    • 2. ☘️代码样例


一、🍀前言

本文详细介绍如何基于threejs在三维场景中使用TWEEN插件实现动画,亲测可用。希望能帮助到您。一起学习,加油!加油!

1.1 ☘️THREE.PLYLoader PLY模型加载器

THREE.PLYLoader 用于加载和处理多边形文件格式(.ply) 3D模型文件的扩展。
PLY三维文件:
PLY全名为多边形档案(Polygon File Format),是一种开放的三维模型文件格式,以文本或二进制方式存储。它十分灵活,可以包含多种几何体类型、颜色、法线等属性,并且可扩展、易于解析和处理,具有跨平台兼容性和数据压缩支持,被广泛应用于计算机图形学、计算机辅助设计和三维扫描等领域。

1.1 ☘️tween.js

**补间动画(Tween):**是一种在动画中插值的方法,它根据开始值和结束值之间的缓动函数(Easing Function)来计算中间值,并在一定的时间内逐渐将属性值从初始状态过渡到目标状态,从而实现平滑的过渡效果。
**tween.js:**是一种JavaScript动画库,它可以帮助您轻松创建补间动画。它提供了许多内置的缓动函数和灵活的API,可以很容易地控制动画的速度、延迟和重复次数等参数。tween.js还支持多个动画同时播放,您可以使用它来创建复杂的动画序列。
具体使用方法可以参考tween.js简介

二、🍀使用TWEEN插件实现动画

1. ☘️实现思路

  • 1、初始化renderer渲染器
  • 2、初始化Scene三维场景
  • 3、初始化camera相机,定义相机位置 camera.position.set,设置相机方向camera.lookAt。
  • 4、初始化THREE.AmbientLight环境光源,scene场景加入环境光源,初始化THREE.PointLight点光源,设置点光源位置,设置点光源投影,scene添加点光源。
  • 5、加载几何模型:创建THREE.AxesHelper坐标辅助工具,创建PLYLoader加载器,调用load方法,在load回调中获取geometry集合体对象,创建THREE.Mesh对象,参入geometry和材质对象,生成mesh模型物体,设置旋转、大小、位置。定义initTween方法,实现模型局部坐标localPosition位置改变的补间动画,执行动画。scene场景加入mesh和THREE.AxesHelper坐标辅助工具。
  • 6、加入controls控制,加入stats监控器,监控帧数信息。

2. ☘️代码样例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>learn47(使用TWEEN插件实现动画)</title>
    <script src="lib/threejs/127/three.js-master/build/three.js"></script>
    <script src="lib/js/tween.min.js"></script>
    <script src="lib/threejs/127/three.js-master/examples/js/loaders/PLYLoader.js"></script>
    <script src="lib/threejs/127/three.js-master/examples/js/controls/OrbitControls.js"></script>
    <script src="lib/threejs/127/three.js-master/examples/js/libs/stats.min.js"></script>
    <script src="lib/threejs/127/three.js-master/examples/js/libs/dat.gui.min.js"></script>
</head>
<style type="text/css">
    html, body {
        margin: 0;
        height: 100%;
    }

    canvas {
        display: block;
    }

</style>
<body onload="draw();">
</body>
<script>
  var renderer
  var initRender = () => {
    renderer = new THREE.WebGLRenderer({antialias: true})
    renderer.setClearColor(0xffffff)
    renderer.setSize(window.innerWidth, window.innerHeight)
    document.body.appendChild(renderer.domElement)
  }
  var scene
  var initScene = () => {
    scene = new THREE.Scene()
  }
  var camera
  var initCamera = () => {
    camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000)
    camera.position.set(0, 0, 50)
    camera.lookAt(new THREE.Vector3(0, 0, 0))
  }
  var light
  var initLight = () => {
    scene.add(new THREE.AmbientLight(0x444444))
    light = new THREE.PointLight(0xffffff)
    light.position.set(0, 50, 50)
    light.castShadow = true
    scene.add(light)
  }
  var initModel = () => {
    var helper = new THREE.AxesHelper(50)
    scene.add(helper)
    var loader = new THREE.PLYLoader()
    loader.load('data/model/ply/Lucy100k.ply', geometry => {
      geometry.computeVertexNormals()
      var material = new THREE.MeshStandardMaterial({color: 0x0055ff})
      var mesh = new THREE.Mesh(geometry, material)
      mesh.rotation.y = Math.PI
      mesh.scale.set(0.02, 0.02, 0.02)
      scene.add(mesh)

      // 保存一份默认的定点信息
      var position = geometry.getAttribute('position').array
      geometry.localPosition = []
      for (var i = 0; i < position.length; i++) {
        geometry.localPosition.push(position[i])
      }
      initTween(geometry)
    })
  }
  var tween
  var initTween = (geometry) => {
    var position = {y: 1}
    tween = new TWEEN.Tween(position).to({y: 0}, 5000)
    tween.easing(TWEEN.Easing.Sinusoidal.InOut)

    var tweenBack = new TWEEN.Tween(position).to({y: 1}, 5000)
    tweenBack.easing(TWEEN.Easing.Sinusoidal.InOut)

    tween.chain(tweenBack)
    tweenBack.chain(tween)
    var count = geometry.getAttribute("position").count

    //获取一下模型的最矮处
    geometry.computeBoundingBox()
    var minY = geometry.boundingBox.min.y

    var onUpdate = function () {
      var y = this.y

      var arr = []
      for (var i = 0; i < count; i++) {
        arr.push(geometry.localPosition[i * 3])
        arr.push((geometry.localPosition[i * 3 + 1]-minY) * y)
        arr.push(geometry.localPosition[i * 3 + 2])
      }

      geometry.getAttribute("position").array = new Float32Array(arr)

      geometry.getAttribute("position").needsUpdate = true

    }

    tween.onUpdate(onUpdate)
    tweenBack.onUpdate(onUpdate)

    tween.start()
  }
  var stats
  var initStats = () => {
    stats = new Stats()
    document.body.appendChild(stats.dom)
  }
  var controls
  var initControls = () => {
    controls = new THREE.OrbitControls(camera, renderer.domElement)
    controls.enableDamping = true
  }
  var render = () => {
    TWEEN.update()
    renderer.render(scene, camera)
  }
  var onWindowResize = () => {
    camera.aspect = window.innerWidth / window.innerHeight
    camera.updateProjectionMatrix()
    render()
    renderer.setSize(window.innerWidth, window.innerHeight)
  }
  var animate = () => {
    render()
    stats.update()
    controls.update()
    requestAnimationFrame(animate)
  }
  var draw = () => {
    initRender()
    initScene()
    initCamera()
    initLight()
    initModel()
    initStats()
    initControls()

    animate()
    window.onresize = onWindowResize
  }
</script>
</html>

效果如下:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

世界坐标系、相机坐标系、图像物理坐标系、像素平面坐标系

坐标系及其转换在计算机视觉领域占据核心地位。理解如何从一个坐标系转换到另一个坐标系&#xff0c;不仅是理论上的需要&#xff0c;也是实际应用中不可或缺的技能。 一、世界坐标系的定义 世界坐标系是一个全局的坐标系统&#xff0c;用于定义场景中物体的位置。在这个坐标…

03-axios常用的请求方法、axios错误处理

欢迎来到“雪碧聊技术”CSDN博客&#xff01; 在这里&#xff0c;您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者&#xff0c;还是具有一定经验的开发者&#xff0c;相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导&#xff0c;我将…

Redis/Codis性能瓶颈揭秘:网卡软中断的影响与优化

目录 现象回顾 问题剖析 现场分析 解决方案 总结与反思 1.调整中断亲和性&#xff08;IRQ Affinity&#xff09;&#xff1a; 2.RPS&#xff08;Receive Packet Steering&#xff09;和 RFS&#xff08;Receive Flow Steering&#xff09;&#xff1a; 近期&#xff0c;…

openwebui使用

文章目录 1、feature2、安装使用2.1 安装过程2.2 安装好后 1、feature 可以加载多个大模型 同时回复 模型问答: 使用vLLM框架部署模型&#xff0c;再使用Open WebUI直接进行模型问答 多模型支持: 多模型回复比对&#xff08;Qwen2-72B-Instruct, llama3-70b-8192, mixtral-8x7…

汽车资讯新引擎:Spring Boot技术领航

3系统分析 3.1可行性分析 通过对本汽车资讯网站实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本汽车资讯网站采用SSM框架&#xff0c;JAVA作为开发语言&#…

应用系统开发(12) Zync中实现数字相敏检波

在 Xilinx Zynq 系列(如 Zynq-7000 或 Zynq UltraScale+)中实现数字相敏检波(DSP,Digital Synchronous Detection)可以通过硬件(PL部分,FPGA逻辑)和软件(PS部分,ARM Cortex-A 处理器)的协同工作来实现。以下是一个详细的设计方法,包括基本原理和 Zynq 的实现步骤。…

《译文》2024年11月数维杯国际大学生数学建模挑战赛题目

# 赛题正式发布 2024年第十届数维杯国际大学生数学建模挑战赛顺利开赛&#xff0c;竞赛开始时间为北京时间2024年11月15日09:00至北京时间2024年11月19日09:00&#xff0c;共计4天&#xff0c;竞赛题目正式发布&#xff0c;快来一起围观&#xff0c;你认为今年的哪个题目更具有…

apk反编译修改教程系列-----apk应用反编译中AndroidManifest.xml详细代码释义解析 包含各种权限 代码含义【二】

💝💝💝💝在上期博文中解析了一个常规apk中 AndroidManifest.xml的权限以及代码。应粉丝需求。这次解析一个权限较高的apk。这款apk是一个家长管控的应用。需求的各种权限较高。而且通过管控端可以设置控制端的app隐藏与否。 通过博文了解💝💝💝💝 1💝💝…

【UGUI】背包的交互01(道具信息跟随鼠标+道具信息面板显示)

详细程序逻辑过程 初始化物品栏&#xff1a; 在 Awake 方法中&#xff0c;通过标签找到提示框和信息面板。 循环生成10个背包格子&#xff0c;并为每个格子设置图标和名称。 为每个格子添加 UInterMaager232 脚本&#xff0c;以便处理交互事件。 关闭提示框和信息面板&#…

Docker: ubuntu系统下Docker的安装

安装依赖 操作系统版本 Ubuntu Kinetic 22.10Ubuntu Jammy 24.04 (LTS)Ubuntu Jammy 22.04 (LTS)Ubuntu Focal 20.04 (LTS)Ubuntu Bionic 18.04 (LTS) CPU架构支持 ARMx86_64 查看我们的系统版本信息 uname -a通过该命令查得cpu架构是x86_64的&#xff1b; cat /etc/*re…

Nacos 配置中心变更利器:自定义标签灰度

作者&#xff1a;柳遵飞 配置中心被广泛使用 配置中心是 Nacos 的核心功能之一&#xff0c;接入配置中心&#xff0c;可以实现不重启线上应用的情况下动态改变程序的运行期行为&#xff0c;在整个软件生命周期中&#xff0c;可以极大降低了软件构建及部署的成本&#xff0c;提…

基于RK3568J多网口电力可信物联网关解决方案

前言 随着工业物联网的普及和功能越来越强大&#xff0c;边缘计算网关应运而生。 边缘计算有效降低了云端服务器的负载、大大降低了带宽的占用&#xff0c;同时也为本地化的区域自治提供了便利条件。 边缘计算网关&#xff0c;完美地发挥了“边”与“端” 结合优势&#xff0c…

无人机飞手入门指南

无人机飞手入门指南旨在为初学者提供一份全面的学习路径和实践建议&#xff0c;帮助新手快速掌握无人机飞行技能并了解相关法规知识。以下是一份详细的入门指南&#xff1a; 一、了解无人机基础知识 1. 无人机构造&#xff1a;了解无人机的组成部分&#xff0c;如机身、螺旋桨…

网络传输:网卡、IP、网关、子网掩码、MAC、ARP、路由器、NAT、交换机

目录 网卡IP网络地址主机地址子网子网掩码网关默认网关 MACARPARP抓包分析 路由器NATNAPT 交换机 网卡 网卡(Network Interface Card&#xff0c;简称NIC)&#xff0c;也称网络适配器。 OSI模型&#xff1a; 1、网卡工作在OSI模型的最后两层&#xff0c;物理层和数据链路层。物…

多账号登录管理器(淘宝、京东、拼多多等)

目录 下载安装与运行 解决什么问题 功能说明 目前支持的平台 功能演示 登录后能保持多久 下载安装与运行 下载、安装与运行 语雀 解决什么问题 多个账号的快捷登录与切换 功能说明 支持多个电商平台支持多个账号的登录保持支持快捷切换支持导入导出支持批量删除支持…

你可以通过以下步骤找到并打开 **Visual Studio 开发者命令提示符**:

你可以通过以下步骤找到并打开 Visual Studio 开发者命令提示符&#xff1a; 1. 通过开始菜单查找 打开 开始菜单&#xff08;点击屏幕左下角的 Windows 图标&#xff09;。在搜索框中输入 Developer Command Prompt。你应该看到以下几种选项&#xff08;具体取决于你的 Visu…

版本控制【Git Bash】【Gitee】

目录 一、什么是版本控制&#xff1f; 二、版本控制的种类&#xff1a; 1、本地版本控制 2、集中版本控制 3、分布式版本控制 三、下载Git Bash 四、Git Bash 配置 五、Git Bash使用 1、切换目录&#xff1a;cd 2.查看当前文件路径&#xff1a;pwd 3.列出当前目录下文件…

大数据-226 离线数仓 - Flume 优化配置 自定义拦截器 拦截原理 拦截器实现 Java

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; Java篇开始了&#xff01; 目前开始更新 MyBatis&#xff0c;一起深入浅出&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff0…

【3D Slicer】的小白入门使用指南九

定量医学影像临床研究与实践 任务 定量成像教程 定量成像是从医学影像中提取定量测量的过程。 本教程基于两个定量成像的例子构建: - 形态学:缓慢生长肿瘤中的小体积变化 - 功能:鳞状细胞癌中的代谢活动 第1部分:使用变化跟踪模块测量脑膜瘤的小体积变化第2部分:使用PET标…

Visual Studio 圈复杂度评估

VisualStudio自带的有工具 之后就可以看到分析结果