fabric
Version:
Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.
1 lines • 7 kB
Source Map (JSON)
{"version":3,"file":"controlRendering.min.mjs","sources":["../../../src/controls/controlRendering.ts"],"sourcesContent":["import { FILL, STROKE, twoMathPi } from '../constants';\nimport type { InteractiveFabricObject } from '../shapes/Object/InteractiveObject';\nimport { degreesToRadians } from '../util/misc/radiansDegreesConversion';\nimport type { Control } from './Control';\n\nexport type ControlRenderingStyleOverride = Partial<\n Pick<\n InteractiveFabricObject,\n | 'cornerStyle'\n | 'cornerSize'\n | 'cornerColor'\n | 'cornerStrokeColor'\n | 'cornerDashArray'\n | 'transparentCorners'\n >\n>;\n\nexport type ControlRenderer<\n O extends InteractiveFabricObject = InteractiveFabricObject,\n> = (\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride,\n fabricObject: O,\n) => void;\n\n/**\n * Render a round control, as per fabric features.\n * This function is written to respect object properties like transparentCorners, cornerSize\n * cornerColor, cornerStrokeColor\n * plus the addition of offsetY and offsetX.\n * @param {CanvasRenderingContext2D} ctx context to render on\n * @param {Number} left x coordinate where the control center should be\n * @param {Number} top y coordinate where the control center should be\n * @param {Object} styleOverride override for FabricObject controls style\n * @param {FabricObject} fabricObject the fabric object for which we are rendering controls\n */\nexport function renderCircleControl(\n this: Control,\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride,\n fabricObject: InteractiveFabricObject,\n) {\n styleOverride = styleOverride || {};\n const xSize =\n this.sizeX || styleOverride.cornerSize || fabricObject.cornerSize,\n ySize = this.sizeY || styleOverride.cornerSize || fabricObject.cornerSize,\n transparentCorners =\n typeof styleOverride.transparentCorners !== 'undefined'\n ? styleOverride.transparentCorners\n : fabricObject.transparentCorners,\n methodName = transparentCorners ? STROKE : FILL,\n stroke =\n !transparentCorners &&\n (styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor);\n let myLeft = left,\n myTop = top,\n size;\n ctx.save();\n ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor || '';\n ctx.strokeStyle =\n styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor || '';\n // TODO: use proper ellipse code.\n if (xSize > ySize) {\n size = xSize;\n ctx.scale(1.0, ySize / xSize);\n myTop = (top * xSize) / ySize;\n } else if (ySize > xSize) {\n size = ySize;\n ctx.scale(xSize / ySize, 1.0);\n myLeft = (left * ySize) / xSize;\n } else {\n size = xSize;\n }\n ctx.beginPath();\n ctx.arc(myLeft, myTop, size / 2, 0, twoMathPi, false);\n ctx[methodName]();\n if (stroke) {\n ctx.stroke();\n }\n ctx.restore();\n}\n\n/**\n * Render a square control, as per fabric features.\n * This function is written to respect object properties like transparentCorners, cornerSize\n * cornerColor, cornerStrokeColor\n * plus the addition of offsetY and offsetX.\n * @param {CanvasRenderingContext2D} ctx context to render on\n * @param {Number} left x coordinate where the control center should be\n * @param {Number} top y coordinate where the control center should be\n * @param {Object} styleOverride override for FabricObject controls style\n * @param {FabricObject} fabricObject the fabric object for which we are rendering controls\n */\nexport function renderSquareControl(\n this: Control,\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride,\n fabricObject: InteractiveFabricObject,\n) {\n styleOverride = styleOverride || {};\n const xSize =\n this.sizeX || styleOverride.cornerSize || fabricObject.cornerSize,\n ySize = this.sizeY || styleOverride.cornerSize || fabricObject.cornerSize,\n transparentCorners =\n typeof styleOverride.transparentCorners !== 'undefined'\n ? styleOverride.transparentCorners\n : fabricObject.transparentCorners,\n methodName = transparentCorners ? STROKE : FILL,\n stroke =\n !transparentCorners &&\n (styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor),\n xSizeBy2 = xSize / 2,\n ySizeBy2 = ySize / 2;\n ctx.save();\n ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor || '';\n ctx.strokeStyle =\n styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor || '';\n ctx.translate(left, top);\n // angle is relative to canvas plane\n const angle = fabricObject.getTotalAngle();\n ctx.rotate(degreesToRadians(angle));\n // this does not work, and fixed with ( && ) does not make sense.\n // to have real transparent corners we need the controls on upperCanvas\n // transparentCorners || ctx.clearRect(-xSizeBy2, -ySizeBy2, xSize, ySize);\n ctx[`${methodName}Rect`](-xSizeBy2, -ySizeBy2, xSize, ySize);\n if (stroke) {\n ctx.strokeRect(-xSizeBy2, -ySizeBy2, xSize, ySize);\n }\n ctx.restore();\n}\n"],"names":["renderCircleControl","ctx","left","top","styleOverride","fabricObject","xSize","this","sizeX","cornerSize","ySize","sizeY","transparentCorners","methodName","STROKE","FILL","stroke","cornerStrokeColor","size","myLeft","myTop","save","fillStyle","cornerColor","strokeStyle","scale","beginPath","arc","twoMathPi","restore","renderSquareControl","xSizeBy2","ySizeBy2","translate","angle","getTotalAngle","rotate","degreesToRadians","concat","strokeRect"],"mappings":"wJAsCO,SAASA,EAEdC,EACAC,EACAC,EACAC,EACAC,GAEAD,EAAgBA,GAAiB,GACjC,MAAME,EACFC,KAAKC,OAASJ,EAAcK,YAAcJ,EAAaI,WACzDC,EAAQH,KAAKI,OAASP,EAAcK,YAAcJ,EAAaI,WAC/DG,OAC8C,IAArCR,EAAcQ,mBACjBR,EAAcQ,mBACdP,EAAaO,mBACnBC,EAAaD,EAAqBE,EAASC,EAC3CC,GACGJ,IACAR,EAAca,mBAAqBZ,EAAaY,mBACrD,IAEEC,EAFEC,EAASjB,EACXkB,EAAQjB,EAEVF,EAAIoB,OACJpB,EAAIqB,UAAYlB,EAAcmB,aAAelB,EAAakB,aAAe,GACzEtB,EAAIuB,YACFpB,EAAca,mBAAqBZ,EAAaY,mBAAqB,GAEnEX,EAAQI,GACVQ,EAAOZ,EACPL,EAAIwB,MAAM,EAAKf,EAAQJ,GACvBc,EAASjB,EAAMG,EAASI,GACfA,EAAQJ,GACjBY,EAAOR,EACPT,EAAIwB,MAAMnB,EAAQI,EAAO,GACzBS,EAAUjB,EAAOQ,EAASJ,GAE1BY,EAAOZ,EAETL,EAAIyB,YACJzB,EAAI0B,IAAIR,EAAQC,EAAOF,EAAO,EAAG,EAAGU,GAAW,GAC/C3B,EAAIY,KACAG,GACFf,EAAIe,SAENf,EAAI4B,SACN,CAaO,SAASC,EAEd7B,EACAC,EACAC,EACAC,EACAC,GAEAD,EAAgBA,GAAiB,GACjC,MAAME,EACFC,KAAKC,OAASJ,EAAcK,YAAcJ,EAAaI,WACzDC,EAAQH,KAAKI,OAASP,EAAcK,YAAcJ,EAAaI,WAC/DG,OAC8C,IAArCR,EAAcQ,mBACjBR,EAAcQ,mBACdP,EAAaO,mBACnBC,EAAaD,EAAqBE,EAASC,EAC3CC,GACGJ,IACAR,EAAca,mBAAqBZ,EAAaY,mBACnDc,EAAWzB,EAAQ,EACnB0B,EAAWtB,EAAQ,EACrBT,EAAIoB,OACJpB,EAAIqB,UAAYlB,EAAcmB,aAAelB,EAAakB,aAAe,GACzEtB,EAAIuB,YACFpB,EAAca,mBAAqBZ,EAAaY,mBAAqB,GACvEhB,EAAIgC,UAAU/B,EAAMC,GAEpB,MAAM+B,EAAQ7B,EAAa8B,gBAC3BlC,EAAImC,OAAOC,EAAiBH,IAI5BjC,EAAGqC,GAAAA,OAAIzB,YAAmBkB,GAAWC,EAAU1B,EAAOI,GAClDM,GACFf,EAAIsC,YAAYR,GAAWC,EAAU1B,EAAOI,GAE9CT,EAAI4B,SACN"}