UNPKG

ue-too

Version:

pan, zoom, and rotate your html canvas

1 lines 50.5 kB
import{PointCal}from"point2point";import{Observable as Observable$1}from"../utils/observable";import{convertDeltaInViewPortToWorldSpace as convertDeltaInViewPortToWorldSpace$1}from"./utils";function isValidZoomLevelLimits(zoomLevelLimits){return void 0===zoomLevelLimits||!(void 0!==zoomLevelLimits.min&&void 0!==zoomLevelLimits.max&&zoomLevelLimits.min>zoomLevelLimits.max)}function clampZoomLevel(zoomLevel,zoomLevelLimits){return zoomLevelWithinLimits(zoomLevel,zoomLevelLimits)||void 0===zoomLevelLimits||(zoomLevelLimits.max&&(zoomLevel=Math.min(zoomLevelLimits.max,zoomLevel)),zoomLevelLimits.min&&(zoomLevel=Math.max(zoomLevelLimits.min,zoomLevel))),zoomLevel}function zoomLevelWithinLimits(zoomLevel,zoomLevelLimits){return void 0===zoomLevelLimits||!(zoomLevel<=0||void 0!==zoomLevelLimits&&(void 0!==zoomLevelLimits.max&&zoomLevelLimits.max<zoomLevel||void 0!==zoomLevelLimits.min&&zoomLevelLimits.min>zoomLevel))}function decomposeCameraMatrix(transformMatrix,devicePixelRatio,canvasWidth,canvasHeight){const a=transformMatrix.a,b=transformMatrix.b;transformMatrix.c,transformMatrix.d;const tx=transformMatrix.e,ty=transformMatrix.f,rotation=-Math.atan2(b,a),zoom=Math.sqrt(a*a+b*b)/devicePixelRatio;let reverse=[tx,ty];reverse=[reverse[0]/devicePixelRatio,reverse[1]/devicePixelRatio],reverse=[reverse[0]-canvasWidth/2,reverse[1]-canvasHeight/2];const cos_r=Math.cos(rotation),sin_r=Math.sin(rotation);reverse=[cos_r*reverse[0]-sin_r*reverse[1],sin_r*reverse[0]+cos_r*reverse[1]],reverse=[reverse[0]/zoom,reverse[1]/zoom];return{position:{x:-reverse[0],y:-reverse[1]},zoom:zoom,rotation:rotation}}function createCameraMatrix(cameraPos,zoom,rotation,devicePixelRatio,canvasWidth,canvasHeight){const multipliedMatrix=multiplyMatrix({a:devicePixelRatio,b:0,c:0,d:devicePixelRatio,e:0,f:0},{a:1,b:0,c:0,d:1,e:canvasWidth/2,f:canvasHeight/2}),cos_r=Math.cos(-rotation),sin_r=Math.sin(-rotation),rotatedMatrix=multiplyMatrix(multipliedMatrix,{a:cos_r,b:sin_r,c:-sin_r,d:cos_r,e:0,f:0}),zoomedMatrix=multiplyMatrix(rotatedMatrix,{a:zoom,b:0,c:0,d:zoom,e:0,f:0});return multiplyMatrix(zoomedMatrix,{a:1,b:0,c:0,d:1,e:-cameraPos.x,f:-cameraPos.y})}function multiplyMatrix(m1,m2){const a1=m1.a,b1=m1.b,c1=m1.c,d1=m1.d,tx1=m1.e,ty1=m1.f,a2=m2.a,b2=m2.b,c2=m2.c,d2=m2.d,tx2=m2.e,ty2=m2.f;return{a:a1*a2+c1*b2,b:b1*a2+d1*b2,c:a1*c2+c1*d2,d:b1*c2+d1*d2,e:a1*tx2+c1*ty2+tx1,f:b1*tx2+d1*ty2+ty1}}function convert2WorldSpaceWRT(targetPosition,interestPoint,viewPortWidth,viewPortHeight,cameraZoomLevel,cameraRotation){let cameraFrameCenter={x:viewPortWidth/2,y:viewPortHeight/2},delta2Point=PointCal.subVector(interestPoint,cameraFrameCenter);return delta2Point=PointCal.multiplyVectorByScalar(delta2Point,1/cameraZoomLevel),delta2Point=PointCal.rotatePoint(delta2Point,cameraRotation),PointCal.addVector(targetPosition,delta2Point)}function convert2WorldSpace(point,viewPortWidth,viewPortHeight,cameraPosition,cameraZoomLevel,cameraRotation){let cameraFrameCenter={x:viewPortWidth/2,y:viewPortHeight/2},delta2Point=PointCal.subVector(point,cameraFrameCenter);return delta2Point=PointCal.multiplyVectorByScalar(delta2Point,1/cameraZoomLevel),delta2Point=PointCal.rotatePoint(delta2Point,cameraRotation),PointCal.addVector(cameraPosition,delta2Point)}function convert2WorldSpaceAnchorAtCenter(point,cameraPosition,cameraZoomLevel,cameraRotation){const scaledBack=PointCal.multiplyVectorByScalar(point,1/cameraZoomLevel),rotatedBack=PointCal.rotatePoint(scaledBack,cameraRotation);return PointCal.addVector(rotatedBack,cameraPosition)}function convert2ViewPortSpaceAnchorAtCenter(point,cameraPosition,cameraZoomLevel,cameraRotation){const withOffset=PointCal.subVector(point,cameraPosition),scaled=PointCal.multiplyVectorByScalar(withOffset,cameraZoomLevel);return PointCal.rotatePoint(scaled,-cameraRotation)}function invertFromWorldSpace(point,viewPortWidth,viewPortHeight,cameraPosition,cameraZoomLevel,cameraRotation){let cameraFrameCenter={x:viewPortWidth/2,y:viewPortHeight/2},delta2Point=PointCal.subVector(point,cameraPosition);return delta2Point=PointCal.rotatePoint(delta2Point,-cameraRotation),delta2Point=PointCal.multiplyVectorByScalar(delta2Point,cameraZoomLevel),PointCal.addVector(cameraFrameCenter,delta2Point)}function pointIsInViewPort(point,viewPortWidth,viewPortHeight,cameraPosition,cameraZoomLevel,cameraRotation){const pointInCameraFrame=invertFromWorldSpace(point,viewPortWidth,viewPortHeight,cameraPosition,cameraZoomLevel,cameraRotation);return!(pointInCameraFrame.x<0||pointInCameraFrame.x>viewPortWidth||pointInCameraFrame.y<0||pointInCameraFrame.y>viewPortHeight)}function convertDeltaInViewPortToWorldSpace(delta,cameraZoomLevel,cameraRotation){return PointCal.multiplyVectorByScalar(PointCal.rotatePoint(delta,cameraRotation),1/cameraZoomLevel)}function convertDeltaInWorldToViewPortSpace(delta,cameraZoomLevel,cameraRotation){return PointCal.multiplyVectorByScalar(PointCal.rotatePoint(delta,-cameraRotation),cameraZoomLevel)}function cameraPositionToGet(pointInWorld,toPointInViewPort,cameraZoomLevel,cameraRotation){const scaled=PointCal.multiplyVectorByScalar(toPointInViewPort,1/cameraZoomLevel),rotated=PointCal.rotatePoint(scaled,cameraRotation);return PointCal.subVector(pointInWorld,rotated)}function transformationMatrixFromCamera(cameraPosition,cameraZoomLevel,cameraRotation){const cos=Math.cos(cameraRotation),sin=Math.sin(cameraRotation),trMatrix=multiplyMatrix({a:1,b:0,c:0,d:1,e:cameraPosition.x,f:cameraPosition.y},{a:cos,b:sin,c:-sin,d:cos,e:0,f:0});return multiplyMatrix(trMatrix,{a:1/cameraZoomLevel,b:0,c:0,d:1/cameraZoomLevel,e:0,f:0})}function convert2WorldSpaceWithTransformationMatrix(point,transformationMatrix){return{x:point.x*transformationMatrix.a+point.y*transformationMatrix.c+transformationMatrix.e,y:point.x*transformationMatrix.b+point.y*transformationMatrix.d+transformationMatrix.f}}function withinBoundaries(point,boundaries){if(null==boundaries)return!0;let leftSide=!1,rightSide=!1,topSide=!1,bottomSide=!1;return(null==boundaries.max||null==boundaries.max.x||point.x<=boundaries.max.x)&&(rightSide=!0),(null==boundaries.min||null==boundaries.min.x||point.x>=boundaries.min.x)&&(leftSide=!0),(null==boundaries.max||null==boundaries.max.y||point.y<=boundaries.max.y)&&(topSide=!0),(null==boundaries.min||null==boundaries.min.y||point.y>=boundaries.min.y)&&(bottomSide=!0),leftSide&&rightSide&&topSide&&bottomSide}function isValidBoundaries(boundaries){var _a,_b,_c,_d;if(null==boundaries)return!0;const minX=null===(_a=boundaries.min)||void 0===_a?void 0:_a.x,maxX=null===(_b=boundaries.max)||void 0===_b?void 0:_b.x;if(null!=minX&&null!=maxX&&minX>=maxX)return!1;const minY=null===(_c=boundaries.min)||void 0===_c?void 0:_c.y,maxY=null===(_d=boundaries.max)||void 0===_d?void 0:_d.y;return!(null!=minY&&null!=maxY&&minY>=maxY)}function boundariesFullyDefined(boundaries){return null!=boundaries&&(null!=boundaries.max&&null!=boundaries.min&&(null!=boundaries.max.x&&null!=boundaries.max.y&&null!=boundaries.min.x&&null!=boundaries.min.y))}function clampPoint(point,boundaries){if(withinBoundaries(point,boundaries)||null==boundaries)return point;let manipulatePoint={x:point.x,y:point.y},limit=boundaries.min;return null!=limit&&(null!=limit.x&&(manipulatePoint.x=Math.max(manipulatePoint.x,limit.x)),null!=limit.y&&(manipulatePoint.y=Math.max(manipulatePoint.y,limit.y))),limit=boundaries.max,null!=limit&&(null!=limit.x&&(manipulatePoint.x=Math.min(manipulatePoint.x,limit.x)),null!=limit.y&&(manipulatePoint.y=Math.min(manipulatePoint.y,limit.y))),manipulatePoint}function translationWidthOf(boundaries){if(null!=boundaries&&null!=boundaries.min&&null!=boundaries.max&&null!=boundaries.min.x&&null!=boundaries.max.x)return boundaries.max.x-boundaries.min.x}function halfTranslationWidthOf(boundaries){const translationWidth=translationWidthOf(boundaries);return null!=translationWidth?translationWidth/2:void 0}function translationHeightOf(boundaries){if(null!=boundaries&&null!=boundaries.min&&null!=boundaries.max&&null!=boundaries.min.y&&null!=boundaries.max.y)return boundaries.max.y-boundaries.min.y}function halfTranslationHeightOf(boundaries){const translationHeight=translationHeightOf(boundaries);return null!=translationHeight?translationHeight/2:void 0}function clampPointEntireViewPort(point,viewPortWidth,viewPortHeight,boundaries,cameraZoomLevel,cameraRotation){if(null==boundaries)return point;let topLeftCorner=convert2WorldSpaceWRT(point,{x:0,y:viewPortHeight},viewPortWidth,viewPortHeight,cameraZoomLevel,cameraRotation),bottomLeftCorner=convert2WorldSpaceWRT(point,{x:0,y:0},viewPortWidth,viewPortHeight,cameraZoomLevel,cameraRotation),topRightCorner=convert2WorldSpaceWRT(point,{x:viewPortWidth,y:viewPortHeight},viewPortWidth,viewPortHeight,cameraZoomLevel,cameraRotation),bottomRightCorner=convert2WorldSpaceWRT(point,{x:viewPortWidth,y:0},viewPortWidth,viewPortHeight,cameraZoomLevel,cameraRotation),topLeftCornerClamped=clampPoint(topLeftCorner,boundaries),topRightCornerClamped=clampPoint(topRightCorner,boundaries),bottomLeftCornerClamped=clampPoint(bottomLeftCorner,boundaries),bottomRightCornerClamped=clampPoint(bottomRightCorner,boundaries),diffs=[PointCal.subVector(topLeftCornerClamped,topLeftCorner),PointCal.subVector(topRightCornerClamped,topRightCorner),PointCal.subVector(bottomLeftCornerClamped,bottomLeftCorner),PointCal.subVector(bottomRightCornerClamped,bottomRightCorner)],maxXDiff=Math.abs(diffs[0].x),maxYDiff=Math.abs(diffs[0].y),delta=diffs[0];return diffs.forEach((diff=>{Math.abs(diff.x)>maxXDiff&&(maxXDiff=Math.abs(diff.x),delta.x=diff.x),Math.abs(diff.y)>maxYDiff&&(maxYDiff=Math.abs(diff.y),delta.y=diff.y)})),PointCal.addVector(point,delta)}function clampRotation(rotation,rotationLimits){if(rotationWithinLimits(rotation,rotationLimits)||void 0===rotationLimits)return rotation;rotation=normalizeAngleZero2TwoPI(rotation);const angleSpanFromStart=angleSpan(rotationLimits.start,rotation),angleSpanFromEnd=angleSpan(rotationLimits.end,rotation);if(rotationLimits.ccw&&(angleSpanFromStart<0||angleSpanFromEnd>0)||!rotationLimits.ccw&&(angleSpanFromStart>0||angleSpanFromEnd<0)){if(Math.abs(angleSpanFromStart)===Math.abs(angleSpanFromEnd))return rotationLimits.startAsTieBreaker?rotationLimits.start:rotationLimits.end;return Math.abs(angleSpanFromStart)<Math.abs(angleSpanFromEnd)?rotationLimits.start:rotationLimits.end}return rotation}function rotationWithinLimits(rotation,rotationLimits){if(void 0===rotationLimits)return!0;if(normalizeAngleZero2TwoPI(rotationLimits.start)===normalizeAngleZero2TwoPI(rotationLimits.end))return!0;if(normalizeAngleZero2TwoPI(rotationLimits.start+.01)===normalizeAngleZero2TwoPI(rotationLimits.end+.01))return!0;const normalizedRotation=normalizeAngleZero2TwoPI(rotation),angleSpanFromStart=angleSpan(rotationLimits.start,normalizedRotation),angleSpanFromEnd=angleSpan(rotationLimits.end,normalizedRotation);return!(rotationLimits.ccw&&(angleSpanFromStart<0||angleSpanFromEnd>0)||!rotationLimits.ccw&&(angleSpanFromStart>0||angleSpanFromEnd<0))}function rotationWithinBoundary(rotation,rotationBoundary){if(normalizeAngleZero2TwoPI(rotationBoundary.start)===normalizeAngleZero2TwoPI(rotationBoundary.end))return!0;if(normalizeAngleZero2TwoPI(rotationBoundary.start+.01)===normalizeAngleZero2TwoPI(rotationBoundary.end+.01))return!0;let angleFromStart=normalizeAngleZero2TwoPI(rotation)-normalizeAngleZero2TwoPI(rotationBoundary.start);angleFromStart<0&&(angleFromStart+=2*Math.PI),!rotationBoundary.positiveDirection&&angleFromStart>0&&(angleFromStart=2*Math.PI-angleFromStart);let angleRange=normalizeAngleZero2TwoPI(rotationBoundary.end)-normalizeAngleZero2TwoPI(rotationBoundary.start);return angleRange<0&&(angleRange+=2*Math.PI),!rotationBoundary.positiveDirection&&angleRange>0&&(angleRange=2*Math.PI-angleRange),angleRange>=angleFromStart}function normalizeAngleZero2TwoPI(angle){return angle=((angle%=2*Math.PI)+2*Math.PI)%(2*Math.PI)}function angleSpan(from,to){from=normalizeAngleZero2TwoPI(from);let angleDiff=(to=normalizeAngleZero2TwoPI(to))-from;return angleDiff>Math.PI&&(angleDiff=-(2*Math.PI-angleDiff)),angleDiff<-Math.PI&&(angleDiff+=2*Math.PI),angleDiff}function deg2rad(deg){return deg*Math.PI/180}function rad2deg(rad){return 180*rad/Math.PI}class CameraUpdatePublisher{constructor(){this.pan=new Observable$1,this.zoom=new Observable$1,this.rotate=new Observable$1,this.all=new Observable$1}notifyPan(event,cameraState){this.pan.notify(event,cameraState),this.all.notify({type:"pan",diff:event.diff},cameraState)}notifyZoom(event,cameraState){this.zoom.notify(event,cameraState),this.all.notify({type:"zoom",deltaZoomAmount:event.deltaZoomAmount},cameraState)}notifyRotate(event,cameraState){this.rotate.notify(event,cameraState),this.all.notify({type:"rotate",deltaRotation:event.deltaRotation},cameraState)}on(eventName,callback,options){switch(eventName){case"pan":return this.pan.subscribe(callback,options);case"zoom":return this.zoom.subscribe(callback,options);case"rotate":return this.rotate.subscribe(callback,options);case"all":return this.all.subscribe(callback,options);default:throw new Error(`Invalid event name: ${eventName}`)}}}class BaseCamera{constructor(viewPortWidth=1e3,viewPortHeight=1e3,position={x:0,y:0},rotation=0,zoomLevel=1,boundaries={min:{x:-1e4,y:-1e4},max:{x:1e4,y:1e4}},zoomLevelBoundaries={min:.1,max:10},rotationBoundaries=void 0){this._position=position,this._zoomLevel=zoomLevel,this._rotation=rotation,this._viewPortHeight=viewPortHeight,this._viewPortWidth=viewPortWidth,this._zoomBoundaries=zoomLevelBoundaries,this._rotationBoundaries=rotationBoundaries,this._boundaries=boundaries}get boundaries(){return this._boundaries}set boundaries(boundaries){this._boundaries=boundaries}get viewPortWidth(){return this._viewPortWidth}set viewPortWidth(width){this._viewPortWidth=width}get viewPortHeight(){return this._viewPortHeight}set viewPortHeight(height){this._viewPortHeight=height}get position(){return this._position}setPosition(destination){if(!withinBoundaries(destination,this._boundaries))return!1;const diff=PointCal.subVector(destination,this._position);return!(PointCal.magnitude(diff)<1e-9&&PointCal.magnitude(diff)<1/this._zoomLevel)&&(this._position=destination,!0)}get zoomLevel(){return this._zoomLevel}get zoomBoundaries(){return this._zoomBoundaries}set zoomBoundaries(zoomBoundaries){if(void 0!==zoomBoundaries&&void 0!==zoomBoundaries.min&&void 0!==zoomBoundaries.max&&zoomBoundaries.min>zoomBoundaries.max){let temp=zoomBoundaries.max;zoomBoundaries.max=zoomBoundaries.min,zoomBoundaries.min=temp}this._zoomBoundaries=zoomBoundaries}setMaxZoomLevel(maxZoomLevel){return null==this._zoomBoundaries&&(this._zoomBoundaries={min:void 0,max:void 0}),!(null!=this._zoomBoundaries.min&&this._zoomBoundaries.min>maxZoomLevel||this._zoomLevel>maxZoomLevel)&&(this._zoomBoundaries.max=maxZoomLevel,!0)}setMinZoomLevel(minZoomLevel){return null==this._zoomBoundaries&&(this._zoomBoundaries={min:void 0,max:void 0}),!(null!=this._zoomBoundaries.max&&this._zoomBoundaries.max<minZoomLevel)&&(this._zoomBoundaries.min=minZoomLevel,this._zoomLevel<minZoomLevel&&(this._zoomLevel=minZoomLevel),!0)}setZoomLevel(zoomLevel){return!!zoomLevelWithinLimits(zoomLevel,this._zoomBoundaries)&&((void 0===this._zoomBoundaries||void 0===this._zoomBoundaries.max||clampZoomLevel(zoomLevel,this._zoomBoundaries)!=this._zoomBoundaries.max||this._zoomLevel!=this._zoomBoundaries.max)&&((void 0===this._zoomBoundaries||void 0===this._zoomBoundaries.min||clampZoomLevel(zoomLevel,this._zoomBoundaries)!=this._zoomBoundaries.min||this._zoomLevel!=this._zoomBoundaries.min)&&(this._zoomLevel=zoomLevel,!0)))}get rotation(){return this._rotation}get rotationBoundaries(){return this._rotationBoundaries}set rotationBoundaries(rotationBoundaries){if(void 0!==rotationBoundaries&&void 0!==rotationBoundaries.start&&void 0!==rotationBoundaries.end&&rotationBoundaries.start>rotationBoundaries.end){let temp=rotationBoundaries.end;rotationBoundaries.end=rotationBoundaries.start,rotationBoundaries.start=temp}this._rotationBoundaries=rotationBoundaries}getTransform(devicePixelRatio,alignCoorindate){if(void 0!==this.currentCachedTransform&&this.currentCachedTransform.devicePixelRatio===devicePixelRatio&&this.currentCachedTransform.alignCoorindate===alignCoorindate&&this.currentCachedTransform.position.x===this._position.x&&this.currentCachedTransform.position.y===this._position.y&&this.currentCachedTransform.rotation===this._rotation&&this.currentCachedTransform.zoomLevel===this._zoomLevel&&this.currentCachedTransform.viewPortWidth===this._viewPortWidth&&this.currentCachedTransform.viewPortHeight===this._viewPortHeight)return Object.assign(Object.assign({},this.currentCachedTransform.transform),{cached:!0});const tx=devicePixelRatio*this._viewPortWidth/2,ty=devicePixelRatio*this._viewPortHeight/2,tx2=-this._position.x,ty2=alignCoorindate?-this._position.y:this._position.y,s=devicePixelRatio,s2=this._zoomLevel,θ=alignCoorindate?-this._rotation:this._rotation,sin=Math.sin(θ),cos=Math.cos(θ),a=s2*s*cos,b=s2*s*sin,c=-s*s2*sin,d=s2*s*cos,e=s*s2*cos*tx2-s*s2*sin*ty2+tx,f=s*s2*sin*tx2+s*s2*cos*ty2+ty;return this.currentCachedTransform={transform:{a:a,b:b,c:c,d:d,e:e,f:f},position:this._position,rotation:this._rotation,zoomLevel:this._zoomLevel,alignCoorindate:alignCoorindate,devicePixelRatio:devicePixelRatio,viewPortWidth:this._viewPortWidth,viewPortHeight:this._viewPortHeight},{a:a,b:b,c:c,d:d,e:e,f:f,cached:!1}}setUsingTransformationMatrix(transformationMatrix){const decomposed=decomposeCameraMatrix(transformationMatrix,this._viewPortWidth,this._viewPortHeight,this._zoomLevel);this.setPosition(decomposed.position),this.setRotation(decomposed.rotation),this.setZoomLevel(decomposed.zoom)}setRotation(rotation){return!!rotationWithinLimits(rotation,this._rotationBoundaries)&&(rotation=normalizeAngleZero2TwoPI(rotation),(void 0===this._rotationBoundaries||void 0===this._rotationBoundaries.end||clampRotation(rotation,this._rotationBoundaries)!=this._rotationBoundaries.end||this._rotation!=this._rotationBoundaries.end)&&((void 0===this._rotationBoundaries||void 0===this.rotationBoundaries.start||clampRotation(rotation,this._rotationBoundaries)!=this._rotationBoundaries.start||this._rotation!=this._rotationBoundaries.start)&&(this._rotation=rotation,!0)))}getCameraOriginInWindow(centerInWindow){return centerInWindow}convertFromViewPort2WorldSpace(point){return convert2WorldSpaceAnchorAtCenter(point,this._position,this._zoomLevel,this._rotation)}convertFromWorld2ViewPort(point){return convert2ViewPortSpaceAnchorAtCenter(point,this._position,this._zoomLevel,this._rotation)}invertFromWorldSpace2ViewPort(point){let cameraFrameCenter={x:this.viewPortWidth/2,y:this._viewPortHeight/2},delta2Point=PointCal.subVector(point,this._position);return delta2Point=PointCal.rotatePoint(delta2Point,-this._rotation),delta2Point=PointCal.multiplyVectorByScalar(delta2Point,this._zoomLevel),PointCal.addVector(cameraFrameCenter,delta2Point)}setHorizontalBoundaries(min,max){if(min>max){let temp=max;max=min,min=temp}null==this._boundaries&&(this._boundaries={min:{x:void 0,y:void 0},max:{x:void 0,y:void 0}}),this._boundaries.min.x=min,this._boundaries.max.x=max}setVerticalBoundaries(min,max){if(min>max){let temp=max;max=min,min=temp}null==this._boundaries&&(this._boundaries={min:{x:void 0,y:void 0},max:{x:void 0,y:void 0}}),this._boundaries.min.y=min,this._boundaries.max.y=max}}const DEFAULT_BOARD_CAMERA_VIEWPORT_WIDTH=1e3,DEFAULT_BOARD_CAMERA_VIEWPORT_HEIGHT=1e3,DEFAULT_BOARD_CAMERA_ZOOM_BOUNDARIES={min:.1,max:10},DEFAULT_BOARD_CAMERA_BOUNDARIES={min:{x:-1e4,y:-1e4},max:{x:1e4,y:1e4}},DEFAULT_BOARD_CAMERA_ROTATION_BOUNDARIES=void 0;class DefaultBoardCamera{constructor(viewPortWidth=1e3,viewPortHeight=1e3,position={x:0,y:0},rotation=0,zoomLevel=1,boundaries=DEFAULT_BOARD_CAMERA_BOUNDARIES,zoomLevelBoundaries=DEFAULT_BOARD_CAMERA_ZOOM_BOUNDARIES,rotationBoundaries=undefined){this._baseCamera=new BaseCamera(viewPortWidth,viewPortHeight,position,rotation,zoomLevel,boundaries,zoomLevelBoundaries,rotationBoundaries),this._observer=new CameraUpdatePublisher}get boundaries(){return this._baseCamera.boundaries}set boundaries(boundaries){this._baseCamera.boundaries=boundaries}get viewPortWidth(){return this._baseCamera.viewPortWidth}set viewPortWidth(width){this._baseCamera.viewPortWidth=width}get viewPortHeight(){return this._baseCamera.viewPortHeight}set viewPortHeight(height){this._baseCamera.viewPortHeight=height}get position(){return this._baseCamera.position}setPosition(destination){const currentPosition=Object.assign({},this._baseCamera.position);return!!this._baseCamera.setPosition(destination)&&(this._observer.notifyPan({diff:PointCal.subVector(destination,currentPosition)},{position:this._baseCamera.position,rotation:this._baseCamera.rotation,zoomLevel:this._baseCamera.zoomLevel}),!0)}get zoomLevel(){return this._baseCamera.zoomLevel}get zoomBoundaries(){return this._baseCamera.zoomBoundaries}set zoomBoundaries(zoomBoundaries){this._baseCamera.zoomBoundaries=zoomBoundaries}setMaxZoomLevel(maxZoomLevel){const currentZoomLevel=this._baseCamera.zoomLevel;return!!this._baseCamera.setMaxZoomLevel(maxZoomLevel)&&(this._observer.notifyZoom({deltaZoomAmount:maxZoomLevel-currentZoomLevel},{position:this._baseCamera.position,rotation:this._baseCamera.rotation,zoomLevel:this._baseCamera.zoomLevel}),!0)}setMinZoomLevel(minZoomLevel){return!!this._baseCamera.setMinZoomLevel(minZoomLevel)}setZoomLevel(zoomLevel){return!!this._baseCamera.setZoomLevel(zoomLevel)}get rotation(){return this._baseCamera.rotation}get rotationBoundaries(){return this._baseCamera.rotationBoundaries}set rotationBoundaries(rotationBoundaries){this._baseCamera.rotationBoundaries=rotationBoundaries}getTransform(devicePixelRatio,alignCoorindate){return this._baseCamera.getTransform(devicePixelRatio,alignCoorindate)}setRotation(rotation){const currentRotation=this._baseCamera.rotation;return!!this._baseCamera.setRotation(rotation)&&(this._observer.notifyRotate({deltaRotation:rotation-currentRotation},{position:this._baseCamera.position,rotation:this._baseCamera.rotation,zoomLevel:this._baseCamera.zoomLevel}),!0)}getCameraOriginInWindow(centerInWindow){return centerInWindow}convertFromViewPort2WorldSpace(point){return convert2WorldSpaceAnchorAtCenter(point,this._baseCamera.position,this._baseCamera.zoomLevel,this._baseCamera.rotation)}convertFromWorld2ViewPort(point){return convert2ViewPortSpaceAnchorAtCenter(point,this._baseCamera.position,this._baseCamera.zoomLevel,this._baseCamera.rotation)}invertFromWorldSpace2ViewPort(point){let cameraFrameCenter={x:this._baseCamera.viewPortWidth/2,y:this._baseCamera.viewPortHeight/2},delta2Point=PointCal.subVector(point,this._baseCamera.position);return delta2Point=PointCal.rotatePoint(delta2Point,-this._baseCamera.rotation),delta2Point=PointCal.multiplyVectorByScalar(delta2Point,this._baseCamera.zoomLevel),PointCal.addVector(cameraFrameCenter,delta2Point)}setHorizontalBoundaries(min,max){if(min>max){let temp=max;max=min,min=temp}null==this._baseCamera.boundaries&&(this._baseCamera.boundaries={min:{x:void 0,y:void 0},max:{x:void 0,y:void 0}}),this._baseCamera.boundaries.min.x=min,this._baseCamera.boundaries.max.x=max}setVerticalBoundaries(min,max){if(min>max){let temp=max;max=min,min=temp}null==this._baseCamera.boundaries&&(this._baseCamera.boundaries={min:{x:void 0,y:void 0},max:{x:void 0,y:void 0}}),this._baseCamera.boundaries.min.y=min,this._baseCamera.boundaries.max.y=max}on(eventName,callback,options){return this._observer.on(eventName,callback,options)}}class ContextCentricCamera{constructor(position={x:0,y:0},rotation=0,zoomLevel=1,viewPortWidth=1e3,viewPortHeight=1e3,observer=new CameraUpdatePublisher,boundaries={min:{x:-1e4,y:-1e4},max:{x:1e4,y:1e4}},zoomLevelBoundaries={min:.1,max:10},rotationBoundaries={start:0,end:2*Math.PI,ccw:!0,startAsTieBreaker:!1}){this._contextRotation=-rotation,this._zoomLevel=zoomLevel,this._contextPosition=PointCal.subVector({x:viewPortWidth/2,y:viewPortHeight/2},PointCal.multiplyVectorByScalar(PointCal.rotatePoint(position,-rotation),zoomLevel)),this._viewPortWidth=viewPortWidth,this._viewPortHeight=viewPortHeight,this._observer=observer,this._boundaries=boundaries,this._rotationBoundaries=rotationBoundaries,this._zoomBoundaries=zoomLevelBoundaries}get position(){const x=(this._viewPortWidth/2-this._contextPosition.x)/this._zoomLevel,y=(this._viewPortHeight/2-this._contextPosition.y)/this._zoomLevel;return PointCal.rotatePoint({x:x,y:y},-this._contextRotation)}get contextTransform(){return{position:this._contextPosition,rotation:this._contextRotation,zoomLevel:this._zoomLevel}}setPosition(destination){if(withinBoundaries(destination,this._boundaries)){const destinationInAbsoluteCoordinate=PointCal.subVector({x:this._viewPortWidth/2,y:this._viewPortHeight/2},PointCal.multiplyVectorByScalar(PointCal.rotatePoint(destination,-this.rotation),this._zoomLevel));this._contextPosition=destinationInAbsoluteCoordinate}}setPositionByDelta(delta){const destination=PointCal.addVector(this.position,delta);this.setPosition(destination)}setPositionWithUserInputDelta(delta){this._contextPosition=PointCal.addVector(this._contextPosition,delta)}getCameraOriginInWindow(centerInWindow){return{x:centerInWindow.x-this._viewPortWidth/2,y:centerInWindow.y-this._viewPortHeight/2}}convertFromViewPort2WorldSpace(point){const convertedPoint={x:point.x+this._viewPortWidth/2,y:point.y+this._viewPortHeight/2};return PointCal.multiplyVectorByScalar(PointCal.rotatePoint(PointCal.subVector(convertedPoint,this._contextPosition),-this._contextRotation),1/this._zoomLevel)}setZoomLevel(zoomLevel){zoomLevelWithinLimits(zoomLevel,this._zoomBoundaries)&&(this._zoomLevel,this._zoomLevel=zoomLevel)}setRotation(rotation){const destination=-rotation;rotationWithinLimits(destination,this._rotationBoundaries)&&(this._contextRotation=destination)}get zoomLevel(){return this._zoomLevel}get rotation(){return-this._contextRotation}getTransform(canvasWidth,canvasHeight,devicePixelRatio,alignCoorindate){const e=this._contextPosition.x*devicePixelRatio,f=this._contextPosition.y*devicePixelRatio,c=-Math.sin(this._contextRotation)*this._zoomLevel*devicePixelRatio;return{a:this._zoomLevel*Math.cos(this._contextRotation)*devicePixelRatio,b:Math.sin(this._contextRotation)*this._zoomLevel*devicePixelRatio,c:c,d:this._zoomLevel*Math.cos(this._contextRotation)*devicePixelRatio,e:e,f:f}}get viewPortWidth(){return this._viewPortWidth}get viewPortHeight(){return this._viewPortHeight}set viewportWidth(width){this._viewPortWidth=width}set viewportHeight(height){this._viewPortHeight=height}get zoomBoundaries(){return this._zoomBoundaries}get rotationBoundaries(){return this._rotationBoundaries}viewPortDelta2WorldDelta(delta){return delta}setMinZoomLevel(minZoomLevel){return null==this._zoomBoundaries&&(this._zoomBoundaries={min:void 0,max:void 0}),!(null!=this._zoomBoundaries.max&&this._zoomBoundaries.max<minZoomLevel)&&(this._zoomBoundaries.min=minZoomLevel,this._zoomLevel<minZoomLevel&&(this._zoomLevel=minZoomLevel),this._zoomBoundaries.min=minZoomLevel,!0)}setHorizontalBoundaries(min,max){this._boundaries.min.x=min,this._boundaries.max.x=max}setVerticalBoundaries(min,max){this._boundaries.min.y=min,this._boundaries.max.y=max}on(eventName,callback){return this._observer.on(eventName,callback)}set viewPortWidth(width){this._viewPortWidth=width}set viewPortHeight(height){this._viewPortHeight=height}}function createHandlerChain(...handlers){const normalizedHandlers=Array.isArray(handlers[0])?handlers[0]:handlers;return(value,...args)=>normalizedHandlers.reduce(((acc,handler)=>handler(acc,...args)),value)}function createDefaultPanToHandler(){return createHandlerChain(restrictPanToHandler,clampToHandler)}function createDefaultPanByHandler(){return createHandlerChain(restrictPanByHandler,clampByHandler)}function restrictPanToHandler(destination,camera,config){let delta=PointCal.subVector(destination,camera.position);if(delta=convertDeltaToComplyWithRestriction(delta,camera,config),0===delta.x&&0===delta.y)return destination;return PointCal.addVector(camera.position,delta)}function restrictPanByHandler(delta,camera,config){return delta=convertDeltaToComplyWithRestriction(delta,camera,config)}function clampToHandler(destination,camera,config){if(!config.clampTranslation)return destination;let actualDest=clampPoint(destination,camera.boundaries);return config.limitEntireViewPort&&(actualDest=clampPointEntireViewPort(destination,camera.viewPortWidth,camera.viewPortHeight,camera.boundaries,camera.zoomLevel,camera.rotation)),actualDest}function clampByHandler(delta,camera,config){if(!config.clampTranslation)return delta;let actualDelta=PointCal.subVector(clampPoint(PointCal.addVector(camera.position,delta),camera.boundaries),camera.position);return config.limitEntireViewPort&&(actualDelta=PointCal.subVector(clampPointEntireViewPort(PointCal.addVector(camera.position,delta),camera.viewPortWidth,camera.viewPortHeight,camera.boundaries,camera.zoomLevel,camera.rotation),camera.position)),actualDelta}function convertDeltaToComplyWithRestriction(delta,camera,config){if(config.restrictXTranslation&&config.restrictYTranslation)return{x:0,y:0};if(config.restrictRelativeXTranslation&&config.restrictRelativeYTranslation)return{x:0,y:0};if(config.restrictXTranslation&&(delta.x=0),config.restrictYTranslation&&(delta.y=0),config.restrictRelativeXTranslation){const upDirection=PointCal.rotatePoint({x:0,y:1},camera.rotation),value=PointCal.dotProduct(upDirection,delta);delta=PointCal.multiplyVectorByScalar(upDirection,value)}if(config.restrictRelativeYTranslation){const rightDirection=PointCal.rotatePoint({x:1,y:0},camera.rotation),value=PointCal.dotProduct(rightDirection,delta);delta=PointCal.multiplyVectorByScalar(rightDirection,value)}return delta}function convertUserInputDeltaToCameraDelta(delta,camera){return PointCal.multiplyVectorByScalar(PointCal.rotatePoint(delta,camera.rotation),1/camera.zoomLevel)}function clampZoomToHandler(destination,camera,config){return config.clampZoom?clampZoomLevel(destination,camera.zoomBoundaries):destination}function clampZoomByHandler(delta,camera,config){if(!config.clampZoom)return delta;let targetZoom=camera.zoomLevel+delta;return targetZoom=clampZoomLevel(targetZoom,camera.zoomBoundaries),delta=targetZoom-camera.zoomLevel}function restrictZoomToHandler(destination,camera,config){return config.restrictZoom?camera.zoomLevel:destination}function restrictZoomByHandler(delta,camera,config){return config.restrictZoom?0:delta}function createDefaultZoomToOnlyHandler(){return createHandlerChain(clampZoomToHandler,restrictZoomToHandler)}function createDefaultZoomByOnlyHandler(){return createHandlerChain(clampZoomByHandler,restrictZoomByHandler)}function clampRotateByHandler(delta,camera,config){if(!config.clampRotation)return delta;const clampedRotation=clampRotation(normalizeAngleZero2TwoPI(camera.rotation+delta),camera.rotationBoundaries);return angleSpan(camera.rotation,clampedRotation)}function restrictRotateByHandler(delta,camera,config){return config.restrictRotation?0:delta}function clampRotateToHandler(targetRotation,camera,config){if(!config.clampRotation)return targetRotation;return clampRotation(targetRotation,camera.rotationBoundaries)}function restrictRotateToHandler(targetRotation,camera,config){return config.restrictRotation?camera.rotation:targetRotation}function createDefaultRotateByHandler(){return createHandlerChain(restrictRotateByHandler,clampRotateByHandler)}function createDefaultRotateToHandler(){return createHandlerChain(restrictRotateToHandler,clampRotateToHandler)}class Observable{constructor(){this.observers=[]}subscribe(observer,options){if(this.observers.push(observer),null==options?void 0:options.signal){if(options.signal.aborted)return this.observers=this.observers.filter((o=>o!==observer)),()=>{};const abortHandler=()=>{var _a;this.observers=this.observers.filter((o=>o!==observer)),null===(_a=options.signal)||void 0===_a||_a.removeEventListener("abort",abortHandler)};options.signal.addEventListener("abort",abortHandler)}return()=>{this.observers=this.observers.filter((o=>o!==observer))}}notify(...data){this.observers.forEach((observer=>queueMicrotask((()=>observer(...data)))))}}class CameraPositionUpdateBatcher{constructor(){this.nextPosition=null,this.delta={x:0,y:0},this.queuePositionUpdateCount=0,this.queuePositionUpdateToCount=0,this.queuePositionUpdateByCount=0,this.lastUpdateCount=0,this.observable=new Observable}queuePositionUpdate(x,y){this.queuePositionUpdateCount++,this.queuePositionUpdateTo({x:x,y:y})}queuePositionUpdateTo(destination){this.queuePositionUpdateToCount++,this.nextPosition=Object.assign({},destination),this.delta={x:0,y:0}}queuePositionUpdateBy(delta){this.queuePositionUpdateByCount++,null===this.nextPosition?this.delta={x:this.delta.x+delta.x,y:this.delta.y+delta.y}:this.nextPosition={x:this.nextPosition.x+delta.x,y:this.nextPosition.y+delta.y}}processQueuedUpdates(){if(this.lastUpdateCount=this.queuePositionUpdateCount+this.queuePositionUpdateToCount+this.queuePositionUpdateByCount,this.queuePositionUpdateCount=0,this.queuePositionUpdateToCount=0,this.queuePositionUpdateByCount=0,null!==this.nextPosition){const update=Object.assign(Object.assign({},this.nextPosition),{type:"destination"});return this.nextPosition=null,this.delta={x:0,y:0},this.observable.notify(update),update}if(0!==this.delta.x||0!==this.delta.y){const update=Object.assign(Object.assign({},this.delta),{type:"delta"});return this.delta={x:0,y:0},this.observable.notify(update),update}return null}subscribe(observer,options){return this.observable.subscribe(observer,options)}getDebugInfo(){return{lastUpdateTotalCalls:this.lastUpdateCount,queuePositionUpdateCalls:this.queuePositionUpdateCount,queuePositionUpdateToCalls:this.queuePositionUpdateToCount,queuePositionUpdateByCalls:this.queuePositionUpdateByCount}}}class CameraZoomUpdateBatcher{constructor(){this.nextZoom=null,this.anchor=null,this.delta=0,this.anchorCoordinateSystem="viewport",this.queueZoomUpdateCount=0,this.queueZoomUpdateToCount=0,this.lastUpdateCount=0,this.observable=new Observable}queueZoomUpdateTo(destination,anchor){"world"===this.anchorCoordinateSystem&&(this.anchorCoordinateSystem="viewport",this.nextZoom=null,this.delta=0),this.anchor=anchor,this.nextZoom=destination,0!==this.delta&&(this.delta=0)}queueZoomUpdateBy(delta,anchor){"world"===this.anchorCoordinateSystem&&(this.anchorCoordinateSystem="viewport",this.nextZoom=null,this.delta=0),null===this.nextZoom?this.delta+=delta:this.nextZoom+=delta,this.anchor=anchor}queueZoomByAtWorld(delta,worldAnchor){"viewport"===this.anchorCoordinateSystem&&(this.anchorCoordinateSystem="world",this.nextZoom=null,this.delta=0),this.anchor=worldAnchor,null===this.nextZoom?this.delta+=delta:this.nextZoom+=delta}queueZoomToAtWorld(destination,worldAnchor){"viewport"===this.anchorCoordinateSystem&&(this.anchorCoordinateSystem="world",this.nextZoom=null,this.delta=0),this.anchor=worldAnchor,this.nextZoom=destination,0!==this.delta&&(this.delta=0)}processQueuedUpdates(){if(null===this.nextZoom&&0===this.delta)return null;const delta=this.delta,nextZoom=this.nextZoom,anchor=this.anchor;return this.delta=0,this.nextZoom=null,this.anchor=null,0!==delta?{anchorCoordinateSystem:this.anchorCoordinateSystem,update:{type:"delta",delta:delta,anchor:anchor}}:{anchorCoordinateSystem:this.anchorCoordinateSystem,update:{type:"destination",destination:nextZoom,anchor:anchor}}}subscribe(observer,options){return this.observable.subscribe(observer,options)}getDebugInfo(){return{lastUpdateTotalCalls:this.lastUpdateCount,queueZoomUpdateCalls:this.queueZoomUpdateCount,queueZoomUpdateToCalls:this.queueZoomUpdateToCount}}}class CameraRotationUpdateBatcher{constructor(){this.nextRotation=null,this.delta=0,this.queueRotationUpdateCount=0,this.queueRotationUpdateToCount=0,this.queueRotationUpdateByCount=0,this.lastUpdateCount=0,this.observable=new Observable}queueRotationUpdate(rotation){this.queueRotationUpdateCount++,this.queueRotationUpdateTo(rotation)}queueRotationUpdateTo(destination){this.queueRotationUpdateToCount++,this.nextRotation=destination,this.delta=0}queueRotationUpdateBy(delta){this.queueRotationUpdateByCount++,null===this.nextRotation?this.delta=this.delta+delta:this.nextRotation=this.nextRotation+delta}processQueuedUpdates(){if(this.lastUpdateCount=this.queueRotationUpdateCount+this.queueRotationUpdateToCount+this.queueRotationUpdateByCount,this.queueRotationUpdateCount=0,this.queueRotationUpdateToCount=0,this.queueRotationUpdateByCount=0,null!==this.nextRotation){const update={destination:this.nextRotation,type:"destination"};return this.nextRotation=null,this.delta=0,this.observable.notify(update),update}if(0!==this.delta){const update={delta:this.delta,type:"delta"};return this.delta=0,this.observable.notify(update),update}return null}subscribe(observer,options){return this.observable.subscribe(observer,options)}getDebugInfo(){return{lastUpdateTotalCalls:this.lastUpdateCount,queueRotationUpdateCalls:this.queueRotationUpdateCount,queueRotationUpdateToCalls:this.queueRotationUpdateToCount,queueRotationUpdateByCalls:this.queueRotationUpdateByCount}}}class CameraRigWithUpdateBatcher{constructor(config,camera=new DefaultBoardCamera){this._panBy=createDefaultPanByHandler(),this._panTo=createDefaultPanToHandler(),this._zoomTo=createDefaultZoomToOnlyHandler(),this._zoomBy=createDefaultZoomByOnlyHandler(),this._rotateBy=createDefaultRotateByHandler(),this._rotateTo=createDefaultRotateToHandler(),this._config=Object.assign(Object.assign({},config),{restrictRotation:!1,clampRotation:!0}),this._camera=camera,this._positionBatcher=new CameraPositionUpdateBatcher,this._zoomBatcher=new CameraZoomUpdateBatcher,this._rotationBatcher=new CameraRotationUpdateBatcher}zoomToAt(targetZoom,at){this._zoomBatcher.queueZoomUpdateTo(targetZoom,at)}zoomByAt(delta,at){this._zoomBatcher.queueZoomUpdateBy(delta,at)}zoomTo(targetZoom){this._zoomBatcher.queueZoomUpdateTo(targetZoom)}zoomBy(delta){this._zoomBatcher.queueZoomUpdateBy(delta)}zoomToAtWorld(targetZoom,at){this._zoomBatcher.queueZoomToAtWorld(targetZoom,at)}zoomByAtWorld(delta,at){this._zoomBatcher.queueZoomByAtWorld(delta,at)}_actualPanByWorld(delta){const transformedDelta=this._panBy(delta,this._camera,this._config);this._camera.setPosition(PointCal.addVector(this._camera.position,transformedDelta))}_actualPanToWorld(target){const transformedTarget=this._panTo(target,this._camera,this._config);this._camera.setPosition(transformedTarget)}panByWorld(delta){this._positionBatcher.queuePositionUpdateBy(delta)}panByViewPort(delta){const diffInWorld=PointCal.multiplyVectorByScalar(PointCal.rotatePoint(delta,this._camera.rotation),1/this._camera.zoomLevel);this._positionBatcher.queuePositionUpdateBy(diffInWorld)}panToWorld(target){this._positionBatcher.queuePositionUpdateTo(target)}panToViewPort(target){const targetInWorld=this._camera.convertFromViewPort2WorldSpace(target);this._positionBatcher.queuePositionUpdateTo(targetInWorld)}rotateBy(delta){this._rotationBatcher.queueRotationUpdateBy(delta)}rotateTo(target){this._rotationBatcher.queueRotationUpdateTo(target)}set limitEntireViewPort(limit){this._config.limitEntireViewPort=limit}get limitEntireViewPort(){return this._config.limitEntireViewPort}get camera(){return this._camera}get config(){return this._config}set config(config){this._config=Object.assign({},config)}updatePosition(){const positionUpdate=this._positionBatcher.processQueuedUpdates();if(null!=positionUpdate)switch(positionUpdate.type){case"destination":this._actualPanToWorld(positionUpdate);break;case"delta":this._actualPanByWorld(positionUpdate);break;default:throw new Error("Invalid position update type")}}updateZoom(){const op=this._zoomBatcher.processQueuedUpdates();if(null!=op)if("world"===op.anchorCoordinateSystem)switch(op.update.type){case"destination":if(op.update.anchor)this._zoomToAtWorld(op.update.destination,op.update.anchor);else{const targetZoom=this._zoomTo(op.update.destination,this._camera,this._config);this._camera.setZoomLevel(targetZoom)}break;case"delta":if(op.update.anchor)this._zoomByAtWorld(op.update.delta,op.update.anchor);else{const transformedDelta=this._zoomBy(op.update.delta,this._camera,this._config);this._camera.setZoomLevel(this._camera.zoomLevel+transformedDelta)}}else switch(op.update.type){case"destination":if(op.update.anchor)this._zoomToAtViewPort(op.update.destination,op.update.anchor);else{const targetZoom=this._zoomTo(op.update.destination,this._camera,this._config);this._camera.setZoomLevel(targetZoom)}break;case"delta":if(op.update.anchor)this._zoomByAtViewPort(op.update.delta,op.update.anchor);else{const transformedDelta=this._zoomBy(op.update.delta,this._camera,this._config);this._camera.setZoomLevel(this._camera.zoomLevel+transformedDelta)}}}updateRotation(){const op=this._rotationBatcher.processQueuedUpdates();if(null!=op)switch(op.type){case"destination":const transformedTarget=this._rotateTo(op.destination,this._camera,this._config);this._camera.setRotation(transformedTarget);break;case"delta":const transformedDelta=this._rotateBy(op.delta,this._camera,this._config);this._camera.setRotation(this._camera.rotation+transformedDelta);break;default:throw new Error("Invalid rotation update type")}}update(){this.updateZoom(),this.updatePosition(),this.updateRotation()}_zoomToAtViewPort(targetZoom,at){const originalAnchorInWorld=this._camera.convertFromViewPort2WorldSpace(at),transformedTarget=this._zoomTo(targetZoom,this._camera,this._config);this._camera.setZoomLevel(transformedTarget);const anchorInWorldAfterZoom=this._camera.convertFromViewPort2WorldSpace(at),cameraPositionDiff=PointCal.subVector(originalAnchorInWorld,anchorInWorldAfterZoom),transformedCameraPositionDiff=this._panBy(cameraPositionDiff,this._camera,this._config);this._camera.setPosition(PointCal.addVector(this._camera.position,transformedCameraPositionDiff))}_zoomToAtWorld(targetZoom,at){let originalAnchorInViewPort=this._camera.convertFromWorld2ViewPort(at);const transformedTarget=this._zoomTo(targetZoom,this._camera,this._config);this._camera.setZoomLevel(transformedTarget);let anchorInViewPortAfterZoom=this._camera.convertFromWorld2ViewPort(at);const cameraPositionDiff=PointCal.subVector(originalAnchorInViewPort,anchorInViewPortAfterZoom),transformedCameraPositionDiff=this._panBy(cameraPositionDiff,this._camera,this._config);this._camera.setPosition(PointCal.addVector(this._camera.position,transformedCameraPositionDiff))}_zoomByAtViewPort(delta,at){const originalAnchorInWorld=this._camera.convertFromViewPort2WorldSpace(at),transformedDelta=this._zoomBy(delta,this._camera,this._config);this._camera.setZoomLevel(this._camera.zoomLevel+transformedDelta);const anchorInWorldAfterZoom=this._camera.convertFromViewPort2WorldSpace(at),cameraPositionDiff=PointCal.subVector(originalAnchorInWorld,anchorInWorldAfterZoom),transformedCameraPositionDiff=this._panBy(cameraPositionDiff,this._camera,this._config);this._camera.setPosition(PointCal.addVector(this._camera.position,transformedCameraPositionDiff))}_zoomByAtWorld(delta,at){let anchorInViewPortBeforeZoom=this._camera.convertFromWorld2ViewPort(at);const transformedDelta=this._zoomBy(delta,this._camera,this._config);this._camera.setZoomLevel(this._camera.zoomLevel+transformedDelta);let anchorInViewPortAfterZoom=this._camera.convertFromWorld2ViewPort(at);const diffInViewPort=PointCal.subVector(anchorInViewPortBeforeZoom,anchorInViewPortAfterZoom),diffInWorld=convertDeltaInViewPortToWorldSpace$1(diffInViewPort,this._camera.zoomLevel,this._camera.rotation),transformedDiff=this._panBy(diffInWorld,this._camera,this._config);this._camera.setPosition(PointCal.addVector(this._camera.position,transformedDiff))}configure(config){this._config=Object.assign(Object.assign({},this._config),config)}cleanup(){}setup(){}}function createDefaultCameraRigWithUpdateBatcher(camera){return new CameraRigWithUpdateBatcher({limitEntireViewPort:!0,restrictRelativeXTranslation:!1,restrictRelativeYTranslation:!1,restrictXTranslation:!1,restrictYTranslation:!1,restrictZoom:!1,clampTranslation:!0,clampZoom:!0},camera)}class DefaultCameraRig{constructor(config,camera=new DefaultBoardCamera){this._panBy=createDefaultPanByHandler(),this._panTo=createDefaultPanToHandler(),this._zoomTo=createDefaultZoomToOnlyHandler(),this._zoomBy=createDefaultZoomByOnlyHandler(),this._rotateBy=createDefaultRotateByHandler(),this._rotateTo=createDefaultRotateToHandler(),this._config=Object.assign(Object.assign({},config),{restrictRotation:!1,clampRotation:!0}),this._camera=camera}zoomToAt(targetZoom,at){let originalAnchorInWorld=this._camera.convertFromViewPort2WorldSpace(at);const transformTarget=this._zoomTo(targetZoom,this._camera,this._config);this._camera.setZoomLevel(transformTarget);let anchorInWorldAfterZoom=this._camera.convertFromViewPort2WorldSpace(at);const cameraPositionDiff=PointCal.subVector(originalAnchorInWorld,anchorInWorldAfterZoom),transformedCameraPositionDiff=this._panBy(cameraPositionDiff,this._camera,this._config);this._camera.setPosition(PointCal.addVector(this._camera.position,transformedCameraPositionDiff))}zoomByAt(delta,at){let originalAnchorInWorld=this._camera.convertFromViewPort2WorldSpace(at);const transformedDelta=this._zoomBy(delta,this._camera,this._config);this._camera.setZoomLevel(this._camera.zoomLevel+transformedDelta);let anchorInWorldAfterZoom=this._camera.convertFromViewPort2WorldSpace(at);const diff=PointCal.subVector(originalAnchorInWorld,anchorInWorldAfterZoom),transformedDiff=this._panBy(diff,this._camera,this._config);this._camera.setPosition(PointCal.addVector(this._camera.position,transformedDiff))}zoomTo(targetZoom){this._zoomTo(targetZoom,this._camera,this._config)}zoomBy(delta){this._zoomBy(delta,this._camera,this._config)}zoomToAtWorld(targetZoom,at){let originalAnchorInViewPort=this._camera.convertFromWorld2ViewPort(at);const transformedTarget=this._zoomTo(targetZoom,this._camera,this._config);this._camera.setZoomLevel(transformedTarget);let anchorInViewPortAfterZoom=this._camera.convertFromWorld2ViewPort(at);const cameraPositionDiffInViewPort=PointCal.subVector(anchorInViewPortAfterZoom,originalAnchorInViewPort),cameraPositionDiffInWorld=convertDeltaInViewPortToWorldSpace$1(cameraPositionDiffInViewPort,this._camera.zoomLevel,this._camera.rotation),transformedCameraPositionDiff=this._panBy(cameraPositionDiffInWorld,this._camera,this._config);this._camera.setPosition(PointCal.addVector(this._camera.position,transformedCameraPositionDiff))}zoomByAtWorld(delta,at){let anchorInViewPortBeforeZoom=this._camera.convertFromWorld2ViewPort(at);const transformedDelta=this._zoomBy(delta,this._camera,this._config);this._camera.setZoomLevel(this._camera.zoomLevel+transformedDelta);let anchorInViewPortAfterZoom=this._camera.convertFromWorld2ViewPort(at);const diffInViewPort=PointCal.subVector(anchorInViewPortAfterZoom,anchorInViewPortBeforeZoom),diffInWorld=convertDeltaInViewPortToWorldSpace$1(diffInViewPort,this._camera.zoomLevel,this._camera.rotation),transformedDiff=this._panBy(diffInWorld,this._camera,this._config);this._camera.setPosition(PointCal.addVector(this._camera.position,transformedDiff))}panByViewPort(delta){const diffInWorld=PointCal.multiplyVectorByScalar(PointCal.rotatePoint(delta,this._camera.rotation),1/this._camera.zoomLevel),transformedDelta=this._panBy(diffInWorld,this._camera,this._config);this._camera.setPosition(PointCal.addVector(this._camera.position,transformedDelta))}panByWorld(delta){const diffInViewPort=this._camera.convertFromWorld2ViewPort(delta);this.panByViewPort(diffInViewPort)}panToWorld(target){const transformedTarget=this._panTo(target,this._camera,this._config);this._camera.setPosition(transformedTarget)}panToViewPort(target){const targetInWorld=this._camera.convertFromViewPort2WorldSpace(target);this.panToWorld(targetInWorld)}rotateBy(delta){const transformedDelta=this._rotateBy(delta,this._camera,this._config);this._camera.setRotation(this._camera.rotation+transformedDelta)}rotateTo(target){const transformedTarget=this._rotateTo(target,this._camera,this._config);this._camera.setRotation(transformedTarget)}set limitEntireViewPort(limit){this._config.limitEntireViewPort=limit}get limitEntireViewPort(){return this._config.limitEntireViewPort}get camera(){return this._camera}get config(){return this._config}set config(config){this._config=Object.assign({},config)}configure(config){this._config=Object.assign(Object.assign({},this._config),config)}cleanup(){}setup(){}update(){}}function createDefaultCameraRig(camera){return new DefaultCameraRig({limitEntireViewPort:!0,restrictRelativeXTranslation:!1,restrictRelativeYTranslation:!1,restrictXTranslation:!1,restrictYTranslation:!1,restrictZoom:!1,clampTranslation:!0,clampZoom:!0},camera)}export{BaseCamera,CameraPositionUpdateBatcher,CameraRigWithUpdateBatcher,CameraRotationUpdateBatcher,CameraUpdatePublisher,CameraZoomUpdateBatcher,ContextCentricCamera,DEFAULT_BOARD_CAMERA_BOUNDARIES,DEFAULT_BOARD_CAMERA_ROTATION_BOUNDARIES,DEFAULT_BOARD_CAMERA_VIEWPORT_HEIGHT,DEFAULT_BOARD_CAMERA_VIEWPORT_WIDTH,DEFAULT_BOARD_CAMERA_ZOOM_BOUNDARIES,DefaultCameraRig,angleSpan,boundariesFullyDefined,cameraPositionToGet,clampByHandler,clampPoint,clampPointEntireViewPort,clampRotateByHandler,clampRotateToHandler,clampRotation,clampToHandler,clampZoomByHandler,clampZoomLevel,clampZoomToHandler,convert2ViewPortSpaceAnchorAtCenter,convert2WorldSpace,convert2WorldSpaceAnchorAtCenter,convert2WorldSpaceWRT,convert2WorldSpaceWithTransformationMatrix,convertDeltaInViewPortToWorldSpace,convertDeltaInWorldToViewPortSpace,convertDeltaToComplyWithRestriction,convertUserInputDeltaToCameraDelta,createCameraMatrix,createDefaultCameraRig,createDefaultCameraRigWithUpdateBatcher,createDefaultPanByHandler,createDefaultPanToHandler,createDefaultRotateByHandler,createDefaultRotateToHandler,createDefaultZoomByOnlyHandler,createDefaultZoomToOnlyHandler,decomposeCam