文章目录
-
- 概述
- setInterval()与setTimeout()
- requestAnimationFrame()
- [requestAnimationFrame在ArcGIS For JavaScript的应用](#requestAnimationFrame在ArcGIS For JavaScript的应用)
- 结果
概述
本节主要讲解与时间相关的三个方法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>