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>

结果

相关推荐
惜.己1 分钟前
使用python的读取xml文件,简单的处理成元组数组
xml·开发语言·python·测试工具
sunbyte3 分钟前
50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | GoodCheapFast(Good - Cheap - Fast三选二开关)
前端·javascript·css·vue.js·tailwindcss
apihz24 分钟前
域名WHOIS信息查询免费API使用指南
android·开发语言·数据库·网络协议·tcp/ip
coding随想38 分钟前
掌控网页的魔法之书:JavaScript DOM的奇幻之旅
开发语言·javascript·ecmascript
爱吃烤鸡翅的酸菜鱼1 小时前
IDEA高效开发:Database Navigator插件安装与核心使用指南
java·开发语言·数据库·编辑器·intellij-idea·database
然我1 小时前
不用 Redux 也能全局状态管理?看我用 useReducer+Context 搞个 Todo 应用
前端·javascript·react.js
前端小巷子1 小时前
Web 实时通信:从短轮询到 WebSocket
前端·javascript·面试
心情好的小球藻2 小时前
Python应用进阶DAY9--类型注解Type Hinting
开发语言·python
惜.己2 小时前
使用python读取json数据,简单的处理成元组数组
开发语言·python·测试工具·json
Y4090012 小时前
C语言转Java语言,相同与相异之处
java·c语言·开发语言·笔记