/** * @module AnchorBehavior * * An anchor is a container that takes physical priority in the representation : * - It cannot be moved by other rigid siblings container * - It cannot be resized by any other siblings container * - It cannot overlap any other siblings rigid container : * - overlapping container are shifted to the nearest available space/width * - or resized when there is no available space left other than theirs * - or lose their rigid body properties when there is no available space left) * Meaning that: * - Moving an anchor container will resize the width of an overlapping container * or make them lose their property as a rigid body */ import { IContainerModel } from '../../../Interfaces/IContainerModel'; import { constraintBodyInsideUnallocatedWidth } from './RigidBodyBehaviors'; /** * Impose the container position to its siblings * Apply the following modification to the overlapping rigid body container : * @param container Container to impose its position */ export function ApplyAnchor(container: IContainerModel): IContainerModel { if (container.parent === undefined || container.parent === null) { return container; } const rigidBodies = container.parent.children.filter( child => child.properties.isRigidBody && !child.properties.isAnchor ); const overlappingContainers = getOverlappingContainers(container, rigidBodies); for (const overlappingContainer of overlappingContainers) { constraintBodyInsideUnallocatedWidth(overlappingContainer); } return container; } /** * Returns the overlapping containers with container * @param container A container * @param containers A list of containers * @returns A list of overlapping containers */ function getOverlappingContainers( container: IContainerModel, containers: IContainerModel[] ): IContainerModel[] { const min1 = container.properties.x; const max1 = container.properties.x + container.properties.width; const overlappingContainers: IContainerModel[] = []; for (const other of containers) { if (other === container) { continue; } const min2 = other.properties.x; const max2 = other.properties.x + other.properties.width; const isOverlapping = Math.min(max1, max2) - Math.max(min1, min2) > 0; if (!isOverlapping) { continue; } overlappingContainers.push(other); } return overlappingContainers; }