UNPKG

ue-too

Version:

pan, zoom, and rotate your html canvas

3 lines (2 loc) 8.94 kB
import{PointCal}from"point2point";function calculateOrderOfMagnitude(value){if(value<=0)return 0;let count=0;if(value<1){let divisor=1;for(;divisor>value;)divisor/=10,count--}else{let divisor=1;for(;10*divisor<=value;)divisor*=10,count++}return count}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)))))}}function createHandlerChain(...handlers){const normalizedHandlers=Array.isArray(handlers[0])?handlers[0]:handlers;return(value,...args)=>normalizedHandlers.reduce(((acc,handler)=>handler(acc,...args)),value)}function drawArrow(context,cameraZoomLevel,startPoint,endPoint,width=1,arrowRatio=.3){const length=PointCal.distanceBetweenPoints(startPoint,endPoint),arrowHeight=10<length*cameraZoomLevel*.5?10/cameraZoomLevel:.5*length,offsetLength=length-arrowHeight,offsetPoint=PointCal.linearInterpolation(startPoint,endPoint,offsetLength/length);context.beginPath(),context.lineWidth=width/cameraZoomLevel,context.moveTo(startPoint.x,startPoint.y),context.lineTo(offsetPoint.x,offsetPoint.y),context.stroke();const unitVector=PointCal.rotatePoint(PointCal.unitVectorFromA2B(endPoint,startPoint),Math.PI/2),arrowPoint1=PointCal.addVector(offsetPoint,PointCal.multiplyVectorByScalar(unitVector,.5*arrowHeight)),arrowPoint2=PointCal.subVector(offsetPoint,PointCal.multiplyVectorByScalar(unitVector,.5*arrowHeight));context.beginPath(),context.moveTo(endPoint.x,endPoint.y),context.lineTo(arrowPoint1.x,arrowPoint1.y),context.lineTo(arrowPoint2.x,arrowPoint2.y),context.closePath(),context.fill()}const MAJOR_TICK_LENGTH=30,MINOR_TICK_LENGTH=9,HALF_TICK_LENGTH=15,TEXT_MAJOR_TICK_OFFSET=10,TEXT_HALF_TICK_OFFSET=2.5,TEXT_MAJOR_TICK_FONT_SIZE=20,TEXT_HALF_TICK_FONT_SIZE=10;function drawRuler(context,topLeftCorner,topRightCorner,bottomLeftCorner,alignCoordinateSystem,cameraZoomLevel){const{minMajorTickValue:minMajorTickValue,maxMajorTickValue:maxMajorTickValue,majorTickStep:majorTickStep,minMinTickValue:minMinTickValue,maxMaxTickValue:maxMaxTickValue,minTickStep:minTickStep,minHalfTickValue:minHalfTickValue,maxHalfTickValue:maxHalfTickValue,halfTickStep:halfTickStep,calibrationMultiplier:calibrationMultiplier,normalizedOrderOfMagnitude:normalizedOrderOfMagnitude}=calculateTickValues(topLeftCorner.x,topRightCorner.x);context.save(),context.strokeStyle="red";for(let i=minMajorTickValue;i<=maxMajorTickValue;i+=majorTickStep){drawXAxisTick(context,cameraZoomLevel,{x:i*calibrationMultiplier,y:topLeftCorner.y},alignCoordinateSystem?30/cameraZoomLevel:-30/cameraZoomLevel,i*calibrationMultiplier,{textOffset:alignCoordinateSystem?10/cameraZoomLevel:-10/cameraZoomLevel,fontSize:20})}for(let i=minMinTickValue;i<=maxMaxTickValue;i+=minTickStep){if(i%majorTickStep==0)continue;if(i%halfTickStep==0)continue;drawXAxisTick(context,cameraZoomLevel,{x:i*calibrationMultiplier,y:topLeftCorner.y},alignCoordinateSystem?9/cameraZoomLevel:-9/cameraZoomLevel,i)}for(let i=minHalfTickValue;i<=maxHalfTickValue;i+=halfTickStep){if(i%majorTickStep==0)continue;drawXAxisTick(context,cameraZoomLevel,{x:i*calibrationMultiplier,y:topLeftCorner.y},alignCoordinateSystem?15/cameraZoomLevel:-15/cameraZoomLevel,i*calibrationMultiplier,{textOffset:alignCoordinateSystem?2.5/cameraZoomLevel:-2.5/cameraZoomLevel,fontSize:10,color:"red"})}context.restore();const{minMajorTickValue:vMinMajorTickValue,maxMajorTickValue:vMaxMajorTickValue,majorTickStep:vMajorTickStep,minMinTickValue:vMinMinTickValue,maxMaxTickValue:vMaxMaxTickValue,minTickStep:vMinTickStep,minHalfTickValue:vMinHalfTickValue,maxHalfTickValue:vMaxHalfTickValue,halfTickStep:vHalfTickStep,calibrationMultiplier:vCalibrationMultiplier}=calculateTickValues(topLeftCorner.y,bottomLeftCorner.y,normalizedOrderOfMagnitude);context.save(),context.strokeStyle="green";for(let i=vMinMajorTickValue;i<=vMaxMajorTickValue;i+=vMajorTickStep){drawYAxisTick(context,cameraZoomLevel,{x:topLeftCorner.x,y:i*vCalibrationMultiplier},30/cameraZoomLevel,i,{textOffset:10/cameraZoomLevel,fontSize:20})}for(let i=vMinHalfTickValue;i<=vMaxHalfTickValue;i+=vHalfTickStep){if(i%vMajorTickStep==0)continue;drawYAxisTick(context,cameraZoomLevel,{x:topLeftCorner.x,y:i*vCalibrationMultiplier},15/cameraZoomLevel,i,{textOffset:2.5/cameraZoomLevel,fontSize:10})}for(let i=vMinMinTickValue;i<=vMaxMaxTickValue;i+=vMinTickStep){if(i%vMajorTickStep==0)continue;drawYAxisTick(context,cameraZoomLevel,{x:topLeftCorner.x,y:i*vCalibrationMultiplier},9/cameraZoomLevel,i)}context.restore()}function drawYAxisTick(context,cameraZoomLevel,majorTickPoint,majorTickLength,tickValue,textOption){var _a;const drawText=void 0!==textOption;if(context.save(),context.lineWidth=1/cameraZoomLevel,context.beginPath(),context.moveTo(majorTickPoint.x,majorTickPoint.y),context.lineTo(majorTickPoint.x+majorTickLength,majorTickPoint.y),context.stroke(),context.restore(),!drawText)return;const color=null!==(_a=textOption.color)&&void 0!==_a?_a:"green";context.save(),context.textAlign="left",context.textBaseline="middle",context.fillStyle=color,context.font=textOption.fontSize/cameraZoomLevel+"px Arial";const tickValueText=tickValue%1==0?tickValue:tickValue.toFixed(2);context.fillText(`${tickValueText}`,majorTickPoint.x+majorTickLength+textOption.textOffset,majorTickPoint.y),context.restore()}function drawXAxisTick(context,cameraZoomLevel,majorTickPoint,majorTickLength,tickValue,textOption){var _a;const drawText=void 0!==textOption;if(context.save(),context.lineWidth=1/cameraZoomLevel,context.beginPath(),context.moveTo(majorTickPoint.x,majorTickPoint.y),context.lineTo(majorTickPoint.x,majorTickPoint.y+majorTickLength),context.stroke(),context.restore(),!drawText)return;const color=null!==(_a=textOption.color)&&void 0!==_a?_a:"red";context.save(),context.textAlign="center",context.textBaseline="top",context.fillStyle=color,context.font=textOption.fontSize/cameraZoomLevel+"px Arial";const tickValueText=tickValue%1==0?tickValue:tickValue.toFixed(2);context.fillText(`${tickValueText}`,majorTickPoint.x,majorTickPoint.y+majorTickLength+textOption.textOffset),context.restore()}function calculateTickValues(minValue,maxValue,orderOfMagnitude){const trueMinValue=Math.min(minValue,maxValue),trueMaxValue=Math.max(minValue,maxValue),trueOrderOfMagnitude=orderOfMagnitude||calculateOrderOfMagnitude(trueMaxValue-trueMinValue),normalizedOrderOfMagnitude=Math.max(1,trueOrderOfMagnitude),calibrationMultiplier=Math.pow(10,normalizedOrderOfMagnitude-trueOrderOfMagnitude),minMajorTickValue=(minValue>0?Math.floor(trueMinValue*calibrationMultiplier/Math.pow(10,normalizedOrderOfMagnitude)):Math.ceil(trueMinValue*calibrationMultiplier/Math.pow(10,normalizedOrderOfMagnitude)))*Math.pow(10,normalizedOrderOfMagnitude),maxMajorTickValue=(maxValue>0?Math.floor(trueMaxValue*calibrationMultiplier/Math.pow(10,normalizedOrderOfMagnitude)):Math.ceil(trueMaxValue*calibrationMultiplier/Math.pow(10,normalizedOrderOfMagnitude)))*Math.pow(10,normalizedOrderOfMagnitude),majorTickStep=Math.pow(10,normalizedOrderOfMagnitude),minTickOrderOfMagnitude=normalizedOrderOfMagnitude-1,halfTickStep=majorTickStep/2;return{minMajorTickValue:minMajorTickValue,maxMajorTickValue:maxMajorTickValue,majorTickStep:majorTickStep,minMinTickValue:(minValue>0?Math.floor(trueMinValue*calibrationMultiplier/Math.pow(10,minTickOrderOfMagnitude)):Math.ceil(trueMinValue*calibrationMultiplier/Math.pow(10,minTickOrderOfMagnitude)))*Math.pow(10,minTickOrderOfMagnitude),maxMaxTickValue:(maxValue>0?Math.floor(trueMaxValue*calibrationMultiplier/Math.pow(10,minTickOrderOfMagnitude)):Math.ceil(trueMaxValue*calibrationMultiplier/Math.pow(10,minTickOrderOfMagnitude)))*Math.pow(10,minTickOrderOfMagnitude),minTickStep:Math.pow(10,minTickOrderOfMagnitude),minHalfTickValue:(minValue>0?Math.floor(trueMinValue*calibrationMultiplier/halfTickStep):Math.ceil(trueMinValue*calibrationMultiplier/halfTickStep))*halfTickStep,maxHalfTickValue:(maxValue>0?Math.floor(trueMaxValue*calibrationMultiplier/halfTickStep):Math.ceil(trueMaxValue*calibrationMultiplier/halfTickStep))*halfTickStep,halfTickStep:halfTickStep,calibrationMultiplier:1/calibrationMultiplier,normalizedOrderOfMagnitude:normalizedOrderOfMagnitude}}export{HALF_TICK_LENGTH,MAJOR_TICK_LENGTH,MINOR_TICK_LENGTH,Observable,TEXT_HALF_TICK_FONT_SIZE,TEXT_HALF_TICK_OFFSET,TEXT_MAJOR_TICK_FONT_SIZE,TEXT_MAJOR_TICK_OFFSET,calculateOrderOfMagnitude,calculateTickValues,createHandlerChain,drawArrow,drawRuler}; //# sourceMappingURL=index.js.map