@niuee/board
Version:
<h1 align="center"> board </h1> <p align="center"> board supercharges your html canvas element giving it the capabilities to pan, zoom, rotate, and much more. </p> <p align="center"> <a href="https://www.npmjs.com/package/@niuee/board">
3 lines (2 loc) • 5.7 kB
JavaScript
import{PointCal}from"point2point";function createHandlerChain(...handlers){const normalizedHandlers=Array.isArray(handlers[0])?handlers[0]:handlers;return(value,...args)=>normalizedHandlers.reduce(((acc,handler)=>handler(acc,...args)),value)}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 clampPoint(point,boundaries){if(function(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}(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 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 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)}export{clampByHandler,clampToHandler,convertDeltaToComplyWithRestriction,convertUserInputDeltaToCameraDelta,createDefaultPanByHandler,createDefaultPanToHandler,restrictPanByHandler,restrictPanToHandler};
//# sourceMappingURL=index.js.map