Implement isAnchor basics properties + fix IsRigidbody

This commit is contained in:
Eric NGUYEN 2022-08-12 14:15:40 +02:00
parent 42d6d30763
commit 0b41f7ac2c
10 changed files with 89 additions and 31 deletions

View file

@ -2,7 +2,7 @@ import { Dispatch, SetStateAction } from 'react';
import { IConfiguration } from '../../Interfaces/IConfiguration'; import { IConfiguration } from '../../Interfaces/IConfiguration';
import { ContainerModel } from '../../Interfaces/IContainerModel'; import { ContainerModel } from '../../Interfaces/IContainerModel';
import { fetchConfiguration } from '../API/api'; import { fetchConfiguration } from '../API/api';
import { IEditorState } from "../../Interfaces/IEditorState"; import { IEditorState } from '../../Interfaces/IEditorState';
import { LoadState } from './Load'; import { LoadState } from './Load';
export function NewEditor( export function NewEditor(
@ -23,6 +23,7 @@ export function NewEditor(
width: configuration.MainContainer.Width, width: configuration.MainContainer.Width,
height: configuration.MainContainer.Height, height: configuration.MainContainer.Height,
isRigidBody: false, isRigidBody: false,
isAnchor: false,
fillOpacity: 0, fillOpacity: 0,
stroke: 'black' stroke: 'black'
} }

View file

@ -0,0 +1,23 @@
/**
* @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
*/
/**
* Impose the container position
* Apply the following modification to the overlapping rigid body container :
*
*/
export function ImposePosition(){
}

View file

@ -1,5 +1,13 @@
import { IContainerModel } from '../../Interfaces/IContainerModel'; /**
import { ISizePointer } from '../../Interfaces/ISizePointer'; * @module RigidBodyBehaviors
* Apply the following contraints to the `container` :
* - The container must be kept inside its parent
* - The container must find an unallocated space within the parent
* If the contraints fails, an error message will be returned
*/
import { IContainerModel } from '../../../Interfaces/IContainerModel';
import { ISizePointer } from '../../../Interfaces/ISizePointer';
/** /**
* "Transform the container into a rigid body" * "Transform the container into a rigid body"
@ -179,17 +187,18 @@ function getAvailableWidths(
const width = Number(container.properties.width); const width = Number(container.properties.width);
let unallocatedSpaces: ISizePointer[] = [{ x, width }]; let unallocatedSpaces: ISizePointer[] = [{ x, width }];
// We will only uses containers that also have the rigid bodies // We will only uses containers that also are rigid or are anchors
// as out-of-bound or enormouse containers should be ignored const solidBodies = container.children.filter(
const rigidBodies = container.children.filter( (child) => child.properties.isRigidBody || child.properties.isAnchor
(child) => child.properties.isRigidBody
); );
for (const child of rigidBodies) { for (const child of solidBodies) {
// Ignore the exception // Ignore the exception
if (child === exception) { if (child === exception) {
continue; continue;
} }
const childX = child.properties.x;
const childWidth = Number(child.properties.width);
// get the space of the child that is inside the parent // get the space of the child that is inside the parent
let newUnallocatedSpace: ISizePointer[] = []; let newUnallocatedSpace: ISizePointer[] = [];
@ -202,8 +211,8 @@ function getAvailableWidths(
const newUnallocatedWidths = getAvailableWidthsTwoLines( const newUnallocatedWidths = getAvailableWidthsTwoLines(
unallocatedSpace.x, unallocatedSpace.x,
unallocatedSpace.x + unallocatedSpace.width, unallocatedSpace.x + unallocatedSpace.width,
child.properties.x, childX,
child.properties.x + Number(child.properties.width) childX + childWidth
); );
// Concat the new list of SizePointer pointing to availables spaces // Concat the new list of SizePointer pointing to availables spaces
@ -262,7 +271,7 @@ function getAvailableWidthsTwoLines(
width: min2 - min1 width: min2 - min1
}, },
{ {
x: min2, x: max2,
width: max1 - max2 width: max1 - max2
} }
]; ];

View file

@ -4,6 +4,7 @@ import { IConfiguration } from '../../Interfaces/IConfiguration';
import { ContainerModel, IContainerModel } from '../../Interfaces/IContainerModel'; import { ContainerModel, IContainerModel } from '../../Interfaces/IContainerModel';
import { findContainerById } from '../../utils/itertools'; import { findContainerById } from '../../utils/itertools';
import { getCurrentHistory } from './Editor'; import { getCurrentHistory } from './Editor';
import IProperties from '../../Interfaces/IProperties';
/** /**
* Select a container * Select a container
@ -203,20 +204,23 @@ export function AddContainer(
} }
} }
const defaultProperties: IProperties = {
id: `${type}-${count}`,
parentId: parentClone.properties.id,
x,
y: 0,
width: properties.Width,
height: parentClone.properties.height,
isRigidBody: false,
isAnchor: false,
XPositionReference: properties.XPositionReference,
...properties.Style
};
// Create the container // Create the container
const newContainer = new ContainerModel( const newContainer = new ContainerModel(
parentClone, parentClone,
{ defaultProperties,
id: `${type}-${count}`,
parentId: parentClone.properties.id,
x,
y: 0,
width: properties?.Width,
height: parentClone.properties.height,
isRigidBody: false,
XPositionReference: properties.XPositionReference,
...properties.Style
},
[], [],
{ {
type type

View file

@ -4,6 +4,7 @@ import { IHistoryState } from '../../Interfaces/IHistoryState';
import IProperties from '../../Interfaces/IProperties'; import IProperties from '../../Interfaces/IProperties';
import { findContainerById } from '../../utils/itertools'; import { findContainerById } from '../../utils/itertools';
import { getCurrentHistory } from './Editor'; import { getCurrentHistory } from './Editor';
import { RecalculatePhysics } from './Behaviors/RigidBodyBehaviors';
import { INPUT_TYPES } from '../Properties/PropertiesInputTypes'; import { INPUT_TYPES } from '../Properties/PropertiesInputTypes';
/** /**

View file

@ -17,7 +17,8 @@ describe.concurrent('Elements sidebar', () => {
y: 0, y: 0,
width: 2000, width: 2000,
height: 100, height: 100,
isRigidBody: false isRigidBody: false,
isAnchor: false
}, },
userData: {} userData: {}
}} }}
@ -47,7 +48,8 @@ describe.concurrent('Elements sidebar', () => {
y: 0, y: 0,
width: 2000, width: 2000,
height: 100, height: 100,
isRigidBody: false isRigidBody: false,
isAnchor: false
}, },
userData: {} userData: {}
}; };
@ -103,7 +105,8 @@ describe.concurrent('Elements sidebar', () => {
y: 0, y: 0,
width: 2000, width: 2000,
height: 100, height: 100,
isRigidBody: false isRigidBody: false,
isAnchor: false
}, },
userData: {} userData: {}
}; };
@ -119,7 +122,8 @@ describe.concurrent('Elements sidebar', () => {
y: 0, y: 0,
width: 0, width: 0,
height: 0, height: 0,
isRigidBody: false isRigidBody: false,
isAnchor: false
}, },
userData: {} userData: {}
} }
@ -136,7 +140,8 @@ describe.concurrent('Elements sidebar', () => {
y: 0, y: 0,
width: 0, width: 0,
height: 0, height: 0,
isRigidBody: false isRigidBody: false,
isAnchor: false
}, },
userData: {} userData: {}
} }
@ -173,7 +178,8 @@ describe.concurrent('Elements sidebar', () => {
y: 0, y: 0,
width: 2000, width: 2000,
height: 100, height: 100,
isRigidBody: false isRigidBody: false,
isAnchor: false
}, },
userData: {} userData: {}
}; };
@ -188,7 +194,8 @@ describe.concurrent('Elements sidebar', () => {
y: 0, y: 0,
width: 0, width: 0,
height: 0, height: 0,
isRigidBody: false isRigidBody: false,
isAnchor: false
}, },
userData: {} userData: {}
}; };

View file

@ -23,7 +23,8 @@ describe.concurrent('Properties', () => {
parentId: 'parentId', parentId: 'parentId',
x: 1, x: 1,
y: 1, y: 1,
isRigidBody: false isRigidBody: false,
isAnchor: false
}; };
const handleChange = vi.fn((key, value) => { const handleChange = vi.fn((key, value) => {

View file

@ -3,5 +3,6 @@ export const INPUT_TYPES: Record<string, string> = {
y: 'number', y: 'number',
width: 'number', width: 'number',
height: 'number', height: 'number',
isRigidBody: 'checkbox' isRigidBody: 'checkbox',
isAnchor: 'checkbox'
}; };

View file

@ -1,11 +1,21 @@
import * as React from 'react'; import * as React from 'react';
import { XPositionReference } from '../Enums/XPositionReference'; import { XPositionReference } from '../Enums/XPositionReference';
/**
* Properties of a container
* @property id id of the container
* @property parentId id of the parent container
* @property x horizontal offset of the container
* @property y vertical offset of the container
* @property isRigidBody if true apply rigid body behaviors
* @property isAnchor if true apply anchor behaviors
*/
export default interface IProperties extends React.CSSProperties { export default interface IProperties extends React.CSSProperties {
id: string id: string
parentId: string | null parentId: string | null
x: number x: number
y: number y: number
isRigidBody: boolean isRigidBody: boolean
isAnchor: boolean
XPositionReference?: XPositionReference XPositionReference?: XPositionReference
} }

View file

@ -33,6 +33,7 @@ export const DEFAULT_MAINCONTAINER_PROPS: IProperties = {
width: DEFAULT_CONFIG.MainContainer.Width, width: DEFAULT_CONFIG.MainContainer.Width,
height: DEFAULT_CONFIG.MainContainer.Height, height: DEFAULT_CONFIG.MainContainer.Height,
isRigidBody: false, isRigidBody: false,
isAnchor: false,
fillOpacity: 0, fillOpacity: 0,
stroke: 'black' stroke: 'black'
}; };