@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 12.4 kB
JavaScript
/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.32/esri/copyright.txt for details.
*/
import{_ as t}from"../../../../../chunks/tslib.es6.js";import e from"../../../../../core/Accessor.js";import{multiplyOpacityToUnitRGBA as a}from"../../../../../core/colorUtils.js";import{cyclicalPI as o}from"../../../../../core/Cyclical.js";import i from"../../../../../core/Evented.js";import"../../../../../core/has.js";import{clamp as r,rad2deg as s}from"../../../../../core/mathUtils.js";import{destroyMaybe as n}from"../../../../../core/maybe.js";import{watch as l,initial as c}from"../../../../../core/reactiveUtils.js";import{addFrameTask as d}from"../../../../../core/scheduling.js";import{createScreenPointArray as h}from"../../../../../core/screenUtils.js";import{property as u}from"../../../../../core/accessorSupport/decorators/property.js";import"../../../../../core/Logger.js";import"../../../../../core/RandomLCG.js";import{subclass as p}from"../../../../../core/accessorSupport/decorators/subclass.js";import{fromRotation as m,fromScaling as g,multiply as f,scale as _,rotate as D}from"../../../../../core/libs/gl-matrix-2/math/mat4.js";import{create as S}from"../../../../../core/libs/gl-matrix-2/factories/mat4f64.js";import{i as v,d as M,l as b,s as j,e as y,g as R}from"../../../../../chunks/vec32.js";import{clone as w,fromValues as A}from"../../../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{fromPositionAndNormal as T,create as I,getNormal as O}from"../../../../../geometry/support/plane.js";import{wrap as C,distance2 as E}from"../../../../../geometry/support/ray.js";import{sv3d as k,sm4d as F}from"../../../../../geometry/support/vectorStacks.js";import{Manipulator3D as P}from"../../Manipulator3D.js";import{calculateInputRotationTransform as U}from"../../manipulatorUtils.js";import{RenderObject as L}from"../../RenderObject.js";import{screenToRenderPlane as x}from"../dragEventPipeline3D.js";import{ManipulatorType as N}from"../ManipulatorType.js";import{ringIndicatorDelayMs as H,rotateIndicatorDirectionBuffer as G,scaleIndicatorDirectionBuffer as z,rotateIndicatorArrowPlacementPercentage as B,ringThickness as q,dragThresholdPx as J,ringRadius as K,innerIndicatorRadius as Q,outerIndicatorRadius as V,ringHeight as W,rotateIndicatorArrowTipRadius as X,rotateIndicatorArrowTipLength as Y,scaleIndicatorOffset1 as Z,scaleIndicatorOffset2 as $,indicatorThickness as tt,geometrySegments as et,rotateIndicatorArcLength as at,ringResetAnimationSpeedFactor as ot,scaleIndicatorArcLength as it}from"../manipulations/config.js";import{CullFaceOptions as rt}from"../../../webgl-engine/lib/basicInterfaces.js";import{createExtrudedTriangle as st,transformInPlace as nt,createPathExtrusionGeometry as lt}from"../../../webgl-engine/lib/GeometryUtil.js";import{RenderOccludedFlag as ct}from"../../../webgl-engine/lib/Material.js";import{ColorMaterial as dt}from"../../../webgl-engine/materials/ColorMaterial.js";import{createManipulatorDragEventPipeline as ht}from"../../../../interactive/dragEventPipeline.js";import{ManipulatorStateCustomFlags as ut,ManipulatorStateFlags as pt}from"../../../../interactive/interfaces.js";var mt;!function(t){t.ScaleIn=ut.Custom2,t.ScaleOut=ut.Custom3,t.RotateLeft=ut.Custom4,t.RotateRight=ut.Custom5,t.Unlocked=ut.Custom7,t.DelayedFocused=ut.Custom8,t.TouchInput=ut.Custom12}(mt||(mt={}));let gt=class extends e{get angle(){return this.adapter.angle}get scale(){return this.adapter.scale}set location(t){this._ringManipulator.location=t}set elevationAlignedLocation(t){this._ringManipulator.elevationAlignedLocation=t}get grabbing(){return this._ringManipulator.grabbing}set interactive(t){this._ringManipulator.interactive=t}get updating(){return!!this._activeAnimation}constructor(t){super(t),this.mode=null,this._scaleRotateDragData=null,this._activeAnimation=null,this._ringIndicatorDelayMs=H,this.events=new i,this.getFocused=()=>this._ringManipulator.focused,this.getScale=()=>"scale"===this._scaleRotateDragData?.mode?this.adapter.scale:1}initialize(){this._createManipulator(),this._updateDragState(),this._updateManipulatorTransform(),this.addHandles([l((()=>{const{adapter:t}=this;return[t.angle,t.scale]}),(()=>this._updateManipulatorTransform()))])}destroy(){this._activeAnimation?.frameTask.remove(),this._activeAnimation=null,this.tool.manipulators.remove(this._ringManipulator),this._ringManipulator=null}startAnimation(t){this.cancelActiveAnimation(),t.start();const e=d({update:({deltaTime:e})=>{t.update(e)&&this.cancelActiveAnimation()}});this._activeAnimation={...t,frameTask:e}}cancelActiveAnimation(){this._activeAnimation?.frameTask.remove(),this._activeAnimation=n(this._activeAnimation)}forEachManipulator(t){t(this._ringManipulator,N.SCALE_ROTATE)}_createManipulator(){const t=this._createRingManipulator();this._ringManipulator=t,this.tool.manipulators.add(t);const e=this.tool.object,a=ht(t,((t,a,i)=>{this._scaleRotateDragData=null;const n=this.adapter.startInteraction(),l={mode:"none",origin:w(t.renderLocation),initialAngle:this.adapter.angle,angle:0,angleDir:0,scaleDir:0};this._scaleRotateDragData=l,this._updateDragState();const c=k.get();this.tool.view.renderCoordsHelper.worldUpAtPosition(t.renderLocation,c),a.next(x(this.tool.view,T(t.renderLocation,c,I()))).next((t=>{const a=O(t.plane),i=U(t.renderStart,t.renderEnd,l.origin,a),c=o.shortestSignedDiff(l.angle,i);l.angleDir=r(l.angleDir+c,-.3,G),l.angle=i;const d=ft(l,t),h=d-this.adapter.scale;if(l.scaleDir=r(l.scaleDir+h,-.2,z),this._onScaleChanged(),"none"===l.mode){const a=this.mode||_t(t,t.plane,l.origin,this.tool.view.state.camera);if(null!=a){switch(a){case"rotate":this.tool.events.emit("rotate-start",{object:e,angle:0}),this.tool.events.emit("record-undo",{updates:[this.adapter.createUndoRecord()]});break;case"scale":this.tool.events.emit("scale-start",{object:e,xScale:1,yScale:1}),this.tool.events.emit("record-undo",{updates:[this.adapter.createUndoRecord()]})}l.mode=a}}switch(l.mode){case"rotate":n.state.angle=l.initialAngle+i;break;case"scale":n.state.scale=d,this._onScaleChanged()}switch(this._updateDragState(),this._updateManipulatorTransform(),t.action){case"start":case"update":switch(l.mode){case"rotate":this.tool.events.emit("rotate",{object:e,angle:s(l.angle)});break;case"scale":this.tool.events.emit("scale",{object:e,xScale:d,yScale:d})}break;case"end":switch(l.mode){case"rotate":this.tool.events.emit("rotate-stop",{object:e,angle:s(l.angle)});break;case"scale":this.tool.events.emit("scale-stop",{object:e,xScale:d,yScale:d})}}return"end"===t.action&&(this.startAnimation(vt(this,(()=>this._onScaleChanged()))),this._scaleRotateDragData=null,this._updateDragState(),n.done()),t})),i.next((()=>{if(n.cancel(),null!=this._scaleRotateDragData){switch(this._scaleRotateDragData.mode){case"none":break;case"rotate":this.tool.events.emit("rotate-stop",{object:e,angle:0});break;case"scale":this.tool.events.emit("scale-stop",{object:e,xScale:1,yScale:1})}this.startAnimation(vt(this,(()=>this._onScaleChanged()))),this._scaleRotateDragData=null,this._updateDragState()}}))}));this.addHandles([a,t.events.on("focus-changed",(t=>{"focus"===t.action?this.startAnimation(Mt(this,(()=>this._updateDelayedFocusedState()),{delayMs:this._ringIndicatorDelayMs})):this._updateDelayedFocusedState()})),t.events.on("immediate-click",(t=>{t.stopPropagation()})),l((()=>this.tool.object.visible),(t=>this._ringManipulator.available=t),c)])}_onScaleChanged(){this.events.emit("scale-changed"),this._updateManipulatorTransform()}_updateDelayedFocusedState(){this._ringManipulator.updateStateEnabled(mt.DelayedFocused,this.getFocused())}_updateDragState(){if(this._ringManipulator.updateStateEnabled(mt.Unlocked,!(null!=this._scaleRotateDragData&&"none"!==this._scaleRotateDragData?.mode)),null!=this._scaleRotateDragData)switch(this._scaleRotateDragData.mode){case"rotate":this._ringManipulator.updateStateEnabled(mt.ScaleIn|mt.ScaleOut,!1),this._ringManipulator.updateStateEnabled(mt.RotateLeft,this._scaleRotateDragData.angleDir<0),this._ringManipulator.updateStateEnabled(mt.RotateRight,this._scaleRotateDragData.angleDir>=0);break;case"scale":this._ringManipulator.updateStateEnabled(mt.RotateLeft|mt.RotateRight,!1),this._ringManipulator.updateStateEnabled(mt.ScaleIn,this._scaleRotateDragData.scaleDir<0),this._ringManipulator.updateStateEnabled(mt.ScaleOut,this._scaleRotateDragData.scaleDir>=0)}else this._ringManipulator.updateStateEnabled(mt.ScaleIn|mt.ScaleOut|mt.RotateLeft|mt.RotateRight,!1)}_updateManipulatorTransform(){const t=m(F.get(),this.adapter.angle,A(0,0,1));if(null==t)return;const e=this.getScale(),a=g(F.get(),v(k.get(),e,e,e));this._ringManipulator.modelTransform=f(F.get(),a,t)}_createRingManipulator(){const t=(t,e,a)=>{const o=[],i=Math.ceil(et*(e-t)/(2*Math.PI));for(let r=0;r<i+1;r++){const s=t+r*(e-t)/i;o.push(A(a*Math.cos(s),a*Math.sin(s),0))}return o},e=e=>t(0,2*Math.PI,e),a=t=>[[-t/2,0],[t/2,0],[t/2,W/2],[-t/2,W/2]],o=this._createMaterial(1),i=(t,e,i=o)=>lt(i,a(e),t,[],[],!1),r=e(K),s=i(r,q),n={left:new Array,right:new Array},l=[];for(let w=0;w<2;w++){const e=w*Math.PI-Math.PI/4,a=Math.PI/2-at,r=e+a,s=e+Math.PI/2-a,c=t(r,s,Q),d=i(c,tt);l.push(c),l.push(t(r,s,V-q/2)),n.left.push(d),n.right.push(d.instantiate());for(let t=0;t<2;t++){const e=0===t,a=S();if(e){_(a,a,[1,-1,1]),D(a,a,-r,[0,0,1]);const t=Math.round(B*(c.length-1));a[12]=c[t][0],a[13]=c[t][1],a[14]=c[t][2]}else{D(a,a,s,[0,0,1]);const t=Math.round((1-B)*(c.length-1));a[12]=c[t][0],a[13]=c[t][1],a[14]=c[t][2]}const i=st(o,Y,0,X,W);nt(i,a),(e?n.left:n.right).push(i)}}const c=[];for(let _=0;_<2;_++){const e=_*Math.PI-Math.PI/4,a=Math.PI/2-it,o=e+a,r=e+Math.PI/2-a,s=t(o,r,V);c.push(i(s,tt))}const d=this._createMaterial(.66),h=this._createMaterial(.5),u=this._createMaterial(.33),p=e(K+Z),m=e(K+$),g=i(p,tt,d),f=i(m,tt,u),v=e(K-Z),M=e(K-$),b=i(v,tt,d),j=i(M,tt,u);let y=[new L(s,mt.DelayedFocused),new L(s.instantiate({material:h}),pt.None)];this.mode&&"scale"!==this.mode||(y=y.concat([...c.map((t=>new L(t,mt.DelayedFocused|mt.Unlocked))),new L(g,mt.DelayedFocused|mt.ScaleIn),new L(f,mt.DelayedFocused|mt.ScaleIn),new L(b,mt.DelayedFocused|mt.ScaleOut),new L(j,mt.DelayedFocused|mt.ScaleOut)])),this.mode&&"rotate"!==this.mode||(y=y.concat([...n.right.map((t=>new L(t.instantiate(),mt.DelayedFocused|mt.Unlocked))),...n.left.map((t=>new L(t,mt.DelayedFocused|mt.RotateLeft))),...n.right.map((t=>new L(t,mt.DelayedFocused|mt.RotateRight)))]));const R=[r,...l];return new P({view:this.tool.view,renderObjects:y,autoScaleRenderObjects:!1,worldOriented:!0,radius:q,focusMultiplier:1,touchMultiplier:1.5,elevationInfo:this.tool.object.elevationInfo,collisionType:{type:"ribbon",paths:R,direction:A(0,0,1)}})}_createMaterial(t){const e=new dt({cullFace:rt.Back,renderOccluded:ct.Transparent,isDecoration:!0});return this.addHandles(l((()=>a(this.tool.view.effectiveTheme.accentColor,t)),(t=>e.setParameters({color:t})),c)),e}get test(){}};function ft(t,e){const a=M(k.get(),e.renderStart,t.origin),o=M(k.get(),e.renderEnd,t.origin),i=b(a),r=b(o);return 0===i?0:r/i}function _t(t,e,a,o){const{renderStart:i,renderEnd:r}=t,s=Dt(i,o,k.get()),n=Dt(r,o,k.get());if(j(s,n)<J*J)return null;const l=M(k.get(),i,a),c=y(k.get(),l,O(e)),d=i,h=R(k.get(),d,c),u=Dt(a,o,k.get()),p=s,m=Dt(h,o,k.get()),g=M(k.get(),m,p),f=M(k.get(),s,u),_=C(p,g),D=C(u,f);return E(_,n)<E(D,n)?"rotate":"scale"}function Dt(t,e,a){return e.projectToScreen(t,bt),v(a,bt[0],bt[1],0)}var St;function vt(t,e){let a=null,o=1;const i=()=>o;return{start:()=>{o=t.getScale(),a=t.getScale,t.getScale=i,e()},update:t=>(o+=((o+1)/2-o)*Math.min(t*ot,1),e(),Math.abs(o-1)<.01?St.STOP:St.CONTINUE),destroy:()=>{a&&(t.getScale=a),e()}}}function Mt(t,e,a){let o=0,i=null;const r=()=>!1;return{start:()=>{i=t.getFocused,t.getFocused=r,o=0,e()},update:t=>(o+=t,!i?.()||o>=a.delayMs?St.STOP:St.CONTINUE),destroy:()=>{i&&(t.getFocused=i),e()}}}t([u({constructOnly:!0})],gt.prototype,"tool",void 0),t([u({constructOnly:!0})],gt.prototype,"adapter",void 0),t([u({constructOnly:!0})],gt.prototype,"sketchOptions",void 0),t([u()],gt.prototype,"mode",void 0),t([u()],gt.prototype,"_activeAnimation",void 0),t([u()],gt.prototype,"updating",null),gt=t([p("esri.views.3d.interactive.editingTools.transform.ScaleRotateTransform")],gt),function(t){t[t.CONTINUE=0]="CONTINUE",t[t.STOP=1]="STOP"}(St||(St={}));const bt=h();export{gt as ScaleRotateTransform};