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>

结果

相关推荐
dlnu201525062215 分钟前
ssr实现方案
前端·javascript·ssr
Kisorge1 小时前
【C语言】指针数组、数组指针、函数指针、指针函数、函数指针数组、回调函数
c语言·开发语言
轻口味2 小时前
命名空间与模块化概述
开发语言·前端·javascript
前端小小王2 小时前
React Hooks
前端·javascript·react.js
迷途小码农零零发3 小时前
react中使用ResizeObserver来观察元素的size变化
前端·javascript·react.js
晓纪同学3 小时前
QT-简单视觉框架代码
开发语言·qt
威桑3 小时前
Qt SizePolicy详解:minimum 与 minimumExpanding 的区别
开发语言·qt·扩张策略
飞飞-躺着更舒服3 小时前
【QT】实现电子飞行显示器(简易版)
开发语言·qt
明月看潮生3 小时前
青少年编程与数学 02-004 Go语言Web编程 16课题、并发编程
开发语言·青少年编程·并发编程·编程与数学·goweb
明月看潮生3 小时前
青少年编程与数学 02-004 Go语言Web编程 17课题、静态文件
开发语言·青少年编程·编程与数学·goweb