@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 5 kB
JavaScript
/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.33/esri/copyright.txt for details.
*/
import t from"../../../Camera.js";import i from"../../../Viewpoint.js";import e from"../../../core/Error.js";import{onAbort as n,createAbortError as a}from"../../../core/promiseUtils.js";import{whenOnce as r}from"../../../core/reactiveUtils.js";import{applyAll as o}from"../camera/constraintUtils.js";import{applySurfaceCollisionConstraint as s,Mode as l}from"../camera/constraintUtils/surfaceCollision.js";import{State as c}from"./controllers/CameraController.js";import{isPointToPointAnimationController as h,PointToPointAnimationController as m}from"./controllers/PointToPointAnimationController.js";import{SurfaceCollisionCorrectionController as w}from"./controllers/SurfaceCollisionCorrectionController.js";import{externalToInternal as p}from"../support/cameraUtils.js";import{create as f}from"../support/viewpointUtils.js";class u{constructor(t,i,e){this._target=t,this._options=i,this.view=e,this.state="pending",this._animationController=null,this.promise=new Promise(((t,i)=>{this._resolveCallback=t,this._rejectCallback=i;const e=new AbortController;null!=this._options.signal&&n(this._options.signal,(()=>this.abort())),this._abortController=e,this._waitForReady()}))}_resolve(t){if("finished"!==this.state)return this.state="finished",this._resolveCallback(t)}_reject(t){if("finished"!==this.state)return this.state="finished",this._rejectCallback(t)}abort(t=!1){if(this._abortController.abort(),"wait-for-animation-finish"===this.state)!t&&null!=this._animationController&&this.view.state.cameraController===this._animationController&&this._animationController.running&&this._animationController.stopController();this._reject(a())}async _waitForReady(){if(this.state="wait-for-ready",!this.view.ready)try{await r((()=>this.view.ready),this._abortController.signal)}catch(t){return this._reject(t)}this._createViewPoint()}async _createViewPoint(){if("finished"!==this.state){this.state="wait-for-viewpoint",this._animationController=this._options.animate?this._getAnimationController():null;try{const t=await f(this.view,this._target,this._abortController.signal);if("finished"===this.state)return;const i=t?this._getCameraFromViewpoint(t):null;if(null==i)return;if(this._options.animate){if(null==this._animationController)return;this._startAnimation(i,this._animationController)}else this.view.stateManager.setStateCamera(i.camera,{applyConstraints:!i.isFullySpecified,positionAndOrientationOnly:!0,doNotCancelGoToOperation:!0}),this._resolve()}catch(t){this._reject(t)}}}_getCameraFromViewpoint(n){const a=!!(this._target instanceof i&&this._target.camera||this._target instanceof t),r=n.camera;if(null==r)return null;if(!this.view.stateManager.isCompatible(r)){const t=r.position,i=t&&t.spatialReference,n=i?i.wkid:"none",a=this.view.spatialReference?.wkid;return this._reject(new e("GotoAnimation:incompatible-spatialreference",`Resulting camera has an incompatible spatial reference (camera: ${n}, view: ${a})`,{camera:r})),null}const o=p(this.view,r);return null==o?(this._reject(new e("GotoAnimation:invalid-camera","Resulting camera is invalid")),null):{viewpoint:n,camera:o,isFullySpecified:a}}_startAnimation(t,i){this.state="wait-for-animation-finish";const n=i.viewAnimation;if(null==n)return void this._reject(new e("GotoAnimation:missing-animation","Unreachable code in view.stateManager"));if(n.update(t.viewpoint,"running"),!i.running||null==i.viewAnimation||i.viewAnimation.target!==t.viewpoint||this.view.state.cameraController!==i)return this.abort();let a;t.isFullySpecified?(a=new w({view:this.view,desiredCamera:t.camera}),s(this.view,t.camera,l.EYE_AND_CENTER)):o(this.view,t.camera),i.begin(t.camera,this._options);const r=()=>{const e=this.view.state.cameraController;a&&(e&&e.running?h(e)&&null!=e.viewAnimation&&e.viewAnimation.target===t.viewpoint&&(this.view.state.cameraController=a):null!=i.viewAnimation&&i.viewAnimation.target===t.viewpoint&&i.state===c.Finished&&(this.view.state.cameraController=a))},m=t=>{if(null!=this.view.state)switch(i.state){case c.Finished:switch(this.state){case"pending":case"wait-for-ready":case"wait-for-viewpoint":case"wait-for-animation-finish":this._resolve()}break;case c.Ready:case c.Rejected:case c.Running:case c.Stopped:switch(this.state){case"pending":case"wait-for-ready":case"wait-for-viewpoint":case"wait-for-animation-finish":this._reject(t)}}};n.when(r,(t=>m(t))),i.asyncResult={resolve:()=>m(),reject:t=>m(t)}}_getAnimationController(){let t=null,i=null;const n=this.view.state.cameraController;return h(n)&&(n.updateStateFromViewAnimation(),n.running&&(t=n,i=t.viewAnimation)),null==t&&(t=new m({view:this.view,mode:"animation"}),i=t.viewAnimation,this.view.state.switchCameraController(t),t.state===c.Rejected)?(i?.stop(),this._reject(new e("GotoAnimation:goto-cannot-interrupt","Cannot start an animation while interacting")),null):t}}export{u as GoToOperation};