UNPKG

fabric

Version:

Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.

1 lines 3.81 kB
{"version":3,"file":"rotate.min.mjs","names":[],"sources":["../../../src/controls/rotate.ts"],"sourcesContent":["import type {\n ControlCursorCallback,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport { ROTATING } from '../constants';\nimport { radiansToDegrees } from '../util/misc/radiansDegreesConversion';\nimport { isLocked, NOT_ALLOWED_CURSOR } from './util';\nimport { wrapWithFireEvent } from './wrapWithFireEvent';\nimport { wrapWithFixedAnchor } from './wrapWithFixedAnchor';\n\n/**\n * Find the correct style for the control that is used for rotation.\n * this function is very simple and it just take care of not-allowed or standard cursor\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {Control} control the control that is interested in the action\n * @param {FabricObject} fabricObject the fabric object that is interested in the action\n * @return {String} a valid css string for the cursor\n */\nexport const rotationStyleHandler: ControlCursorCallback = (\n eventData,\n control,\n fabricObject,\n) => {\n if (fabricObject.lockRotation) {\n return NOT_ALLOWED_CURSOR;\n }\n return control.cursorStyle;\n};\n\n/**\n * Action handler for rotation and snapping, without anchor point.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n * @private\n */\nconst rotateObjectWithSnapping: TransformActionHandler = (\n eventData,\n { target, ex, ey, theta, originX, originY },\n x,\n y,\n) => {\n const pivotPoint = target.getPositionByOrigin(originX, originY);\n\n if (isLocked(target, 'lockRotation')) {\n return false;\n }\n\n const lastAngle = Math.atan2(ey - pivotPoint.y, ex - pivotPoint.x),\n curAngle = Math.atan2(y - pivotPoint.y, x - pivotPoint.x);\n let angle = radiansToDegrees(curAngle - lastAngle + theta);\n\n if (target.snapAngle && target.snapAngle > 0) {\n const snapAngle = target.snapAngle,\n snapThreshold = target.snapThreshold || snapAngle,\n rightAngleLocked = Math.ceil(angle / snapAngle) * snapAngle,\n leftAngleLocked = Math.floor(angle / snapAngle) * snapAngle;\n\n if (Math.abs(angle - leftAngleLocked) < snapThreshold) {\n angle = leftAngleLocked;\n } else if (Math.abs(angle - rightAngleLocked) < snapThreshold) {\n angle = rightAngleLocked;\n }\n }\n\n // normalize angle to positive value\n if (angle < 0) {\n angle = 360 + angle;\n }\n angle %= 360;\n\n const hasRotated = target.angle !== angle;\n // TODO: why aren't we using set?\n target.angle = angle;\n return hasRotated;\n};\n\nexport const rotationWithSnapping = wrapWithFireEvent(\n ROTATING,\n wrapWithFixedAnchor(rotateObjectWithSnapping),\n);\n"],"mappings":"uUAkBA,MAAa,GACX,EACA,EACA,IAEI,EAAa,aACR,EAEF,EAAQ,YAsDJ,EAAuB,EAClC,EACA,GA1CA,EAAA,CACE,OAAA,EAAQ,GAAA,EAAI,GAAA,EAAI,MAAA,EAAO,QAAA,EAAS,QAAA,GAClC,EACA,IAAA,CAEA,IAAM,EAAa,EAAO,oBAAoB,EAAS,EAAA,CAEvD,GAAI,EAAS,EAAQ,eAAA,CACnB,MAAA,CAAO,EAGT,IAAM,EAAY,KAAK,MAAM,EAAK,EAAW,EAAG,EAAK,EAAW,EAAA,CAE5D,EAAQ,EADC,KAAK,MAAM,EAAI,EAAW,EAAG,EAAI,EAAW,EAAA,CACjB,EAAY,EAAA,CAEpD,GAAI,EAAO,WAAa,EAAO,UAAY,EAAG,CAC5C,IAAM,EAAY,EAAO,UACvB,EAAgB,EAAO,eAAiB,EACxC,EAAmB,KAAK,KAAK,EAAQ,EAAA,CAAa,EAClD,EAAkB,KAAK,MAAM,EAAQ,EAAA,CAAa,EAEhD,KAAK,IAAI,EAAQ,EAAA,CAAmB,EACtC,EAAQ,EACC,KAAK,IAAI,EAAQ,EAAA,CAAoB,IAC9C,EAAQ,GAKR,EAAQ,IACV,EAAQ,IAAM,GAEhB,GAAS,IAET,IAAM,EAAa,EAAO,QAAU,EAGpC,MADA,GAAO,MAAQ,EACR,GAAA,CAAA,CAAA,OAAA,KAAA,qBAAA,KAAA"}