06-ArcGIS For JavaScript-requestAnimationFrame动画渲染

文章目录

概述

本节主要讲解与时间相关的三个方法setTimeout()、setInterval()和requestAnimationFrame(),这三个方法都属于浏览器的window对象的方法,这三个函数能够更好的服务于2Dcanvas动画、WebGL动画等方面。

setInterval()与setTimeout()

setInterval()函数为周期定时器,可以选择每过一个固定时间段调用一次指定函数。如下,每100毫秒调用一次回调函数:

javascript 复制代码
setInterval(function(){
	console.log("It is setInterval");
}, 100);

setTimeout()为倒计时定时器,例如可以指定100毫秒后调用回调函数,然后结束当前定时。

javascript 复制代码
setTimeout(function(){
	console.log("It is setTimeout");
}, 100);

这两个方法都是可以人为的指定回调函数被调用的时间。

如果不想使用该定时器的时候,可以选择取消。方法如下:

javascript 复制代码
clearInterval();  //取消setInterval()设置的定时
clearTimeout();  //取消setTimeout()设置的定时器

requestAnimationFrame()

requestAnimationFrame主要用途是按帧对网页进行重绘,让各种网页动画效果(DOM动画、Canvas动画、SVG动画、WebGL动画)能够有一个统一的刷新机制,从而节省系统资源,提高系统性能,改善视觉效果。

调用方式如下:

javascript 复制代码
function callback(){
	console.log(requestAnimationFrame)
	requestAnimationFrame(callback)
}
requestAnimationFrame(callback)

requestAnimationFrame在ArcGIS For JavaScript的应用

javascript 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Document</title>
   <link rel="stylesheet" href="https://js.arcgis.com/4.30/esri/themes/light/main.css" />
   <script src="https://js.arcgis.com/4.30/"></script>

   <style>
       html,
       body,
       #viewDiv {
           margin: 0;
           padding: 0;
           height: 100%;
           width: 100%;
       }
   </style>

   <script>
       require([
           "esri/geometry/Mesh",
           "esri/views/SceneView",
           "esri/Map",
           "esri/Graphic",
           "esri/symbols/MeshSymbol3D",
           "esri/symbols/FillSymbol3DLayer",
           "esri/geometry/Point",
           "esri/core/reactiveUtils"
       ], (Mesh, SceneView, Map, Graphic, MeshSymbol3D, FillSymbol3DLayer, Point, reactiveUtils) => {
           let waterHeight = 422;
           async function createMeshGLTF(glbUrl, point, i = [0, 0, 0], r = 1, n = 0) {

               const s = await Mesh.createFromGLTF(point, glbUrl, {
                   vertexSpace: "georeferenced"
               }), o = i.map(h => h * r);

               return s.scale(r),
                   s.offset(o[0], o[1], o[2]),
                   s.rotate(0, 0, n),
                   new Graphic({
                       geometry: s,
                       symbol: new MeshSymbol3D({
                           symbolLayers: [new FillSymbol3DLayer]
                       })
                   })
           }

           let map = new Map({
               basemap: 'satellite'
           })

           let view = new SceneView({
               container: "viewDiv",
               map
           })

           let animatingPinpoint = true;

           view.when(async function () {

               let sailBoat = await createMeshGLTF("./pinpoint.glb", new Point({
                   x: -1354454634895185e-8,
                   y: 4307521548889681e-9,
                   z: waterHeight,
                   spatialReference: {
                       wkid: 102100
                   }

               }));
               view.graphics.add(sailBoat);
               view.extent = sailBoat.geometry.extent;

               function setupCameraHeadingListener() {
                   reactiveUtils.watch(() => Math.round(view.camera.heading), e => {
                       const i = sailBoat.geometry;
                       i.transform.rotationAngle = -e + 20,
                           i.transform.rotationAxis = [0, 0, 1]
                   }
                       , {
                           initial: !0
                       })
               }

               let startTime = Date.now() / 1000;

               function animatePinpoint(graphic) {
                   let startTime = null;
                   animatingPinpoint = true;
                   const animate = (elapsedTime) => {
                       if (!startTime) {
                           startTime = elapsedTime;
                       }
                       const timeDif = (elapsedTime - startTime) / 1000;
                       const scale = 1 + Math.abs(Math.sin(timeDif * 2));
                       const geometry = graphic.geometry;
                       geometry.transform ??= new MeshTransform();
                       geometry.transform.scale = [scale, scale, scale];
                       if (animatingPinpoint) {
                           requestAnimationFrame(animate);
                       }
                   }
                   requestAnimationFrame(animate);
               }

               function stopAnimatingPinpoint() {
                   animatingPinpoint = false;
               }

               animatePinpoint(sailBoat);
               setupCameraHeadingListener();
           })
       })
   </script>
</head>

<body>
   <div id="viewDiv"></div>
</body>

</html>

结果

相关推荐
时光の尘12 分钟前
C语言菜鸟入门·关键字·float以及double的用法
运维·服务器·c语言·开发语言·stm32·单片机·c
以后不吃煲仔饭26 分钟前
Java基础夯实——2.7 线程上下文切换
java·开发语言
进阶的架构师27 分钟前
2024年Java面试题及答案整理(1000+面试题附答案解析)
java·开发语言
前端拾光者31 分钟前
利用D3.js实现数据可视化的简单示例
开发语言·javascript·信息可视化
程序猿阿伟32 分钟前
《C++ 实现区块链:区块时间戳的存储与验证机制解析》
开发语言·c++·区块链
傻啦嘿哟1 小时前
如何使用 Python 开发一个简单的文本数据转换为 Excel 工具
开发语言·python·excel
大数据编程之光1 小时前
Flink Standalone集群模式安装部署全攻略
java·大数据·开发语言·面试·flink
初九之潜龙勿用1 小时前
C#校验画布签名图片是否为空白
开发语言·ui·c#·.net
Dola_Pan1 小时前
C语言:数组转换指针的时机
c语言·开发语言·算法
ExiFengs1 小时前
实际项目Java1.8流处理, Optional常见用法
java·开发语言·spring