diff --git a/index.html b/index.html
index 6613bf0..4ae5d46 100644
--- a/index.html
+++ b/index.html
@@ -2,14 +2,29 @@
-
- Motion
+
+ Entity Component System Animation Engine - Gaston Morixe
+
+ Entity Component System (ECS)
+ Physics Animation Engine (WIP)
+
+ by Gaston Morixe 2024
+ Github Repo
+ - MIT
+
+
1
2
3
-
+
+
+
diff --git a/src/dom.ts b/src/dom.ts
index 6480c49..b4bde18 100644
--- a/src/dom.ts
+++ b/src/dom.ts
@@ -91,27 +91,14 @@ export class DOMComponent extends Component {
}
export class DOMUpdateSystem extends System {
- private domLinks: Map = new Map();
-
- // Link an entity with a DOM element
- linkEntityToDOM(entity: Entity, domElement: HTMLElement) {
- this.domLinks.set(entity.id, domElement);
- }
-
// Update the DOM element positions based on the entity's position component
update(entities: Entity[]) {
entities.forEach((entity) => {
- // const position = entity.getComponent(PositionComponent);
- // if (position && this.domLinks.has(entity.id)) {
- // const domElement = this.domLinks.get(entity.id);
- // if (domElement) {
- // domElement.style.left = `${position.x}px`;
- // domElement.style.top = `${position.y}px`;
- // }
- // }
const position = entity.getComponent(PositionComponent);
- if (position && this.domLinks.has(entity.id)) {
- const domElement = this.domLinks.get(entity.id);
+ const domComponent = entity.getComponent(DOMComponent);
+
+ if (position && domComponent) {
+ const domElement = domComponent.domElement;
if (domElement) {
domElement.style.transform = `translate(${position.x}px, ${position.y}px)`;
}
diff --git a/src/entities.ts b/src/entities.ts
new file mode 100644
index 0000000..c55e1ab
--- /dev/null
+++ b/src/entities.ts
@@ -0,0 +1,52 @@
+import { Entity } from "./ecs";
+import {
+ PositionComponent,
+ VelocityComponent,
+ ForceComponent,
+ FrictionComponent,
+ MassComponent,
+ AccumulatedForceComponent,
+} from "./components";
+import { DOMComponent, MouseDragComponent } from "./dom";
+
+// Define BoxEntity to represent a box that can be dragged
+export class BoxEntity extends Entity {
+ constructor(
+ domElement: HTMLElement,
+ initialPositon: { x: number; y: number },
+ name?: string,
+ initialVelocity: { vx: number; vy: number } = { vx: 0, vy: 0 },
+ mass: number = 1,
+ friction: number = 0.05,
+ ) {
+ super();
+
+ this.name = name;
+ this.addComponent(
+ new PositionComponent(initialPositon.x, initialPositon.y),
+ ); // Initial position
+ this.addComponent(
+ new VelocityComponent(initialVelocity.vx, initialVelocity.vy),
+ ); // Initial velocity
+ this.addComponent(new MassComponent(mass)); // Mass of the entity
+ this.addComponent(new ForceComponent()); // Force acting on the entity
+ this.addComponent(new AccumulatedForceComponent()); // Force acting on the entity
+ this.addComponent(new MouseDragComponent()); // Component for mouse dragging
+ this.addComponent(new FrictionComponent(friction)); // Friction acting on the entity
+ this.addComponent(new DOMComponent(domElement)); // DOM element associated with the entity
+ }
+}
+
+// Define an AnchorEntity to represent a fixed anchor point
+export class AnchorEntity extends Entity {
+ constructor(initialPositon: { x: number; y: number }, name?: string) {
+ super();
+ this.name = name;
+ this.addComponent(
+ new PositionComponent(initialPositon.x, initialPositon.y),
+ ); // Initial position
+ this.addComponent(new VelocityComponent(0, 0)); // Initial velocity
+ this.addComponent(new ForceComponent()); // Force acting on the entity
+ this.addComponent(new AccumulatedForceComponent()); // Force acting on the entity
+ }
+}
diff --git a/src/main.ts b/src/main.ts
index f8a0ed1..ecd8ed0 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -4,97 +4,49 @@ import "./style.css";
import { AnimationEngine } from "./engine";
// ECS
-import { Entity } from "./ecs";
-import {
- PositionComponent,
- VelocityComponent,
- MassComponent,
- ForceComponent,
- AccumulatedForceComponent,
- FrictionComponent,
-} from "./components";
import { MovementSystem, FrictionSystem } from "./systems";
-// Specific Components and Systems
-import {
- MouseDragComponent,
- MouseForceSystem,
- DOMComponent,
- DOMUpdateSystem,
- DOMMouseDragHandler,
-} from "./dom";
+// Specialized Systems and Entities
+import { MouseForceSystem, DOMUpdateSystem, DOMMouseDragHandler } from "./dom";
+import { BoxEntity, AnchorEntity } from "./entities";
import { SpringEntity, SpringPhysicsSystem } from "./spring";
import { ChartSystem } from "./chart";
//
-// Application Logic
+// -- Entities --
//
-// Create the ECS engine
-const engine = new AnimationEngine();
-
// Create the box entity
-const boxEntity = new Entity();
-boxEntity.name = "box1";
-boxEntity.addComponent(new PositionComponent(100, 100)); // Initial position
-boxEntity.addComponent(new VelocityComponent(0, 0)); // Initial velocity
-boxEntity.addComponent(new MassComponent(1)); // Mass of the entity
-boxEntity.addComponent(new ForceComponent()); // Force acting on the entity
-boxEntity.addComponent(new AccumulatedForceComponent()); // Force acting on the entity TODO: may not be needed
-boxEntity.addComponent(new MouseDragComponent()); // Component for mouse dragging
-boxEntity.addComponent(new FrictionComponent(0.05));
-
const boxElement = document.getElementById("box1") as HTMLElement;
-boxEntity.addComponent(new DOMComponent(boxElement));
+const boxEntity = new BoxEntity(boxElement, { x: 100, y: 100 }, "box1");
-// Creating the spring force
-const anchorEntity = new Entity();
-anchorEntity.name = "anchor";
-anchorEntity.addComponent(new PositionComponent(100, 100)); // Fixed point for the spring
-anchorEntity.addComponent(new VelocityComponent(0, 0)); // Initial velocity of the anchor point
-anchorEntity.addComponent(new ForceComponent()); // Force acting on the anchor point
-anchorEntity.addComponent(new AccumulatedForceComponent()); // Force acting on the anchor point
+// Creating a fixed anchor
+const anchorEntity = new AnchorEntity({ x: 100, y: 100 }, "anchor");
-// Create a spring entity that connects entityA and entityB
+// Create a spring entity that connects box1 and anchor
const springEntity = new SpringEntity(boxEntity, anchorEntity, 0.2, 0.05, 1.0);
springEntity.name = "spring";
// Create second box entity
-const boxEntity2 = new Entity();
-boxEntity2.name = "box2";
-boxEntity2.addComponent(new PositionComponent(250, 100)); // Initial position
-boxEntity2.addComponent(new VelocityComponent(0, 0)); // Initial velocity
-boxEntity2.addComponent(new MassComponent(1)); // Mass of the entity
-boxEntity2.addComponent(new ForceComponent()); // Force acting on the entity
-boxEntity2.addComponent(new AccumulatedForceComponent()); // Force acting on the entity TODO: may not be needed
-boxEntity2.addComponent(new MouseDragComponent()); // Component for mouse dragging
-boxEntity2.addComponent(new FrictionComponent(0.05));
-
const boxElement2 = document.getElementById("box2") as HTMLElement;
-boxEntity2.addComponent(new DOMComponent(boxElement2));
+const boxEntity2 = new BoxEntity(boxElement2, { x: 250, y: 100 }, "box2");
// Creating the spring force connecting box and box2
const springEntity2 = new SpringEntity(boxEntity, boxEntity2, 0.2, 0.05, 2.0);
springEntity2.name = "spring2";
// Create third box entity
-const boxEntity3 = new Entity();
-boxEntity3.name = "box3";
-boxEntity3.addComponent(new PositionComponent(400, 100)); // Initial position
-boxEntity3.addComponent(new VelocityComponent(0, 0)); // Initial velocity
-boxEntity3.addComponent(new MassComponent(1)); // Mass of the entity
-boxEntity3.addComponent(new ForceComponent()); // Force acting on the entity
-boxEntity3.addComponent(new AccumulatedForceComponent()); // Force acting on the entity
-boxEntity3.addComponent(new MouseDragComponent()); // Component for mouse dragging
-boxEntity3.addComponent(new FrictionComponent(0.05));
-
const boxElement3 = document.getElementById("box3") as HTMLElement;
-boxEntity3.addComponent(new DOMComponent(boxElement3));
+const boxEntity3 = new BoxEntity(boxElement3, { x: 400, y: 100 }, "box3");
// Creating the spring force connecting box2 and box3
const springEntity3 = new SpringEntity(boxEntity2, boxEntity3, 0.1, 0.05, 1.0);
springEntity3.name = "spring3";
+//
+// --- Systems ---
+//
+
// Set up the movement system (handles physics and movement)
const movementSystem = new MovementSystem();
@@ -109,9 +61,6 @@ const mouseForceSystem = new MouseForceSystem(0.2, 0.1); // Drag strength and da
// Set up the DOM update system (handles syncing the DOM with the entity position)
const domUpdateSystem = new DOMUpdateSystem();
-domUpdateSystem.linkEntityToDOM(boxEntity, boxElement);
-domUpdateSystem.linkEntityToDOM(boxEntity2, boxElement2);
-domUpdateSystem.linkEntityToDOM(boxEntity3, boxElement3);
// Set up the DOM mouse drag handler to handle mouse events via the DOM component
const domMouseDragHandler = new DOMMouseDragHandler();
@@ -123,6 +72,13 @@ domMouseDragHandler2.initializeDragListeners(boxEntity2);
const domMouseDragHandler3 = new DOMMouseDragHandler();
domMouseDragHandler3.initializeDragListeners(boxEntity3);
+//
+// -- Engine --
+//
+
+// Create the ECS engine
+const engine = new AnimationEngine();
+
// Add Entities to the engine
engine.addEntity(anchorEntity);
engine.addEntity(boxEntity);
diff --git a/src/style.css b/src/style.css
index 75bd84f..849550f 100644
--- a/src/style.css
+++ b/src/style.css
@@ -4,7 +4,8 @@
font-weight: 400;
/*color-scheme: light dark;*/
- color: rgba(255, 255, 255, 0.87);
+ /*color: rgba(255, 255, 255, 0.87);*/
+ color: black;
background-color: #fff;
font-synthesis: none;
@@ -13,6 +14,23 @@
-moz-osx-font-smoothing: grayscale;
}
+html,
+body {
+ width: 100%;
+ position: relative;
+ height: 100%;
+}
+
+h1 {
+ margin: 0;
+}
+h2 {
+ margin: 0;
+}
+p {
+ margin: 0;
+}
+
.box {
--bg-color: blue;
background-color: var(--bg-color);
@@ -33,6 +51,7 @@
justify-content: center;
font-size: 1.5rem;
font-weight: 600;
+ color: white;
&.dragging {
cursor: grabbing;
box-shadow: 0 15px 15px rgba(0, 0, 0, 0.15);
@@ -47,10 +66,23 @@
--bg-color: green;
}
-#chart {
+#chart-container {
pointer-events: none;
user-select: none;
position: absolute;
bottom: 20px;
- width: 100%;
+ width: calc(100% - 20px);
+ left: 0;
+ right: 0;
+ height: 90%;
+ /*background-color: yellow;*/
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-end;
+ z-index: -1;
+ canvas {
+ /*height: 100%;*/
+ width: 100%;
+ /*background-color: green;*/
+ }
}