Drag-and-drop zones.
makeDragZone is an attempt to make setting up drag-and-drop functionality within a Scrawl-canvas stack or canvas as simple as possible. The functionality has been designed to allow multiple drag zones to be set on a canvas or stack element, while limiting the number of event listeners that need to be applied to the element to make the magic happen.
Required attribute of the argument object:
- .zone - either the String name of the Stack or Canvas artefact which will host the zone, or the Stack or Canvas artefact itself
Additional, optional, attributes in the argument object
- .coordinateSource - an object containing a
here object
- .coordinateSource - an object containing a
here object
- .collisionGroup - String name of Group object, or Group object itself
- .startOn - Array of Strings
- .endOn - Array of Strings
- .exposeCurrentArtefact - Boolean (default: false)
- .preventTouchDefaultWhenDragging - Boolean (default: false)
- .resetCoordsToZeroOnTouchEnd - Boolean (default: true)
At the heart of the drag zone are a set of functions (or alternatively, objects that can be applied to the selected artefact) which define the actions that happen when a user starts, continues and stops dragging an artefact in the zone. It is possible to set different actions depending on whether the user is pressing the shift button while they perform the drag action:
- .updateOnStart, .updateOnShiftStart - Function, or a
set object to be applied to the current artefact
- .updateOnEnd, .updateOnShiftEnd - Function, or a
set object to be applied to the current artefact
- .updateWhileMoving, .updateWhileShiftMoving - Function to be run while drag is in progress
- .updateOnPrematureExit - Function that will run when checks (defined in code elsewhere) trigger a premature exit from the drag zone. The triggering code can be used, for instance, to make sure an artefact does not leave a given area of the cell, within the canvas element boundaries
Multiple drag zones can be defined on a canvas or stack element. When a user presses the mouse button to start a drag the code will interrogate each drag zone in turn to discover if one of them has an artefact which collides with the mouse cursor; if yes, that drag zone takes precedence for the subsequent move and drop actions
- .processingOrder - positive integer Number - drag zones with a lower value will be interrogated ahead of those with a higher value
If the exposeCurrentArtefact attribute is true, the makeDragZone factory returns a function that can be invoked at any time to get the collision data object (containing x, y, artefact attributes) for the artefact being dragged (false if nothing is being dragged). The function can also be triggered with the following string arguments:
'exit' or 'drop - force the drag action to end
- any other truthy argument - kill the drag zone object. If it was the only drag zone object associated with a given canvas or stack element then the event listeners will also be removed from the element
- null, undefined, any other falsy argument - return the collision data object
If the exposeCurrentArtefact attribute is false, or omitted, the function returns a kill function that can be invoked (with no arguments) to remove the event listeners from the Stack or Canvas zone’s DOM element.
import * as library from "../core/library.js";
import { xta, isa_fn, isa_boolean, isa_obj, λnull, Ωempty } from "../helper/utilities.js";
import { addListener, removeListener } from "../core/events.js";
import { touchAction } from "../core/user-interaction.js";