fabric
Version:
Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.
1 lines • 14.4 kB
Source Map (JSON)
{"version":3,"file":"ActiveSelection.mjs","sources":["../../../src/shapes/ActiveSelection.ts"],"sourcesContent":["import type { ControlRenderingStyleOverride } from '../controls/controlRendering';\nimport { classRegistry } from '../ClassRegistry';\nimport type { GroupProps } from './Group';\nimport { Group } from './Group';\nimport type { FabricObject } from './Object/FabricObject';\nimport {\n LAYOUT_TYPE_ADDED,\n LAYOUT_TYPE_REMOVED,\n} from '../LayoutManager/constants';\nimport type { TClassProperties } from '../typedefs';\nimport { log } from '../util/internals/console';\nimport { ActiveSelectionLayoutManager } from '../LayoutManager/ActiveSelectionLayoutManager';\n\nexport type MultiSelectionStacking = 'canvas-stacking' | 'selection-order';\n\nexport interface ActiveSelectionOptions extends GroupProps {\n multiSelectionStacking: MultiSelectionStacking;\n}\n\nconst activeSelectionDefaultValues: Partial<TClassProperties<ActiveSelection>> =\n {\n multiSelectionStacking: 'canvas-stacking',\n };\n\n/**\n * Used by Canvas to manage selection.\n *\n * @example\n * class MyActiveSelection extends ActiveSelection {\n * ...\n * }\n *\n * // override the default `ActiveSelection` class\n * classRegistry.setClass(MyActiveSelection)\n */\nexport class ActiveSelection extends Group {\n static type = 'ActiveSelection';\n\n static ownDefaults: Record<string, any> = activeSelectionDefaultValues;\n\n static getDefaults(): Record<string, any> {\n return { ...super.getDefaults(), ...ActiveSelection.ownDefaults };\n }\n\n /**\n * The ActiveSelection needs to use the ActiveSelectionLayoutManager\n * or selections on interactive groups may be broken\n */\n declare layoutManager: ActiveSelectionLayoutManager;\n\n /**\n * controls how selected objects are added during a multiselection event\n * - `canvas-stacking` adds the selected object to the active selection while respecting canvas object stacking order\n * - `selection-order` adds the selected object to the top of the stack,\n * meaning that the stack is ordered by the order in which objects were selected\n * @default `canvas-stacking`\n */\n declare multiSelectionStacking: MultiSelectionStacking;\n\n constructor(\n objects: FabricObject[] = [],\n options: Partial<ActiveSelectionOptions> = {},\n ) {\n super();\n Object.assign(this, ActiveSelection.ownDefaults);\n this.setOptions(options);\n const { left, top, layoutManager } = options;\n this.groupInit(objects, {\n left,\n top,\n layoutManager: layoutManager ?? new ActiveSelectionLayoutManager(),\n });\n }\n\n /**\n * @private\n */\n _shouldSetNestedCoords() {\n return true;\n }\n\n /**\n * @private\n * @override we don't want the selection monitor to be active\n */\n __objectSelectionMonitor() {\n // noop\n }\n\n /**\n * Adds objects with respect to {@link multiSelectionStacking}\n * @param targets object to add to selection\n */\n multiSelectAdd(...targets: FabricObject[]) {\n if (this.multiSelectionStacking === 'selection-order') {\n this.add(...targets);\n } else {\n // respect object stacking as it is on canvas\n // perf enhancement for large ActiveSelection: consider a binary search of `isInFrontOf`\n targets.forEach((target) => {\n const index = this._objects.findIndex((obj) => obj.isInFrontOf(target));\n const insertAt =\n index === -1\n ? // `target` is in front of all other objects\n this.size()\n : index;\n this.insertAt(insertAt, target);\n });\n }\n }\n\n /**\n * @override block ancestors/descendants of selected objects from being selected to prevent a circular object tree\n */\n canEnterGroup(object: FabricObject) {\n if (\n this.getObjects().some(\n (o) => o.isDescendantOf(object) || object.isDescendantOf(o),\n )\n ) {\n // prevent circular object tree\n log(\n 'error',\n 'ActiveSelection: circular object trees are not supported, this call has no effect',\n );\n return false;\n }\n\n return super.canEnterGroup(object);\n }\n\n /**\n * Change an object so that it can be part of an active selection.\n * this method is called by multiselectAdd from canvas code.\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object is in canvas coordinate plane\n */\n enterGroup(object: FabricObject, removeParentTransform?: boolean) {\n // This condition check that the object has currently a group, and the group\n // is also its parent, meaning that is not in an active selection, but is\n // in a normal group.\n if (object.parent && object.parent === object.group) {\n // Disconnect the object from the group functionalities, but keep the ref parent intact\n // for later re-enter\n object.parent._exitGroup(object);\n // in this case the object is probably inside an active selection.\n } else if (object.group && object.parent !== object.group) {\n // in this case group.remove will also clear the old parent reference.\n object.group.remove(object);\n }\n // enter the active selection from a render perspective\n // the object will be in the objects array of both the ActiveSelection and the Group\n // but referenced in the group's _activeObjects so that it won't be rendered twice.\n this._enterGroup(object, removeParentTransform);\n }\n\n /**\n * we want objects to retain their canvas ref when exiting instance\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it\n */\n exitGroup(object: FabricObject, removeParentTransform?: boolean) {\n this._exitGroup(object, removeParentTransform);\n // return to parent\n object.parent && object.parent._enterGroup(object, true);\n }\n\n /**\n * @private\n * @param {'added'|'removed'} type\n * @param {FabricObject[]} targets\n */\n _onAfterObjectsChange(type: 'added' | 'removed', targets: FabricObject[]) {\n super._onAfterObjectsChange(type, targets);\n const groups = new Set<Group>();\n targets.forEach((object) => {\n const { parent } = object;\n parent && groups.add(parent);\n });\n if (type === LAYOUT_TYPE_REMOVED) {\n // invalidate groups' layout and mark as dirty\n groups.forEach((group) => {\n group._onAfterObjectsChange(LAYOUT_TYPE_ADDED, targets);\n });\n } else {\n // mark groups as dirty\n groups.forEach((group) => {\n group._set('dirty', true);\n });\n }\n }\n\n /**\n * @override remove all objects\n */\n onDeselect() {\n this.removeAll();\n return false;\n }\n\n /**\n * Returns string representation of a group\n * @return {String}\n */\n toString() {\n return `#<ActiveSelection: (${this.complexity()})>`;\n }\n\n /**\n * Decide if the object should cache or not. The Active selection never caches\n * @return {Boolean}\n */\n shouldCache() {\n return false;\n }\n\n /**\n * Check if this group or its parent group are caching, recursively up\n * @return {Boolean}\n */\n isOnACache() {\n return false;\n }\n\n /**\n * Renders controls and borders for the object\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} [styleOverride] properties to override the object style\n * @param {Object} [childrenOverride] properties to override the children overrides\n */\n _renderControls(\n ctx: CanvasRenderingContext2D,\n styleOverride?: ControlRenderingStyleOverride,\n childrenOverride?: ControlRenderingStyleOverride,\n ) {\n ctx.save();\n ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n const options = {\n hasControls: false,\n ...childrenOverride,\n forActiveSelection: true,\n };\n for (let i = 0; i < this._objects.length; i++) {\n this._objects[i]._renderControls(ctx, options);\n }\n super._renderControls(ctx, styleOverride);\n ctx.restore();\n }\n}\n\nclassRegistry.setClass(ActiveSelection);\nclassRegistry.setClass(ActiveSelection, 'activeSelection');\n"],"names":["activeSelectionDefaultValues","multiSelectionStacking","ActiveSelection","Group","getDefaults","_objectSpread","ownDefaults","constructor","objects","arguments","length","undefined","options","Object","assign","setOptions","left","top","layoutManager","groupInit","ActiveSelectionLayoutManager","_shouldSetNestedCoords","__objectSelectionMonitor","multiSelectAdd","_len","targets","Array","_key","add","forEach","target","index","_objects","findIndex","obj","isInFrontOf","insertAt","size","canEnterGroup","object","getObjects","some","o","isDescendantOf","log","enterGroup","removeParentTransform","parent","group","_exitGroup","remove","_enterGroup","exitGroup","_onAfterObjectsChange","type","groups","Set","LAYOUT_TYPE_REMOVED","LAYOUT_TYPE_ADDED","_set","onDeselect","removeAll","toString","concat","complexity","shouldCache","isOnACache","_renderControls","ctx","styleOverride","childrenOverride","save","globalAlpha","isMoving","borderOpacityWhenMoving","hasControls","forActiveSelection","i","restore","_defineProperty","classRegistry","setClass"],"mappings":"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"}