import Configuration from "../Configuration" import IElement from "./IElement" import Utility from "../Utility" /** * @typedef {import("../entity/IEntity").default} IEntity * @typedef {import("../template/IDraggableTemplate").default} IDraggableTemplate * @typedef {import("lit").PropertyValues} PropertyValues */ /** * @template {IEntity} T * @template {IDraggableTemplate} U * @extends {IElement} */ export default class IDraggableElement extends IElement { static properties = { ...super.properties, locationX: { type: Number, attribute: false, }, locationY: { type: Number, attribute: false, }, sizeX: { type: Number, attribute: false, }, sizeY: { type: Number, attribute: false, }, } static dragEventName = Configuration.dragEventName static dragGeneralEventName = Configuration.dragGeneralEventName constructor() { super() this.locationX = 0 this.locationY = 0 this.sizeX = 0 this.sizeY = 0 } computeSizes() { const scaleCorrection = 1 / this.blueprint.getScale() const bounding = this.getBoundingClientRect() this.sizeX = bounding.width * scaleCorrection this.sizeY = bounding.height * scaleCorrection } /** @param {PropertyValues} changedProperties */ firstUpdated(changedProperties) { super.firstUpdated(changedProperties) this.computeSizes() } /** @param {Number[]} param0 */ setLocation([x, y], acknowledge = true) { const d = [x - this.locationX, y - this.locationY] this.locationX = x this.locationY = y if (this.blueprint && acknowledge) { const dragLocalEvent = new CustomEvent( /** @type {typeof IDraggableElement} */(this.constructor).dragEventName, { detail: { value: d, }, bubbles: false, cancelable: true, } ) this.dispatchEvent(dragLocalEvent) } } /** @param {Number[]} param0 */ addLocation([x, y], acknowledge = true) { this.setLocation([this.locationX + x, this.locationY + y], acknowledge) } /** @param {Number[]} value */ acknowledgeDrag(value) { const dragEvent = new CustomEvent( /** @type {typeof IDraggableElement} */(this.constructor).dragGeneralEventName, { detail: { value: value }, bubbles: true, cancelable: true } ) this.dispatchEvent(dragEvent) } snapToGrid() { const snappedLocation = Utility.snapToGrid([this.locationX, this.locationY], Configuration.gridSize) if (this.locationX != snappedLocation[0] || this.locationY != snappedLocation[1]) { this.setLocation(snappedLocation) } } topBoundary(justSelectableArea = false) { return this.template.topBoundary(justSelectableArea) } rightBoundary(justSelectableArea = false) { return this.template.rightBoundary(justSelectableArea) } bottomBoundary(justSelectableArea = false) { return this.template.bottomBoundary(justSelectableArea) } leftBoundary(justSelectableArea = false) { return this.template.leftBoundary(justSelectableArea) } }