From 2e8df0ad7922489a13669a2d31aba7aab9617339 Mon Sep 17 00:00:00 2001
From: "Daniel B."
Date: Wed, 12 Mar 2025 20:26:34 -0600
Subject: [PATCH 1/7] =?UTF-8?q?=F0=9F=A7=B9=20Chore:=20Refactor=20Particle?=
=?UTF-8?q?s=20model?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Implement strategy design pattern
---
.vscode/settings.json | 1 +
src/app/layout.jsx | 18 +-
src/frontend/ui/components/atoms/Head.jsx | 4 +-
.../molecules}/Canvas/index.css | 0
.../molecules}/Canvas/index.jsx | 2 +-
.../molecules}/Canvas/layout.jsx | 2 +-
.../molecules}/Model/index.jsx | 13 +-
src/frontend/ui/models/Graph/index.jsx | 21 ++
.../Particles/components/atoms/Box/index.jsx | 24 +++
.../components/atoms/Camera/index.jsx | 24 +++
.../components/atoms/Camera/logic/setup.js | 16 ++
.../components/atoms/Circle/index.jsx | 29 +++
.../components/atoms/Circle/logic/update.js | 8 +
.../components/atoms/Controls/index.jsx | 10 +
.../components/atoms/Mouse/logic/handler.js | 34 ++++
.../components/atoms/Mouse/logic/listener.js | 13 ++
.../components/atoms/Mouse/logic/update.js | 10 +
.../components/atoms/Mouse/updates/color.js | 11 ++
.../atoms/Mouse/updates/position.js | 11 ++
.../atoms/Particles/effects/chaos/effect.js | 21 ++
.../atoms/Particles/effects/chaos/update.js | 8 +
.../atoms/Particles/effects/color/effect.js | 11 ++
.../atoms/Particles/effects/color/update.js | 11 ++
.../Particles/effects/expansion/effect.js | 19 ++
.../Particles/effects/flotation/effect.js | 19 ++
.../Particles/effects/interpolation/effect.js | 20 ++
.../Particles/effects/position/effect.js | 24 +++
.../Particles/effects/position/update.js | 11 ++
.../atoms/Particles/effects/resize/resize.js | 22 +++
.../components/atoms/Particles/index.jsx | 16 ++
.../components/atoms/Particles/logic/setup.js | 65 +++++++
.../atoms/Particles/logic/update.js | 41 ++++
.../components/atoms/Plane/index.jsx | 23 +++
.../components/atoms/Plane/logic/setup.js | 9 +
.../components/atoms/RayLine/index.jsx | 19 ++
.../components/atoms/RayLine/logic/line.js | 12 ++
.../components/atoms/Raycaster/index.jsx | 8 +
.../components/atoms/Raycaster/logic/setup.js | 8 +
.../atoms/Raycaster/logic/update.js | 12 ++
.../components/molecules/ParticleSystem.jsx | 42 ++++
.../components/organisms/ParticlesScene.jsx | 44 +++++
.../ui/models/Particles/config/index.js | 61 ++++++
.../hooks.jsx => Particles/hooks/useArgs.jsx} | 9 +-
src/frontend/ui/models/Particles/index.jsx | 23 +++
.../models/Particles/logic/effects/manager.js | 31 +++
.../Particles/logic/effects/strategy.js | 13 ++
.../Particles/logic/handlers/manager.js | 59 ++++++
.../Particles/logic/handlers/strategy.js | 14 ++
.../ui/models/Particles/logic/index.js | 61 ++++++
.../Particles/logic/listeners/manager.js | 38 ++++
.../Particles/logic/listeners/resize.js | 11 ++
.../Particles/logic/listeners/strategy.js | 22 +++
.../models/Particles/logic/setups/manager.js | 33 ++++
.../models/Particles/logic/setups/strategy.js | 13 ++
.../models/Particles/logic/updates/manager.js | 55 ++++++
.../Particles/logic/updates/strategy.js | 13 ++
.../ui/models/molecule/Particles/effects.js | 124 ------------
.../ui/models/molecule/Particles/index.jsx | 160 ---------------
.../ui/models/molecule/Particles/logic.js | 133 -------------
.../ui/models/molecule/Particles/setups.js | 131 -------------
.../ui/models/molecule/Particles/updates.js | 182 ------------------
61 files changed, 1151 insertions(+), 751 deletions(-)
create mode 100644 .vscode/settings.json
rename src/frontend/ui/{models/atoms => components/molecules}/Canvas/index.css (100%)
rename src/frontend/ui/{models/atoms => components/molecules}/Canvas/index.jsx (92%)
rename src/frontend/ui/{models/atoms => components/molecules}/Canvas/layout.jsx (93%)
rename src/frontend/ui/{models/atoms => components/molecules}/Model/index.jsx (68%)
create mode 100644 src/frontend/ui/models/Graph/index.jsx
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Box/index.jsx
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Camera/index.jsx
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Camera/logic/setup.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Circle/index.jsx
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Circle/logic/update.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Controls/index.jsx
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Mouse/logic/handler.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Mouse/logic/listener.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Mouse/logic/update.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Mouse/updates/color.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Mouse/updates/position.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos/effect.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos/update.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/color/effect.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/color/update.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/expansion/effect.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/flotation/effect.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/interpolation/effect.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/position/effect.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/position/update.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/resize/resize.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/index.jsx
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/logic/setup.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/logic/update.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Plane/index.jsx
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Plane/logic/setup.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/RayLine/index.jsx
create mode 100644 src/frontend/ui/models/Particles/components/atoms/RayLine/logic/line.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Raycaster/index.jsx
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Raycaster/logic/setup.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Raycaster/logic/update.js
create mode 100644 src/frontend/ui/models/Particles/components/molecules/ParticleSystem.jsx
create mode 100644 src/frontend/ui/models/Particles/components/organisms/ParticlesScene.jsx
create mode 100644 src/frontend/ui/models/Particles/config/index.js
rename src/frontend/ui/models/{molecule/Particles/hooks.jsx => Particles/hooks/useArgs.jsx} (88%)
create mode 100644 src/frontend/ui/models/Particles/index.jsx
create mode 100644 src/frontend/ui/models/Particles/logic/effects/manager.js
create mode 100644 src/frontend/ui/models/Particles/logic/effects/strategy.js
create mode 100644 src/frontend/ui/models/Particles/logic/handlers/manager.js
create mode 100644 src/frontend/ui/models/Particles/logic/handlers/strategy.js
create mode 100644 src/frontend/ui/models/Particles/logic/index.js
create mode 100644 src/frontend/ui/models/Particles/logic/listeners/manager.js
create mode 100644 src/frontend/ui/models/Particles/logic/listeners/resize.js
create mode 100644 src/frontend/ui/models/Particles/logic/listeners/strategy.js
create mode 100644 src/frontend/ui/models/Particles/logic/setups/manager.js
create mode 100644 src/frontend/ui/models/Particles/logic/setups/strategy.js
create mode 100644 src/frontend/ui/models/Particles/logic/updates/manager.js
create mode 100644 src/frontend/ui/models/Particles/logic/updates/strategy.js
delete mode 100644 src/frontend/ui/models/molecule/Particles/effects.js
delete mode 100644 src/frontend/ui/models/molecule/Particles/index.jsx
delete mode 100644 src/frontend/ui/models/molecule/Particles/logic.js
delete mode 100644 src/frontend/ui/models/molecule/Particles/setups.js
delete mode 100644 src/frontend/ui/models/molecule/Particles/updates.js
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..9e26dfe
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/src/app/layout.jsx b/src/app/layout.jsx
index 5030cfc..5251ab1 100644
--- a/src/app/layout.jsx
+++ b/src/app/layout.jsx
@@ -26,11 +26,11 @@ import Head from "@semantyk/frontend/ui/components/atoms/Head";
import Body from "@semantyk/frontend/ui/components/molecules/Body";
import { getLang } from "@semantyk/frontend/logic/services/getLang";
import Content from "@semantyk/frontend/ui/components/molecules/Content";
-import Model from "@semantyk/frontend/ui/models/atoms/Model";
+import Model from "@semantyk/frontend/ui/components/molecules/Model";
//* Main
-export async function generateMetadata() {return await getMetadata();}
+export async function generateMetadata() { return await getMetadata(); }
export default function RootLayout({ children }) {
// Logic
@@ -39,13 +39,13 @@ export default function RootLayout({ children }) {
return (
// TODO: Add logic for dynamic language
-
-
-
-
- {children}
-
-
+
+
+
+ {children}
+
+
);
}
\ No newline at end of file
diff --git a/src/frontend/ui/components/atoms/Head.jsx b/src/frontend/ui/components/atoms/Head.jsx
index 2bfad07..0c880a8 100644
--- a/src/frontend/ui/components/atoms/Head.jsx
+++ b/src/frontend/ui/components/atoms/Head.jsx
@@ -22,7 +22,5 @@ import Analytics from "@semantyk/frontend/logic/analytics/Analytics";
//* Main
export default function Head() {
// Return
- return (<>
-
- >);
+ return ;
}
\ No newline at end of file
diff --git a/src/frontend/ui/models/atoms/Canvas/index.css b/src/frontend/ui/components/molecules/Canvas/index.css
similarity index 100%
rename from src/frontend/ui/models/atoms/Canvas/index.css
rename to src/frontend/ui/components/molecules/Canvas/index.css
diff --git a/src/frontend/ui/models/atoms/Canvas/index.jsx b/src/frontend/ui/components/molecules/Canvas/index.jsx
similarity index 92%
rename from src/frontend/ui/models/atoms/Canvas/index.jsx
rename to src/frontend/ui/components/molecules/Canvas/index.jsx
index ff58031..a1bd7b3 100644
--- a/src/frontend/ui/models/atoms/Canvas/index.jsx
+++ b/src/frontend/ui/components/molecules/Canvas/index.jsx
@@ -19,7 +19,7 @@
//* Imports
import React from "react";
//* Local Imports
-import CanvasLayout from "@semantyk/frontend/ui/models/atoms/Canvas/layout";
+import CanvasLayout from "@semantyk/frontend/ui/components/molecules/Canvas/layout";
//* Main
export default function Canvas({ children }) {
diff --git a/src/frontend/ui/models/atoms/Canvas/layout.jsx b/src/frontend/ui/components/molecules/Canvas/layout.jsx
similarity index 93%
rename from src/frontend/ui/models/atoms/Canvas/layout.jsx
rename to src/frontend/ui/components/molecules/Canvas/layout.jsx
index b0f8f69..b9cea6d 100644
--- a/src/frontend/ui/models/atoms/Canvas/layout.jsx
+++ b/src/frontend/ui/components/molecules/Canvas/layout.jsx
@@ -18,7 +18,7 @@
import React from "react";
import { Canvas } from "@react-three/fiber";
//* Local Imports
-import "@semantyk/frontend/ui/models/atoms/Canvas/index.css";
+import "@semantyk/frontend/ui/components/molecules/Canvas/index.css";
//* Main
export default function CanvasLayout(props) {
diff --git a/src/frontend/ui/models/atoms/Model/index.jsx b/src/frontend/ui/components/molecules/Model/index.jsx
similarity index 68%
rename from src/frontend/ui/models/atoms/Model/index.jsx
rename to src/frontend/ui/components/molecules/Model/index.jsx
index 230a9f9..80020bc 100644
--- a/src/frontend/ui/models/atoms/Model/index.jsx
+++ b/src/frontend/ui/components/molecules/Model/index.jsx
@@ -7,7 +7,7 @@
* @file: This file contains the logic for a generic Three.js model component.
*
* @created: Jul 17, 2024
- * @modified: Mar 7, 2025
+ * @modified: Mar 12, 2025
*
* @author: Semantyk Team
* @maintainer: Daniel Bakas
@@ -20,15 +20,20 @@
//* Imports
import React from "react";
-import Canvas from "@semantyk/frontend/ui/models/atoms/Canvas";
-import ParticlesModel from "@semantyk/frontend/ui/models/molecule/Particles";
+import Canvas from "@semantyk/frontend/ui/components/molecules/Canvas";
+import ParticlesModel from "@semantyk/frontend/ui/models/Particles";
+import GraphModel from "@semantyk/frontend/ui/models/Graph";
+import { usePathname } from "next/navigation";
//* Main
export default function Model() {
+ // Logic
+ const pathname = usePathname();
// Return
return (
);
};
\ No newline at end of file
diff --git a/src/frontend/ui/models/Graph/index.jsx b/src/frontend/ui/models/Graph/index.jsx
new file mode 100644
index 0000000..e2a95ba
--- /dev/null
+++ b/src/frontend/ui/models/Graph/index.jsx
@@ -0,0 +1,21 @@
+/**
+ * –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
+ * # `index.jsx` | `GraphModel`
+ * @organization: Semantyk
+ * @project: Client
+ *
+ * @file: This file contains the logic for the Graph model.
+ *
+ * @created: Mar 13, 2025
+ * @modified: Mar 13, 2025
+ *
+ * @author: Semantyk Team
+ * @maintainer: Daniel Bakas
+ *
+ * @copyright: Semantyk © 2025. All rights reserved.
+ * –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
+ */
+
+//* Main
+export default function GraphModel() {
+};
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Box/index.jsx b/src/frontend/ui/models/Particles/components/atoms/Box/index.jsx
new file mode 100644
index 0000000..a29a3bd
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Box/index.jsx
@@ -0,0 +1,24 @@
+/**
+ * Box.jsx
+ * Atom component for the box in the Particles model
+ */
+
+//* Main
+export default function Box({ config, data, refs }) {
+ // Props
+ const {
+ general: { showHelpers }
+ } = config;
+ // Return
+ return (
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Camera/index.jsx b/src/frontend/ui/models/Particles/components/atoms/Camera/index.jsx
new file mode 100644
index 0000000..636282d
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Camera/index.jsx
@@ -0,0 +1,24 @@
+/**
+ * Camera.jsx
+ * Atom component for the perspective camera in the Particles model
+ */
+
+import { PerspectiveCamera } from "@react-three/drei";
+import { CameraHelper } from "three";
+import { useHelper } from "@react-three/drei";
+
+export default function Camera({ config, refs }) {
+ // Props
+ const {
+ general: { showHelpers }
+ } = config;
+ // Logic
+ useHelper(showHelpers && refs.camera, CameraHelper);
+
+ return (
+
+ );
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Camera/logic/setup.js b/src/frontend/ui/models/Particles/components/atoms/Camera/logic/setup.js
new file mode 100644
index 0000000..93ada07
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Camera/logic/setup.js
@@ -0,0 +1,16 @@
+import { SetupStrategy } from '../../../../logic/setups/strategy';
+
+export class CameraSetup extends SetupStrategy {
+ apply({ config, data: { unit }, refs: { camera } }) {
+ const { camera: { margin } } = config;
+
+ const aspectRatio = window.innerWidth / window.innerHeight;
+ let x = (1 + margin) / ((aspectRatio >= 1) ? 2 : (2 * aspectRatio));
+ const fx = 2 * Math.atan(x) * (180 / Math.PI);
+
+ camera.current.fov = fx;
+ camera.current.aspect = aspectRatio;
+ camera.current.position.z = unit / 2;
+ camera.current.updateProjectionMatrix();
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Circle/index.jsx b/src/frontend/ui/models/Particles/components/atoms/Circle/index.jsx
new file mode 100644
index 0000000..a253cd2
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Circle/index.jsx
@@ -0,0 +1,29 @@
+/**
+ * Circle.jsx
+ * Atom component for the circle in the Particles model
+ */
+
+//* Main
+export default function Circle({ config, data, refs }) {
+ // Props
+ const {
+ general: { showHelpers },
+ animations: { chaos: { radius } }
+ } = config;
+ // Return
+ return (
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Circle/logic/update.js b/src/frontend/ui/models/Particles/components/atoms/Circle/logic/update.js
new file mode 100644
index 0000000..c00e734
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Circle/logic/update.js
@@ -0,0 +1,8 @@
+import { UpdateStrategy } from '../../../../logic/updates/strategy';
+
+export class CircleUpdate extends UpdateStrategy {
+ apply({ objects, refs, target }) {
+ objects.raycaster.ray.intersectPlane(refs.plane.current, target);
+ refs.circle.current.position.copy(target);
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Controls/index.jsx b/src/frontend/ui/models/Particles/components/atoms/Controls/index.jsx
new file mode 100644
index 0000000..bac1f01
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Controls/index.jsx
@@ -0,0 +1,10 @@
+//* Imports
+import { OrbitControls } from "@react-three/drei";
+
+//* Main
+export default function Controls({ config }) {
+ // Props
+ const { general: { showHelpers } } = config;
+ // Return
+ return showHelpers && ;
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/handler.js b/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/handler.js
new file mode 100644
index 0000000..ec9c24d
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/handler.js
@@ -0,0 +1,34 @@
+/**
+ * Mouse handler strategy for particle system
+ */
+
+import { HandlerStrategy } from '../../../../logic/handlers/strategy';
+import { updateOnMouseMove } from '../../../../logic/index';
+
+export class MouseHandler extends HandlerStrategy {
+ /**
+ * Handle mouse/touch move events
+ * @param {MouseEvent|TouchEvent} event - Mouse or touch event
+ * @param {Object} args - Particle system arguments
+ */
+ handle(event, args) {
+ const { mouse, moveMouseTimeout } = args.refs;
+ clearTimeout(moveMouseTimeout.current);
+ mouse.current.isMoving = true;
+ moveMouseTimeout.current = setTimeout(() => mouse.current.isMoving = false, 1);
+
+ let clientX, clientY;
+ if (event.type === "mousemove") {
+ clientX = event.clientX;
+ clientY = event.clientY;
+ } else if (event.type === "touchmove") {
+ clientX = event.touches[0].clientX;
+ clientY = event.touches[0].clientY;
+ }
+
+ updateOnMouseMove({
+ events: { mousemove: { clientX, clientY } },
+ ...args
+ });
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/listener.js b/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/listener.js
new file mode 100644
index 0000000..f5bdaa9
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/listener.js
@@ -0,0 +1,13 @@
+import { ListenerStrategy } from '../../../../logic/listeners/strategy';
+
+export class MouseListener extends ListenerStrategy {
+ add({ handleMouseMove }) {
+ window.addEventListener("mousemove", handleMouseMove);
+ window.addEventListener("touchmove", handleMouseMove);
+ }
+
+ remove({ handleMouseMove }) {
+ window.removeEventListener("mousemove", handleMouseMove);
+ window.removeEventListener("touchmove", handleMouseMove);
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/update.js b/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/update.js
new file mode 100644
index 0000000..564efd0
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/update.js
@@ -0,0 +1,10 @@
+import { onMouseMove } from "@semantyk/frontend/logic/services/callbacks";
+import { UpdateStrategy } from '../../../../logic/updates/strategy';
+
+export class MouseUpdate extends UpdateStrategy {
+ apply({ refs, events }) {
+ const { x, y } = onMouseMove(events.mousemove);
+ refs.mouse.current.x = x * 2 - 1;
+ refs.mouse.current.y = -y * 2 + 1;
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/color.js b/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/color.js
new file mode 100644
index 0000000..57bd581
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/color.js
@@ -0,0 +1,11 @@
+import { Color } from 'three';
+import { EffectManager } from '../../../../../logic/effects/manager';
+import { UpdateStrategy } from '../../../../../logic/updates/strategy';
+
+export class ColorUpdate extends UpdateStrategy {
+ apply({ i, colors, particles, ...args }) {
+ const final = new Color();
+ EffectManager.addEffect("color", { colors, particles, i, final, ...args });
+ colors.set(final.toArray(), i * 3);
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/position.js b/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/position.js
new file mode 100644
index 0000000..18e09e8
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/position.js
@@ -0,0 +1,11 @@
+import { Vector3 } from 'three';
+import { EffectManager } from '../../../../../logic/effects/manager';
+import { UpdateStrategy } from '../../../../../logic/updates/strategy';
+
+export class PositionUpdate extends UpdateStrategy {
+ apply({ object, positions, i, ...args }) {
+ const final = new Vector3();
+ EffectManager.addEffect("position", { positions, object, i, final, ...args });
+ positions.set(final.toArray(), i * 3);
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos/effect.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos/effect.js
new file mode 100644
index 0000000..59bacc9
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos/effect.js
@@ -0,0 +1,21 @@
+import { EffectStrategy } from '../../../../../logic/effects/strategy';
+
+export class ChaosEffect extends EffectStrategy {
+ apply({ config, data, i, idxs, mouse, particles }) {
+ const { unit } = data;
+ const { animations: { chaos, order } } = config;
+
+ let magnitude;
+ let currentChaos = particles.data.chaotic[i];
+
+ if (idxs.has(i) && mouse.current.isMoving) {
+ currentChaos += chaos.magnitude;
+ magnitude = Math.min(currentChaos, 1);
+ } else {
+ currentChaos -= order.magnitude / unit;
+ magnitude = Math.max(currentChaos, 0);
+ }
+
+ particles.data.chaotic[i] = magnitude;
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos/update.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos/update.js
new file mode 100644
index 0000000..1771b66
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos/update.js
@@ -0,0 +1,8 @@
+import { UpdateStrategy } from '../../../../../logic/updates/strategy';
+import { EffectManager } from '../../../../../logic/effects/manager';
+
+export class ChaosUpdate extends UpdateStrategy {
+ apply(params) {
+ EffectManager.addEffect("chaos", params);
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/color/effect.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/color/effect.js
new file mode 100644
index 0000000..5db63fe
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/color/effect.js
@@ -0,0 +1,11 @@
+import { Color } from 'three';
+import { EffectStrategy } from '../../../../../logic/effects/strategy';
+
+export class ColorEffect extends EffectStrategy {
+ apply({ particles, i, final, colors }) {
+ const chaoticValue = particles.data.chaotic[i];
+ const target = new Color(1, 0, 0);
+ final.lerp(target, chaoticValue);
+ colors.set(final.toArray(), i * 3);
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/color/update.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/color/update.js
new file mode 100644
index 0000000..57bd581
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/color/update.js
@@ -0,0 +1,11 @@
+import { Color } from 'three';
+import { EffectManager } from '../../../../../logic/effects/manager';
+import { UpdateStrategy } from '../../../../../logic/updates/strategy';
+
+export class ColorUpdate extends UpdateStrategy {
+ apply({ i, colors, particles, ...args }) {
+ const final = new Color();
+ EffectManager.addEffect("color", { colors, particles, i, final, ...args });
+ colors.set(final.toArray(), i * 3);
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/expansion/effect.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/expansion/effect.js
new file mode 100644
index 0000000..ca14ba3
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/expansion/effect.js
@@ -0,0 +1,19 @@
+import { Vector3 } from 'three';
+import { EffectStrategy } from '../../../../../logic/effects/strategy';
+
+export class ExpansionEffect extends EffectStrategy {
+ apply({ config, object, i, final }) {
+ const { animations: { expansion } } = config;
+ const chaosValue = object.data.chaotic[i];
+ const { ideal } = object.data.positions;
+ const positions = object.geometry.attributes.position.array;
+
+ const source = new Vector3().fromArray(positions, i * 3);
+ const target = new Vector3().fromArray(ideal, i * 3);
+ const effect = new Vector3().subVectors(source, target);
+ effect.multiplyScalar(chaosValue);
+ effect.multiplyScalar(expansion.magnitude);
+
+ final.add(effect);
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/flotation/effect.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/flotation/effect.js
new file mode 100644
index 0000000..a3d280e
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/flotation/effect.js
@@ -0,0 +1,19 @@
+import { Vector3 } from 'three';
+import { EffectStrategy } from '../../../../../logic/effects/strategy';
+
+export class FlotationEffect extends EffectStrategy {
+ apply({ config, object, i, final, time }) {
+ const { offsets } = object.data.positions;
+ const { animations: { flotation } } = config;
+
+ const vector = new Vector3().fromArray(offsets, i * 3);
+ vector.addScalar(time * flotation.speed);
+ const effect = new Vector3(
+ Math.sin(vector.x),
+ Math.sin(vector.y)
+ );
+ effect.multiplyScalar(flotation.magnitude);
+
+ final.add(effect);
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/interpolation/effect.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/interpolation/effect.js
new file mode 100644
index 0000000..3c138c3
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/interpolation/effect.js
@@ -0,0 +1,20 @@
+import { Vector3 } from 'three';
+import { ease } from "@semantyk/frontend/ui/models/Particles/logic";
+import { EffectStrategy } from '../../../../../logic/effects/strategy';
+
+export class InterpolationEffect extends EffectStrategy {
+ apply({ config, time, object, i, final }) {
+ const { ideal, initial } = object.data.positions;
+ const { animations: { interpolation: { duration } } } = config;
+
+ const source = new Vector3().fromArray(initial, i * 3);
+ const target = new Vector3().fromArray(ideal, i * 3);
+
+ const easedTime = ease(time, duration);
+ source.multiplyScalar(1 - easedTime);
+ target.multiplyScalar(easedTime);
+
+ final.add(source);
+ final.add(target);
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/position/effect.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/position/effect.js
new file mode 100644
index 0000000..8962ab4
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/position/effect.js
@@ -0,0 +1,24 @@
+import { EffectStrategy } from '../../../../../logic/effects/strategy';
+import { InterpolationEffect } from '../interpolation/effect';
+import { FlotationEffect } from '../flotation/effect';
+import { ExpansionEffect } from '../expansion/effect';
+
+export class PositionEffect extends EffectStrategy {
+ constructor() {
+ super();
+ this.interpolationEffect = new InterpolationEffect();
+ this.flotationEffect = new FlotationEffect();
+ this.expansionEffect = new ExpansionEffect();
+ }
+
+ apply(args) {
+ const { animations: { interpolation } } = args.config;
+
+ this.interpolationEffect.apply(args);
+ this.flotationEffect.apply(args);
+
+ if (args.time >= interpolation.duration) {
+ this.expansionEffect.apply(args);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/position/update.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/position/update.js
new file mode 100644
index 0000000..18e09e8
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/position/update.js
@@ -0,0 +1,11 @@
+import { Vector3 } from 'three';
+import { EffectManager } from '../../../../../logic/effects/manager';
+import { UpdateStrategy } from '../../../../../logic/updates/strategy';
+
+export class PositionUpdate extends UpdateStrategy {
+ apply({ object, positions, i, ...args }) {
+ const final = new Vector3();
+ EffectManager.addEffect("position", { positions, object, i, final, ...args });
+ positions.set(final.toArray(), i * 3);
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/resize/resize.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/resize/resize.js
new file mode 100644
index 0000000..93f3b52
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/resize/resize.js
@@ -0,0 +1,22 @@
+/**
+ * Resize handler strategy for particle system
+ */
+
+import { HandlerStrategy } from '../../../../../logic/handlers/strategy';
+import { SetupManager } from '../../../../../logic/setups/manager';
+
+export class ResizeHandler extends HandlerStrategy {
+ /**
+ * Handle window resize events
+ * @param {Event} event - Window resize event
+ * @param {Object} args - Particle system arguments
+ */
+ handle(event, args) {
+ const { particles } = args.refs;
+ SetupManager.setupObject("camera", args);
+ const { particle } = args.config;
+ const ratio = window.innerWidth / window.innerHeight;
+ const size = Math.min(Math.max(particle.size * ratio, 0), particle.size);
+ particles.current.material.size = size;
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/index.jsx b/src/frontend/ui/models/Particles/components/atoms/Particles/index.jsx
new file mode 100644
index 0000000..8a5fa42
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/index.jsx
@@ -0,0 +1,16 @@
+/**
+ * Particles.jsx
+ * Atom component for the particles in the Particles model
+ */
+
+export default function Particles({ config, refs }) {
+ return (
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/logic/setup.js b/src/frontend/ui/models/Particles/components/atoms/Particles/logic/setup.js
new file mode 100644
index 0000000..2fb3f56
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/logic/setup.js
@@ -0,0 +1,65 @@
+import { Float32BufferAttribute } from 'three';
+
+import { SetupStrategy } from '../../../../logic/setups/strategy';
+import { getImageData } from '../../../../logic';
+
+
+export class ParticlesSetup extends SetupStrategy {
+ apply({ config, data: { color, unit }, objects: { image }, refs }) {
+ const { particle } = config;
+ const particles = refs.particles.current;
+ const { data } = getImageData({ data: { unit }, objects: { image } });
+
+ particles.data = {
+ label: "particles",
+ count: 0,
+ chaotic: [],
+ color,
+ colors: [],
+ positions: { ideal: [], initial: [], offsets: [] },
+ };
+
+ const dimensions = {
+ x: unit,
+ y: (image.height / image.width) * unit,
+ z: unit
+ };
+
+ for (let y = 0; y < dimensions.y; y += particle.density) {
+ for (let x = 0; x < dimensions.x; x += particle.density) {
+ const alpha = data[(x + y * dimensions.x) * 4 + 3];
+ if (alpha > 128) {
+ particles.data.chaotic.push(0);
+ particles.data.colors.push(color.r, color.g, color.b);
+ particles.data.positions.ideal.push(
+ x - dimensions.x / 2,
+ -y + dimensions.y / 2,
+ -dimensions.z / 2);
+ particles.data.positions.initial.push(
+ (Math.random() - 0.5) * unit * 2,
+ (Math.random() - 0.5) * unit * 2,
+ (Math.random() - 0.5) * unit * 2
+ );
+ particles.data.positions.offsets.push(
+ Math.random() * Math.PI * 2,
+ Math.random() * Math.PI * 2,
+ Math.random() * Math.PI * 2,
+ );
+ particles.data.count++;
+ }
+ }
+ }
+
+ const colorsArray = particles.data.colors;
+ const colorsValue = new Float32BufferAttribute(colorsArray, 3);
+ particles.geometry.setAttribute("color", colorsValue);
+
+ const positionsArray = particles.data.positions.ideal;
+ const positionsValue = new Float32BufferAttribute(positionsArray, 3);
+ particles.geometry.setAttribute("position", positionsValue);
+
+ const ratio = window.innerWidth / window.innerHeight;
+ const size = Math.min(Math.max(particle.size * ratio, 0), particle.size);
+ particles.material.size = size;
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/logic/update.js b/src/frontend/ui/models/Particles/components/atoms/Particles/logic/update.js
new file mode 100644
index 0000000..42ddb81
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/logic/update.js
@@ -0,0 +1,41 @@
+import { UpdateManager } from '../../../../logic/updates/manager';
+import { UpdateStrategy } from '../../../../logic/updates/strategy';
+
+export class ParticlesUpdate extends UpdateStrategy {
+ apply({ config, objects, refs: { mouse, particles }, ...args }) {
+ const { clock } = objects;
+ const { animations: { interpolation } } = config;
+
+ const object = particles.current;
+ const time = clock.current.getElapsedTime();
+ const intersects = objects.raycaster.intersectObject(object);
+ const idxs = new Set(intersects.map(({ index }) => index));
+ const positions = object.geometry.attributes.position.array;
+
+ for (let i = 0; i < object.data.count; i++) {
+ if (time >= interpolation.duration) {
+ UpdateManager.updateAttribute("chaos", {
+ config,
+ i,
+ idxs,
+ mouse,
+ particles: object,
+ ...args
+ });
+ }
+ UpdateManager.updateAttribute("position", {
+ config,
+ i,
+ idxs,
+ object,
+ positions,
+ particles,
+ time,
+ ...args
+ });
+ }
+
+ object.geometry.attributes.color.needsUpdate = true;
+ object.geometry.attributes.position.needsUpdate = true;
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Plane/index.jsx b/src/frontend/ui/models/Particles/components/atoms/Plane/index.jsx
new file mode 100644
index 0000000..9fff14d
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Plane/index.jsx
@@ -0,0 +1,23 @@
+//* Main
+export default function Plane({ config, data, refs }) {
+ // Props
+ const {
+ general: { showHelpers }
+ } = config;
+ // Return
+ return (
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Plane/logic/setup.js b/src/frontend/ui/models/Particles/components/atoms/Plane/logic/setup.js
new file mode 100644
index 0000000..68cb95d
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Plane/logic/setup.js
@@ -0,0 +1,9 @@
+import { Plane, Vector3 } from 'three';
+import { SetupStrategy } from '../../../../logic/setups/strategy';
+
+export class PlaneSetup extends SetupStrategy {
+ apply({ data: { unit }, refs: { plane } }) {
+ const normal = new Vector3(0, 0, 1);
+ plane.current = new Plane(normal, unit / 2);
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/RayLine/index.jsx b/src/frontend/ui/models/Particles/components/atoms/RayLine/index.jsx
new file mode 100644
index 0000000..20938db
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/RayLine/index.jsx
@@ -0,0 +1,19 @@
+/**
+ * RayLine.jsx
+ * Atom component for the ray line in the Particles model
+ */
+
+//* Main
+export default function RayLine({ config, refs }) {
+ // Props
+ const {
+ general: { showHelpers }
+ } = config;
+ // Return
+ return (
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/RayLine/logic/line.js b/src/frontend/ui/models/Particles/components/atoms/RayLine/logic/line.js
new file mode 100644
index 0000000..bf8de0a
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/RayLine/logic/line.js
@@ -0,0 +1,12 @@
+import { BufferGeometry } from 'three';
+import { UpdateStrategy } from '../../../../logic/updates/strategy';
+
+export class LineUpdate extends UpdateStrategy {
+ apply({ objects, refs, target }) {
+ const { origin } = objects.raycaster.ray;
+ const points = [origin, target];
+ const geometry = new BufferGeometry().setFromPoints(points);
+ refs.rayLine.current.geometry.dispose();
+ refs.rayLine.current.geometry = geometry;
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Raycaster/index.jsx b/src/frontend/ui/models/Particles/components/atoms/Raycaster/index.jsx
new file mode 100644
index 0000000..a6b2b5b
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Raycaster/index.jsx
@@ -0,0 +1,8 @@
+/**
+ * Raycaster.jsx
+ * Atom component for the raycaster in the Particles model
+ */
+
+export default function Raycaster() {
+ return null;
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Raycaster/logic/setup.js b/src/frontend/ui/models/Particles/components/atoms/Raycaster/logic/setup.js
new file mode 100644
index 0000000..f3729ae
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Raycaster/logic/setup.js
@@ -0,0 +1,8 @@
+import { SetupStrategy } from '../../../../logic/setups/strategy';
+
+export class RaycasterSetup extends SetupStrategy {
+ apply({ config, data: { unit }, objects: { raycaster } }) {
+ const { animations: { chaos: { radius } } } = config;
+ raycaster.params.Points.threshold = radius * unit;
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Raycaster/logic/update.js b/src/frontend/ui/models/Particles/components/atoms/Raycaster/logic/update.js
new file mode 100644
index 0000000..092dd25
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Raycaster/logic/update.js
@@ -0,0 +1,12 @@
+import { Vector2 } from 'three';
+import { UpdateStrategy } from '../../../../logic/updates/strategy';
+
+export class RaycasterUpdate extends UpdateStrategy {
+ apply({ objects, refs }) {
+ const { raycaster } = objects;
+ const camera = refs.camera.current;
+ const mouse = refs.mouse.current;
+ const coords = new Vector2(mouse.x, mouse.y);
+ raycaster.setFromCamera(coords, camera);
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/molecules/ParticleSystem.jsx b/src/frontend/ui/models/Particles/components/molecules/ParticleSystem.jsx
new file mode 100644
index 0000000..25f0389
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/molecules/ParticleSystem.jsx
@@ -0,0 +1,42 @@
+/**
+ * ParticleSystem.jsx
+ * Molecule component that combines Particles with its logic
+ */
+
+//* Imports
+import { useEffect } from "react";
+import { useFrame } from "@react-three/fiber";
+import Particles from "../atoms/Particles";
+import {
+ setupObjects,
+ updateObjects,
+} from "@semantyk/frontend/ui/models/Particles/logic";
+import { SetupManager } from "../../logic/setups/manager";
+import { ListenerManager } from "../../logic/listeners/manager";
+import { HandlerManager } from "../../logic/handlers/manager";
+
+//* Main
+export default function ParticleSystem(args) {
+ // Logic
+ useEffect(() => {
+ setupObjects(args);
+
+ const handleMouseMove = (event) => {
+ HandlerManager.handleMouseMove(event, args);
+ };
+
+ const handleResize = (event) => {
+ HandlerManager.handleResize(event, args);
+ };
+
+ ListenerManager.addEventListeners({ handleMouseMove, handleResize });
+ return () => ListenerManager.removeEventListeners({ handleMouseMove, handleResize });
+ }, [args]);
+
+ useFrame(({ clock }) => {
+ args.objects.clock.current = clock;
+ updateObjects(args);
+ });
+
+ return ;
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/organisms/ParticlesScene.jsx b/src/frontend/ui/models/Particles/components/organisms/ParticlesScene.jsx
new file mode 100644
index 0000000..0b70415
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/organisms/ParticlesScene.jsx
@@ -0,0 +1,44 @@
+/**
+ * –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
+ * # `ParticlesScene.jsx`
+ * @organization: Semantyk
+ * @project: Client
+ *
+ * @file: This file contains the logic for the ParticlesScene component.
+ *
+ * @created: Mar 13, 2025
+ * @modified: Mar 13, 2025
+ *
+ * @author: Semantyk Team
+ * @maintainer: Daniel Bakas
+ *
+ * @copyright: Semantyk © 2025. All rights reserved.
+ * –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
+ */
+
+//* Imports
+import { useArgs } from "@semantyk/frontend/ui/models/Particles/hooks/useArgs";
+import { config } from "@semantyk/frontend/ui/models/Particles/config";
+import Camera from "../atoms/Camera";
+import Controls from "../atoms/Controls";
+import Box from "../atoms/Box";
+import Circle from "../atoms/Circle";
+import ParticleSystem from "../molecules/ParticleSystem";
+import Plane from "../atoms/Plane";
+import RayLine from "../atoms/RayLine";
+
+//* Main
+export default function ParticlesScene() {
+ // Hooks
+ const args = useArgs();
+ // Return
+ return (<>
+
+
+
+
+
+
+
+ >);
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/config/index.js b/src/frontend/ui/models/Particles/config/index.js
new file mode 100644
index 0000000..51d778e
--- /dev/null
+++ b/src/frontend/ui/models/Particles/config/index.js
@@ -0,0 +1,61 @@
+/**
+ * –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
+ * # `config.js`
+ * @organization: Semantyk
+ * @project: Client
+ *
+ * @file: This file contains the configuration for the Particles model.
+ *
+ * @created: Mar 7, 2025
+ * @modified: Mar 7, 2025
+ *
+ * @author: Semantyk Team
+ * @maintainer: Daniel Bakas
+ *
+ * @copyright: Semantyk © 2025. All rights reserved.
+ * –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
+ */
+
+//* Main
+export const config = {
+ // General
+ general: {
+ showHelpers: true,
+ scale: 1,
+ size: 150,
+ },
+ // Camera
+ camera: {
+ margin: 1 / 3,
+ makeDefault: true
+ },
+ // Animations
+ animations: {
+ chaos: {
+ magnitude: 0.25,
+ radius: 0.10
+ },
+ order: {
+ magnitude: 0.25
+ },
+ expansion: {
+ magnitude: 1,
+ },
+ flotation: {
+ magnitude: 1,
+ speed: 1
+ },
+ interpolation: {
+ duration: 5
+ }
+ },
+ // Image
+ image: {
+ path: "/favicon.png"
+ },
+ // Particles
+ particle: {
+ density: 1,
+ size: 0.75
+ }
+};
\ No newline at end of file
diff --git a/src/frontend/ui/models/molecule/Particles/hooks.jsx b/src/frontend/ui/models/Particles/hooks/useArgs.jsx
similarity index 88%
rename from src/frontend/ui/models/molecule/Particles/hooks.jsx
rename to src/frontend/ui/models/Particles/hooks/useArgs.jsx
index 4d2a4a4..ca95f33 100644
--- a/src/frontend/ui/models/molecule/Particles/hooks.jsx
+++ b/src/frontend/ui/models/Particles/hooks/useArgs.jsx
@@ -19,13 +19,13 @@ import { useRef } from "react";
import { useLoader } from "@react-three/fiber";
import { Color, Raycaster, TextureLoader } from "three";
//* Local Imports
-import { props } from "@semantyk/frontend/ui/models/molecule/Particles/logic";
+import { config } from "@semantyk/frontend/ui/models/Particles/config";
import useColorScheme from "@semantyk/frontend/hooks/useColorScheme";
//* Main
export function useArgs() {
// Props
- const { general: { scale, size }, image: { path } } = props;
+ const { general: { scale, size }, image: { path } } = config;
// Hooks
const { colorScheme } = useColorScheme();
const { image } = useLoader(TextureLoader, path);
@@ -34,7 +34,7 @@ export function useArgs() {
const colorV3 = new Color(color, color, color);
// Return
return {
- /// Data
+ // Data
data: {
color: colorV3,
unit: scale * size
@@ -45,12 +45,15 @@ export function useArgs() {
image,
raycaster: new Raycaster()
},
+ // Props
+ config,
// Refs
refs: {
box: useRef(),
camera: useRef(),
circle: useRef(),
mouse: useRef({ x: 0, y: 0 }),
+ moveMouseTimeout: useRef(),
particles: useRef(),
plane: useRef(),
rayLine: useRef(),
diff --git a/src/frontend/ui/models/Particles/index.jsx b/src/frontend/ui/models/Particles/index.jsx
new file mode 100644
index 0000000..e32ae97
--- /dev/null
+++ b/src/frontend/ui/models/Particles/index.jsx
@@ -0,0 +1,23 @@
+/**
+ * –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
+ * # `index.jsx` | `ParticlesModel`
+ * @organization: Semantyk
+ * @project: Client
+ *
+ * @file: This file contains the main entry point for the Particles model.
+ *
+ * @created: Sep 12, 2024
+ * @modified: Mar 12, 2025
+ *
+ * @author: Semantyk Team
+ * @maintainer: Daniel Bakas
+ *
+ * @copyright: Semantyk © 2025. All rights reserved.
+ * –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
+ */
+
+import ParticlesScene from "./components/organisms/ParticlesScene";
+
+export default function ParticlesModel() {
+ return ;
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/effects/manager.js b/src/frontend/ui/models/Particles/logic/effects/manager.js
new file mode 100644
index 0000000..47437a9
--- /dev/null
+++ b/src/frontend/ui/models/Particles/logic/effects/manager.js
@@ -0,0 +1,31 @@
+import { ChaosEffect } from '../../components/atoms/Particles/effects/chaos/effect';
+import { ColorEffect } from '../../components/atoms/Particles/effects/color/effect';
+import { PositionEffect } from '../../components/atoms/Particles/effects/position/effect';
+
+/**
+ * Manager class that handles all particle effects using the Strategy pattern
+ */
+export class EffectManager {
+ static instance = new EffectManager();
+
+ constructor() {
+ this.strategies = {
+ chaos: new ChaosEffect(),
+ color: new ColorEffect(),
+ position: new PositionEffect()
+ };
+ }
+
+ addEffect(type, args) {
+ const strategy = this.strategies[type];
+ if (strategy) {
+ strategy.apply(args);
+ }
+ }
+
+ static addEffect(type, args) {
+ return EffectManager.instance.addEffect(type, args);
+ }
+}
+
+export const { addEffect } = EffectManager;
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/effects/strategy.js b/src/frontend/ui/models/Particles/logic/effects/strategy.js
new file mode 100644
index 0000000..a283135
--- /dev/null
+++ b/src/frontend/ui/models/Particles/logic/effects/strategy.js
@@ -0,0 +1,13 @@
+/**
+ * Base class for particle effects following the Strategy Pattern
+ */
+export class EffectStrategy {
+ /**
+ * Apply the effect
+ * @param {Object} args - Effect arguments
+ * @throws {Error} Must be implemented by child classes
+ */
+ apply(args) {
+ throw new Error('Effect strategy must implement apply method');
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/handlers/manager.js b/src/frontend/ui/models/Particles/logic/handlers/manager.js
new file mode 100644
index 0000000..487fcf2
--- /dev/null
+++ b/src/frontend/ui/models/Particles/logic/handlers/manager.js
@@ -0,0 +1,59 @@
+/**
+ * Manager for particle system event handlers
+ */
+
+import { MouseHandler } from '../../components/atoms/Mouse/logic/handler';
+import { ResizeHandler } from '../../components/atoms/Particles/effects/resize/resize';
+
+export class HandlerManager {
+ static #instance = null;
+ #mouseHandler = new MouseHandler();
+ #resizeHandler = new ResizeHandler();
+
+ /**
+ * Get the singleton instance
+ * @returns {HandlerManager}
+ */
+ static getInstance() {
+ if (!HandlerManager.#instance) {
+ HandlerManager.#instance = new HandlerManager();
+ }
+ return HandlerManager.#instance;
+ }
+
+ /**
+ * Handle mouse/touch move event
+ * @param {MouseEvent|TouchEvent} event - Mouse or touch event
+ * @param {Object} args - Particle system arguments
+ */
+ handleMouseMove(event, args) {
+ this.#mouseHandler.handle(event, args);
+ }
+
+ /**
+ * Handle window resize event
+ * @param {Event} event - Window resize event
+ * @param {Object} args - Particle system arguments
+ */
+ handleResize(event, args) {
+ this.#resizeHandler.handle(event, args);
+ }
+
+ /**
+ * Static method to handle mouse/touch move event
+ * @param {MouseEvent|TouchEvent} event - Mouse or touch event
+ * @param {Object} args - Particle system arguments
+ */
+ static handleMouseMove(event, args) {
+ HandlerManager.getInstance().handleMouseMove(event, args);
+ }
+
+ /**
+ * Static method to handle window resize event
+ * @param {Event} event - Window resize event
+ * @param {Object} args - Particle system arguments
+ */
+ static handleResize(event, args) {
+ HandlerManager.getInstance().handleResize(event, args);
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/handlers/strategy.js b/src/frontend/ui/models/Particles/logic/handlers/strategy.js
new file mode 100644
index 0000000..1eafcd2
--- /dev/null
+++ b/src/frontend/ui/models/Particles/logic/handlers/strategy.js
@@ -0,0 +1,14 @@
+/**
+ * Base class for particle event handlers following the Strategy Pattern
+ */
+export class HandlerStrategy {
+ /**
+ * Handle the event
+ * @param {Object} event - Event object
+ * @param {Object} args - Additional arguments
+ * @throws {Error} Must be implemented by child classes
+ */
+ handle(event, args) {
+ throw new Error('Handler strategy must implement handle method');
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/index.js b/src/frontend/ui/models/Particles/logic/index.js
new file mode 100644
index 0000000..bf21a74
--- /dev/null
+++ b/src/frontend/ui/models/Particles/logic/index.js
@@ -0,0 +1,61 @@
+/**
+ * –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
+ * # `logic.js`
+ * @organization: Semantyk
+ * @project: Client
+ *
+ * @created: Jul 17, 2024
+ * @modified: Mar 7, 2025
+ *
+ * @author: Semantyk Team
+ * @maintainer: Daniel Bakas
+ *
+ * @copyright: Semantyk © 2025. All rights reserved.
+ * –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
+ */
+
+//* Imports
+import { Vector3 } from "three";
+//* Local Imports
+import { UpdateManager } from "./updates/manager";
+import { SetupManager } from "./setups/manager";
+
+//* Main
+export function getImageData(args) {
+ // Args
+ const { data: { unit }, objects: { image } } = args;
+ // Logic
+ let { width, height } = image;
+ const canvas = document.createElement("canvas");
+ const context = canvas.getContext("2d");
+ canvas.width = unit;
+ canvas.height = (height / width) * unit;
+ context.drawImage(image, 0, 0, canvas.width, canvas.height);
+ // Return
+ return context.getImageData(0, 0, canvas.width, canvas.height);
+}
+
+export function ease(time, duration) {
+ const t = Math.min(time / duration, 1);
+ return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
+}
+
+export function setupObjects(args) {
+ SetupManager.setupObject("camera", args);
+ SetupManager.setupObject("plane", args);
+ SetupManager.setupObject("particles", args);
+ SetupManager.setupObject("raycaster", args);
+}
+
+export function updateObjects(args) {
+ UpdateManager.updateObject("particles", args);
+}
+
+export function updateOnMouseMove(args) {
+ const target = new Vector3();
+ UpdateManager.updateObject("camera", args);
+ UpdateManager.updateObject("raycaster", args);
+ UpdateManager.updateObject("mouse", args);
+ UpdateManager.updateObject("circle", { target, ...args });
+ UpdateManager.updateObject("line", { target, ...args });
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/listeners/manager.js b/src/frontend/ui/models/Particles/logic/listeners/manager.js
new file mode 100644
index 0000000..4faf509
--- /dev/null
+++ b/src/frontend/ui/models/Particles/logic/listeners/manager.js
@@ -0,0 +1,38 @@
+import { MouseListener } from '../../components/atoms/Mouse/logic/listener';
+import { ResizeListener } from './resize';
+
+/**
+ * Manager class that handles all particle event listeners using the Strategy pattern
+ */
+export class ListenerManager {
+ static instance = new ListenerManager();
+
+ constructor() {
+ this.strategies = {
+ mouse: new MouseListener(),
+ resize: new ResizeListener(),
+ };
+ }
+
+ addEventListeners(args) {
+ Object.values(this.strategies).forEach(strategy => {
+ strategy.add(args);
+ });
+ }
+
+ removeEventListeners(args) {
+ Object.values(this.strategies).forEach(strategy => {
+ strategy.remove(args);
+ });
+ }
+
+ static addEventListeners(args) {
+ return ListenerManager.instance.addEventListeners(args);
+ }
+
+ static removeEventListeners(args) {
+ return ListenerManager.instance.removeEventListeners(args);
+ }
+}
+
+export const { addEventListeners, removeEventListeners } = ListenerManager;
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/listeners/resize.js b/src/frontend/ui/models/Particles/logic/listeners/resize.js
new file mode 100644
index 0000000..9297517
--- /dev/null
+++ b/src/frontend/ui/models/Particles/logic/listeners/resize.js
@@ -0,0 +1,11 @@
+import { ListenerStrategy } from './strategy';
+
+export class ResizeListener extends ListenerStrategy {
+ add({ handleResize }) {
+ window.addEventListener("resize", handleResize);
+ }
+
+ remove({ handleResize }) {
+ window.removeEventListener("resize", handleResize);
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/listeners/strategy.js b/src/frontend/ui/models/Particles/logic/listeners/strategy.js
new file mode 100644
index 0000000..f7b4f8c
--- /dev/null
+++ b/src/frontend/ui/models/Particles/logic/listeners/strategy.js
@@ -0,0 +1,22 @@
+/**
+ * Base class for particle event listeners following the Strategy Pattern
+ */
+export class ListenerStrategy {
+ /**
+ * Add the event listener
+ * @param {Object} args - Event arguments
+ * @throws {Error} Must be implemented by child classes
+ */
+ add(args) {
+ throw new Error('Listener strategy must implement add method');
+ }
+
+ /**
+ * Remove the event listener
+ * @param {Object} args - Event arguments
+ * @throws {Error} Must be implemented by child classes
+ */
+ remove(args) {
+ throw new Error('Listener strategy must implement remove method');
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/setups/manager.js b/src/frontend/ui/models/Particles/logic/setups/manager.js
new file mode 100644
index 0000000..1e4c8e4
--- /dev/null
+++ b/src/frontend/ui/models/Particles/logic/setups/manager.js
@@ -0,0 +1,33 @@
+import { CameraSetup } from '../../components/atoms/Camera/logic/setup';
+import { ParticlesSetup } from '../../components/atoms/Particles/logic/setup';
+import { PlaneSetup } from '../../components/atoms/Plane/logic/setup';
+import { RaycasterSetup } from '../../components/atoms/Raycaster/logic/setup';
+
+/**
+ * Manager class that handles all particle setups using the Strategy pattern
+ */
+export class SetupManager {
+ static instance = new SetupManager();
+
+ constructor() {
+ this.strategies = {
+ camera: new CameraSetup(),
+ particles: new ParticlesSetup(),
+ plane: new PlaneSetup(),
+ raycaster: new RaycasterSetup(),
+ };
+ }
+
+ setupObject(type, args) {
+ const strategy = this.strategies[type];
+ if (strategy) {
+ strategy.apply(args);
+ }
+ }
+
+ static setupObject(type, args) {
+ return SetupManager.instance.setupObject(type, args);
+ }
+}
+
+export const { setupObject } = SetupManager;
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/setups/strategy.js b/src/frontend/ui/models/Particles/logic/setups/strategy.js
new file mode 100644
index 0000000..8a620b1
--- /dev/null
+++ b/src/frontend/ui/models/Particles/logic/setups/strategy.js
@@ -0,0 +1,13 @@
+/**
+ * Base class for particle setups following the Strategy Pattern
+ */
+export class SetupStrategy {
+ /**
+ * Apply the setup
+ * @param {Object} args - Setup arguments
+ * @throws {Error} Must be implemented by child classes
+ */
+ apply(args) {
+ throw new Error('Setup strategy must implement apply method');
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/updates/manager.js b/src/frontend/ui/models/Particles/logic/updates/manager.js
new file mode 100644
index 0000000..5a9ec9e
--- /dev/null
+++ b/src/frontend/ui/models/Particles/logic/updates/manager.js
@@ -0,0 +1,55 @@
+import { CircleUpdate } from '../../components/atoms/Circle/logic/update';
+import { LineUpdate } from '../../components/atoms/RayLine/logic/line';
+import { MouseUpdate } from '../../components/atoms/Mouse/logic/update';
+import { ParticlesUpdate } from '../../components/atoms/Particles/logic/update';
+import { RaycasterUpdate } from '../../components/atoms/Raycaster/logic/update';
+import { ChaosUpdate } from '../../components/atoms/Particles/effects/chaos/update';
+import { ColorUpdate } from '../../components/atoms/Particles/effects/color/update';
+import { PositionUpdate } from '../../components/atoms/Particles/effects/position/update';
+
+/**
+ * Manager class that handles all particle updates using the Strategy pattern
+ */
+export class UpdateManager {
+ static instance = new UpdateManager();
+
+ constructor() {
+ this.objectStrategies = {
+ circle: new CircleUpdate(),
+ line: new LineUpdate(),
+ mouse: new MouseUpdate(),
+ particles: new ParticlesUpdate(),
+ raycaster: new RaycasterUpdate(),
+ };
+
+ this.attributeStrategies = {
+ chaos: new ChaosUpdate(),
+ color: new ColorUpdate(),
+ position: new PositionUpdate()
+ };
+ }
+
+ updateObject(type, args) {
+ const strategy = this.objectStrategies[type];
+ if (strategy) {
+ strategy.apply(args);
+ }
+ }
+
+ updateAttribute(type, args) {
+ const strategy = this.attributeStrategies[type];
+ if (strategy) {
+ strategy.apply(args);
+ }
+ }
+
+ static updateObject(type, args) {
+ return UpdateManager.instance.updateObject(type, args);
+ }
+
+ static updateAttribute(type, args) {
+ return UpdateManager.instance.updateAttribute(type, args);
+ }
+}
+
+export const { updateObject, updateAttribute } = UpdateManager;
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/updates/strategy.js b/src/frontend/ui/models/Particles/logic/updates/strategy.js
new file mode 100644
index 0000000..02695a1
--- /dev/null
+++ b/src/frontend/ui/models/Particles/logic/updates/strategy.js
@@ -0,0 +1,13 @@
+/**
+ * Base class for particle updates following the Strategy Pattern
+ */
+export class UpdateStrategy {
+ /**
+ * Apply the update
+ * @param {Object} args - Update arguments
+ * @throws {Error} Must be implemented by child classes
+ */
+ apply(args) {
+ throw new Error('Update strategy must implement apply method');
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/molecule/Particles/effects.js b/src/frontend/ui/models/molecule/Particles/effects.js
deleted file mode 100644
index 3be6ec7..0000000
--- a/src/frontend/ui/models/molecule/Particles/effects.js
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- * –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
- * # `effects.js`
- * @organization: Semantyk
- * @project: Client
- *
- * @created: Sep 17, 2024
- * @modified: Mar 7, 2025
- *
- * @author: Semantyk Team
- * @maintainer: Daniel Bakas
- *
- * @copyright: Semantyk © 2025. All rights reserved.
- * –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
- */
-
-// - expansion
-import {
- ease,
- props,
-} from "@semantyk/frontend/ui/models/molecule/Particles/logic";
-import { Color, Vector3 } from "three";
-
-//* Main
-//* ----------------------------------------------------------------------------
-// Effect Builder
-export function addEffect(type, args) {
- // Logic
- // - declare options
- const options = {
- // - THREE.point
- color: addPointColorEffect,
- position: addPointPositionEffect,
- // - custom
- expansion: addExpansionEffect,
- flotation: addFlotationEffect,
- interpolation: addInterpolationEffect,
- };
- // - select option
- let option = options[type];
- // Update
- if (option)
- option(args);
-}
-
-//* ----------------------------------------------------------------------------
-// THREE.point Effects
-// - color
-export function addPointColorEffect({ particles, i, final, colors }) {
- // Logic
- const chaoticValue = particles.data.chaotic[i];
- const target = new Color(1, 0, 0);
- // Transform
- final.lerp(target, chaoticValue);
- // Update
- colors.set(final.toArray(), i * 3);
-}
-
-// - position
-export function addPointPositionEffect(args) {
- // Props
- const { animations: { interpolation } } = props;
- // Effects
- addEffect("interpolation", args);
- addEffect("flotation", args);
- if (args.time >= interpolation.duration)
- addEffect("expansion", args);
-}
-
-//* ----------------------------------------------------------------------------
-// Custom Effects
-// - expansion
-export function addExpansionEffect({ object, i, final }) {
- // Props
- const { expansion } = props.animations;
- const chaosValue = object.data.chaotic[i];
- const { ideal } = object.data.positions;
- const positions = object.geometry.attributes.position.array;
- // Logic
- const source = new Vector3().fromArray(positions, i * 3);
- const target = new Vector3().fromArray(ideal, i * 3);
- const effect = new Vector3().subVectors(source, target);
- effect.multiplyScalar(chaosValue);
- effect.multiplyScalar(expansion.magnitude);
- // Add Effect
- final.add(effect);
-}
-
-// - flotation
-export function addFlotationEffect({ object, i, final, time }) {
- // Props
- const { offsets } = object.data.positions;
- const { animations: { flotation } } = props;
- // Logic
- const vector = new Vector3().fromArray(offsets, i * 3);
- vector.addScalar(time * flotation.speed);
- const effect = new Vector3(
- Math.sin(vector.x),
- Math.sin(vector.y)
- );
- effect.multiplyScalar(flotation.magnitude);
- // Prepare for Update
- final.add(effect);
-}
-
-// - interpolation
-export function addInterpolationEffect(args) {
- // Args
- const { time, object, i, final } = args;
- // Props
- const { ideal, initial } = object.data.positions;
- const { interpolation: { duration } } = props.animations;
- // Logic
- const source = new Vector3().fromArray(initial, i * 3);
- const target = new Vector3().fromArray(ideal, i * 3);
- // - ease timeease
- const easedTime = ease(time, duration);
- // - interpolate
- source.multiplyScalar(1 - easedTime);
- target.multiplyScalar(easedTime);
- // Add Effect
- final.add(source);
- final.add(target);
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/molecule/Particles/index.jsx b/src/frontend/ui/models/molecule/Particles/index.jsx
deleted file mode 100644
index d3fc0f6..0000000
--- a/src/frontend/ui/models/molecule/Particles/index.jsx
+++ /dev/null
@@ -1,160 +0,0 @@
-/**
- * –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
- * # `index.jsx` | `ParticlesModel`
- * @organization: Semantyk
- * @project: Client
- *
- * @file: This file contains the logic for the Particles model.
- *
- * @created: Sep 12, 2024
- * @modified: Mar 7, 2025
- *
- * @author: Semantyk Team
- * @maintainer: Daniel Bakas
- *
- * @copyright: Semantyk © 2025. All rights reserved.
- * –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
- */
-
-//* Imports
-import { useEffect, useRef } from "react";
-import { CameraHelper } from "three";
-import { OrbitControls, PerspectiveCamera, useHelper } from "@react-three/drei";
-import { useFrame } from "@react-three/fiber";
-//* Local Imports
-import {
- addEventListeners,
- props,
- removeEventListeners,
- setupObjects,
- updateObjects,
- updateOnMouseMove,
-} from "@semantyk/frontend/ui/models/molecule/Particles/logic";
-import { useArgs } from "@semantyk/frontend/ui/models/molecule/Particles/hooks";
-import {
- setupCamera
-} from "@semantyk/frontend/ui/models/molecule/Particles/setups";
-
-//* Main
-export default function ParticlesModel() {
- // Props
- const {
- general: { showHelpers },
- animations: { chaos: { radius } }
- } = props;
- // Hooks
- // - useArgs
- const args = useArgs();
- const { data, objects, refs } = args;
- // Logic
- const moveMouseTimeoutRef = useRef(null);
- // Hooks
- // - useEffect
- useEffect(() => {
- // Setup Objects
- setupObjects({ data, objects, refs });
- // Listeners
- // - mousemove/touchmove
- const handleMouseMove = (event) => {
- const { mouse } = refs;
- clearTimeout(moveMouseTimeoutRef.current);
- mouse.current.isMoving = true;
- moveMouseTimeoutRef.current = setTimeout(() => mouse.current.isMoving = false, 1);
- let clientX, clientY;
- if (event.type === "mousemove") {
- clientX = event.clientX;
- clientY = event.clientY;
- } else if (event.type === "touchmove") {
- clientX = event.touches[0].clientX;
- clientY = event.touches[0].clientY;
- }
- updateOnMouseMove({
- events: { mousemove: { clientX, clientY } },
- data,
- objects,
- refs
- });
- };
- // - resize
- const handleResize = () => {
- const { particles } = refs;
- setupCamera(args);
- // Resize Particles
- const { particle } = props;
- const ratio = window.innerWidth / window.innerHeight;
- const size = Math.min(Math.max(particle.size * ratio, 0), particle.size);
- particles.current.material.size = size;
- };
- // - add
- addEventListeners({ handleMouseMove, handleResize });
- // - remove
- return () => removeEventListeners({ handleMouseMove, handleResize });
- }, [args, data, objects, refs]);
- // - useFrame
- useFrame(({ clock }) => {
- objects.clock.current = clock;
- updateObjects(args);
- });
- // - useHelpers
- useHelper(showHelpers && refs.camera, CameraHelper);
- // Return
- return (
- <>
- {/* Camera */}
-
- {/* Orbit Controls */}
- {showHelpers && }
- {/* Box */}
-
-
-
-
- {/* Circle */}
-
-
-
-
- {/* Particles */}
-
-
-
-
- {/* Plane */}
-
-
-
-
- {/* RayLine */}
-
-
-
-
- >
- );
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/molecule/Particles/logic.js b/src/frontend/ui/models/molecule/Particles/logic.js
deleted file mode 100644
index d37c3de..0000000
--- a/src/frontend/ui/models/molecule/Particles/logic.js
+++ /dev/null
@@ -1,133 +0,0 @@
-/**
- * –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
- * # `logic.js`
- * @organization: Semantyk
- * @project: Client
- *
- * @created: Jul 17, 2024
- * @modified: Mar 7, 2025
- *
- * @author: Semantyk Team
- * @maintainer: Daniel Bakas
- *
- * @copyright: Semantyk © 2025. All rights reserved.
- * –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
- */
-
-//* Imports
-import { Vector3 } from "three";
-//* Local Imports
-import {
- updateObject
-} from "@semantyk/frontend/ui/models/molecule/Particles/updates";
-import {
- setupObject
-} from "@semantyk/frontend/ui/models/molecule/Particles/setups";
-
-//* Main
-// props
-export const props = {
- // General
- general: {
- showHelpers: false,
- scale: 1,
- size: 150,
- },
- // Camera
- camera: {
- margin: 1 / 3,
- makeDefault: true
- },
- // Animations
- animations: {
- chaos: {
- magnitude: 0.25,
- radius: 0.10
- },
- order: {
- magnitude: 0.25
- },
- expansion: {
- magnitude: 1,
- },
- flotation: {
- magnitude: 1,
- speed: 1
- },
- interpolation: {
- duration: 5
- }
- },
- // Image
- image: {
- path: "/favicon.png"
- },
- // Particles
- particle: {
- density: 1,
- size: 0.75
- }
-};
-
-export function getImageData(args) {
- // Args
- const { data: { unit }, objects: { image } } = args;
- // Logic
- let { width, height } = image;
- const canvas = document.createElement("canvas");
- const context = canvas.getContext("2d");
- canvas.width = unit;
- canvas.height = (height / width) * unit;
- context.drawImage(image, 0, 0, canvas.width, canvas.height);
- // Return
- return context.getImageData(0, 0, canvas.width, canvas.height);
-}
-
-export function ease(time, duration) {
- const t = Math.min(time / duration, 1);
- return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
-}
-
-export function addEventListeners(args) {
- // Args
- const { handleMouseMove, handleResize } = args;
- // Listeners
- window.addEventListener("mousemove", handleMouseMove);
- window.addEventListener("touchmove", handleMouseMove);
- window.addEventListener("resize", handleResize);
-}
-
-export function removeEventListeners(args) {
- // Args
- const { handleMouseMove, handleResize } = args;
- // Listeners
- window.removeEventListener("mousemove", handleMouseMove);
- window.removeEventListener("touchmove", handleMouseMove);
- window.removeEventListener("resize", handleResize);
-}
-
-export function setupObjects(args) {
- // Setup
- // - camera
- setupObject("camera", args);
- // - plane
- setupObject("plane", args);
- // - object
- setupObject("particles", args);
- // - raycaster
- setupObject("raycaster", args);
-}
-
-export function updateObjects(args) {
- updateObject("particles", args);
-}
-
-export function updateOnMouseMove(args) {
- // Logic
- const target = new Vector3();
- updateObject("camera", args);
- updateObject("raycaster", args);
- updateObject("mouse", args);
- updateObject("circle", { target, ...args });
- updateObject("line", { target, ...args });
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/molecule/Particles/setups.js b/src/frontend/ui/models/molecule/Particles/setups.js
deleted file mode 100644
index 162595a..0000000
--- a/src/frontend/ui/models/molecule/Particles/setups.js
+++ /dev/null
@@ -1,131 +0,0 @@
-/**
- * –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
- * # `setups.js`
- * @organization: Semantyk
- * @project: Client
- *
- * @created: Sep 17, 2024
- * @modified: Mar 7, 2025
- *
- * @author: Semantyk Team
- * @maintainer: Daniel Bakas
- *
- * @copyright: Semantyk © 2025. All rights reserved.
- * –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
- */
-
-//* Imports
-import {
- getImageData,
- props
-} from "@semantyk/frontend/ui/models/molecule/Particles/logic";
-// - plane
-import { Float32BufferAttribute, Plane, Vector3 } from "three";
-
-//* Main
-export function setupObject(type, args) {
- switch (type) {
- case "camera":
- setupCamera(args);
- case "particles":
- setupParticles(args);
- case "plane":
- setupPlane(args);
- case "raycaster":
- setupRaycaster(args);
- default:
- return;
- }
-}
-
-export function setupCamera(args) {
- // Args
- const { data: { unit }, refs: { camera } } = args;
- let { camera: { margin } } = props;
- // Logic
- // - camera
- const aspectRatio = window.innerWidth / window.innerHeight;
- let x = (1 + margin) / ((aspectRatio >= 1) ? 2 : (2 * aspectRatio));
- const fx = 2 * Math.atan(x) * (180 / Math.PI);
- camera.current.fov = fx;
- camera.current.aspect = aspectRatio;
- camera.current.position.z = unit / 2;
- camera.current.updateProjectionMatrix();
-}
-
-// - object
-export function setupParticles(args) {
- // Args
- const { data: { color, unit }, objects: { image }, refs } = args;
- const { particle } = props;
- const particles = refs.particles.current;
- const { data } = getImageData(args);
- particles.data = {
- label: "particles",
- count: 0,
- chaotic: [],
- color,
- colors: [],
- positions: { ideal: [], initial: [], offsets: [] },
- };
-
- const dimensions = {
- x: unit,
- y: (image.height / image.width) * unit,
- z: unit
- };
- for (let y = 0; y < dimensions.y; y += particle.density) {
- for (let x = 0; x < dimensions.x; x += particle.density) {
- const alpha = data[(x + y * dimensions.x) * 4 + 3];
- if (alpha > 128) {
- particles.data.chaotic.push(0);
- particles.data.colors.push(color.r, color.g, color.b);
- particles.data.positions.ideal.push(
- x - dimensions.x / 2,
- -y + dimensions.y / 2,
- -dimensions.z / 2);
- particles.data.positions.initial.push(
- (Math.random() - 0.5) * unit * 2,
- (Math.random() - 0.5) * unit * 2,
- (Math.random() - 0.5) * unit * 2
- );
- particles.data.positions.offsets.push(
- Math.random() * Math.PI * 2,
- Math.random() * Math.PI * 2,
- Math.random() * Math.PI * 2,
- );
- particles.data.count++;
- }
- }
- }
- // - color
- const colorsArray = particles.data.colors;
- const colorsValue = new Float32BufferAttribute(colorsArray, 3);
- particles.geometry.setAttribute("color", colorsValue);
- // - position
- const positionsArray = particles.data.positions.ideal;
- const positionsValue = new Float32BufferAttribute(positionsArray, 3);
- particles.geometry.setAttribute("position", positionsValue);
- // - size
- const ratio = window.innerWidth / window.innerHeight;
- const size = Math.min(Math.max(particle.size * ratio, 0), particle.size);
- particles.material.size = size;
-}
-
-// - plane
-export function setupPlane(args) {
- // Args
- const { data: { unit }, refs: { plane } } = args;
- const normal = new Vector3(0, 0, 1);
- plane.current = new Plane(normal, unit / 2);
-}
-
-// - raycaster
-export function setupRaycaster(args) {
- // Args
- const { data: { unit }, objects: { raycaster } } = args;
- // Props
- const { animations: { chaos: { radius } } } = props;
- // Logic
- raycaster.params.Points.threshold = radius * unit;
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/molecule/Particles/updates.js b/src/frontend/ui/models/molecule/Particles/updates.js
deleted file mode 100644
index 3a99803..0000000
--- a/src/frontend/ui/models/molecule/Particles/updates.js
+++ /dev/null
@@ -1,182 +0,0 @@
-/**
- * –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
- * # `updates.js`
- * @organization: Semantyk
- * @project: Client
- *
- * @created: Sep 17, 2024
- * @modified: Mar 7, 2025
- *
- * @author: Semantyk Team
- * @maintainer: Daniel Bakas
- *
- * @copyright: Semantyk © 2025. All rights reserved.
- * –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
- */
-
-//* Imports
-import { BufferGeometry, Color, Vector2, Vector3 } from "three";
-import {
- addEffect
-} from "@semantyk/frontend/ui/models/molecule/Particles/effects";
-import { onMouseMove } from "@semantyk/frontend/logic/services/callbacks";
-//* ----------------------------------------------------------------------------
-// Particle Updates
-// - particle.chaos
-import { props } from "@semantyk/frontend/ui/models/molecule/Particles/logic";
-
-//* Main
-//* ----------------------------------------------------------------------------
-// Update Factories
-// - particles
-export function updateObject(type, args) {
- // Logic
- // - declare options
- const options = {
- circle: updateCircle,
- line: updateLine,
- mouse: updateMouse,
- particles: updateParticles,
- raycaster: updateRaycaster,
- };
- // - select option
- let option = options[type];
- // Update
- if (option)
- option(args);
-}
-
-// - attribute
-export function updateAttribute(type, args) {
- // Logic
- // - declare options
- const options = {
- chaos: updateChaos,
- color: updateColor,
- position: updatePosition
- };
- // - select option
- let option = options[type];
- // Update
- if (option)
- option(args);
-}
-
-//* ----------------------------------------------------------------------------
-// Object Updates
-// - circle
-export function updateCircle({ objects, refs, target }) {
- // Logic
- objects.raycaster.ray.intersectPlane(refs.plane.current, target);
- refs.circle.current.position.copy(target);
-}
-
-// - particles
-export const updateLine = ({ objects, refs, target }) => {
- // Logic
- const { origin } = objects.raycaster.ray;
- const points = [origin, target];
- const geometry = new BufferGeometry().setFromPoints(points);
- refs.rayLine.current.geometry.dispose();
- // Update
- refs.rayLine.current.geometry = geometry;
-};
-
-// - mouse
-export const updateMouse = ({ refs, events }) => {
- const { x, y } = onMouseMove(events.mousemove);
- refs.mouse.current.x = x * 2 - 1;
- refs.mouse.current.y = -y * 2 + 1;
-};
-
-// - particles
-export const updateParticles = ({
- objects,
- refs: { mouse, particles },
- ...args
- }) => {
- // Props
- let { clock } = objects;
- const { interpolation } = props.animations;
- // Logic
- const object = particles.current;
- const time = clock.current.getElapsedTime();
- const intersects = objects.raycaster.intersectObject(object);
- const idxs = new Set(intersects.map(({ index }) => index));
- const colors = object.geometry.attributes.color.array;
- const positions = object.geometry.attributes.position.array;
- // Update
- // - each particle
- for (let i = 0; i < object.data.count; i++) {
- if (time >= interpolation.duration) {
- updateAttribute("chaos", {
- i,
- idxs,
- mouse,
- particles: object,
- ...args
- });
- // updateAttribute("color", { i, colors, particles: object, ...args });
- }
- updateAttribute("position", {
- i,
- idxs,
- object,
- positions,
- particles,
- time,
- ...args
- });
- }
- // - all particles
- object.geometry.attributes.color.needsUpdate = true;
- object.geometry.attributes.position.needsUpdate = true;
-};
-
-// - raycaster
-export function updateRaycaster({ objects, refs }) {
- // Args
- const { raycaster } = objects;
- const camera = refs.camera.current;
- const mouse = refs.mouse.current;
- const coords = new Vector2(mouse.x, mouse.y);
- raycaster.setFromCamera(coords, camera);
-}
-
-const updateChaos = ({ data, i, idxs, mouse, particles }) => {
- // Props
- const { unit } = data;
- const { animations: { chaos, order } } = props;
- // Logic
- let magnitude;
- let currentChaos = particles.data.chaotic[i];
- if (idxs.has(i) && mouse.current.isMoving) {
- currentChaos += chaos.magnitude;
- magnitude = Math.min(currentChaos, 1);
- } else {
- // magnitude over time
- currentChaos -= order.magnitude / unit;
- magnitude = Math.max(currentChaos, 0);
- }
- particles.data.chaotic[i] = magnitude;
-};
-
-// - particle.color
-const updateColor = ({ i, colors, particles, ...args }) => {
- // Logic
- let final = new Color();
- // Effects
- addEffect("color", { colors, particles, i, final, ...args });
- // Update
- colors.set(final.toArray(), i * 3);
-};
-
-// - particle.position
-function updatePosition({ object, positions, i, ...args }) {
- // Logic
- let final = new Vector3();
- // Effects
- addEffect("position", { positions, object, i, final, ...args });
- // Update
- positions.set(final.toArray(), i * 3);
-}
\ No newline at end of file
From 7a336f4696798903e9211618c5c5f0db74685a04 Mon Sep 17 00:00:00 2001
From: "Daniel B."
Date: Thu, 13 Mar 2025 17:32:57 -0600
Subject: [PATCH 2/7] =?UTF-8?q?=F0=9F=A7=B9=20Chore:=20Refactor=20Particle?=
=?UTF-8?q?s=20model?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Centralize strategy and manager
---
public/bimi.svg | 20 +++++
.../ui/components/molecules/Model/index.jsx | 2 +-
.../molecules/Model/logic/manager.js | 56 ++++++++++++
.../molecules/Model/logic/strategy.js | 31 +++++++
.../components/atoms/Camera/index.jsx | 3 +
.../components/atoms/Camera/logic/setup.js | 14 ++-
.../components/atoms/Circle/index.jsx | 5 ++
.../components/atoms/Circle/logic/update.js | 6 +-
.../components/atoms/Controls/index.jsx | 10 ---
.../Particles/components/atoms/Mouse/index.js | 3 +
.../components/atoms/Mouse/logic/handler.js | 12 +--
.../components/atoms/Mouse/logic/listener.js | 4 +-
.../components/atoms/Mouse/logic/update.js | 6 +-
.../components/atoms/Mouse/updates/color.js | 8 +-
.../atoms/Mouse/updates/position.js | 8 +-
.../atoms/Particles/effects/chaos.js | 25 ++++++
.../atoms/Particles/effects/chaos/effect.js | 21 -----
.../atoms/Particles/effects/chaos/update.js | 8 --
.../atoms/Particles/effects/color.js | 12 +++
.../atoms/Particles/effects/color/effect.js | 11 ---
.../atoms/Particles/effects/color/update.js | 11 ---
.../atoms/Particles/effects/entropy.js | 20 +++++
.../Particles/effects/expansion/effect.js | 19 ----
.../atoms/Particles/effects/flotation.js | 20 +++++
.../Particles/effects/flotation/effect.js | 19 ----
.../atoms/Particles/effects/index.js | 4 +
.../effect.js => interpolation.js} | 11 +--
.../atoms/Particles/effects/position.js | 31 +++++++
.../Particles/effects/position/effect.js | 24 -----
.../Particles/effects/position/update.js | 11 ---
.../atoms/Particles/effects/resize/resize.js | 22 -----
.../atoms/Particles/handlers/index.js | 1 +
.../atoms/Particles/handlers/resize.js | 21 +++++
.../components/atoms/Particles/index.js | 3 +
.../components/atoms/Particles/logic/index.js | 2 +
.../components/atoms/Particles/logic/setup.js | 17 ++--
.../atoms/Particles/logic/update.js | 44 +++-------
.../components/atoms/Plane/index.jsx | 5 ++
.../components/atoms/Plane/logic/setup.js | 14 ++-
.../components/atoms/RayLine/index.jsx | 5 ++
.../RayLine/logic/{line.js => update.js} | 6 +-
.../components/atoms/Raycaster/index.js | 2 +
.../components/atoms/Raycaster/logic/setup.js | 14 ++-
.../atoms/Raycaster/logic/update.js | 6 +-
.../Particles/components/atoms/index.js | 9 ++
.../components/molecules/Controls/index.jsx | 22 +++++
.../index.jsx} | 16 ++--
.../components/organisms/ParticlesScene.jsx | 44 ----------
.../ui/models/Particles/config/index.js | 2 +-
.../ui/models/Particles/hooks/useArgs.jsx | 4 +-
src/frontend/ui/models/Particles/index.jsx | 23 +++--
.../models/Particles/logic/effects/manager.js | 31 -------
.../Particles/logic/effects/strategy.js | 13 ---
.../Particles/logic/handlers/manager.js | 59 -------------
.../Particles/logic/handlers/strategy.js | 14 ---
.../ui/models/Particles/logic/index.js | 23 +++--
.../Particles/logic/listeners/manager.js | 38 --------
.../Particles/logic/listeners/resize.js | 4 +-
.../Particles/logic/listeners/strategy.js | 22 -----
.../ui/models/Particles/logic/manager.js | 88 +++++++++++++++++++
.../models/Particles/logic/setups/manager.js | 33 -------
.../models/Particles/logic/setups/strategy.js | 13 ---
.../models/Particles/logic/updates/manager.js | 55 ------------
.../Particles/logic/updates/strategy.js | 13 ---
64 files changed, 517 insertions(+), 606 deletions(-)
create mode 100644 public/bimi.svg
create mode 100644 src/frontend/ui/components/molecules/Model/logic/manager.js
create mode 100644 src/frontend/ui/components/molecules/Model/logic/strategy.js
delete mode 100644 src/frontend/ui/models/Particles/components/atoms/Controls/index.jsx
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Mouse/index.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos.js
delete mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos/effect.js
delete mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos/update.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/color.js
delete mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/color/effect.js
delete mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/color/update.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/entropy.js
delete mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/expansion/effect.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/flotation.js
delete mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/flotation/effect.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/index.js
rename src/frontend/ui/models/Particles/components/atoms/Particles/effects/{interpolation/effect.js => interpolation.js} (52%)
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/position.js
delete mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/position/effect.js
delete mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/position/update.js
delete mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/resize/resize.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/handlers/index.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/handlers/resize.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/index.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/logic/index.js
rename src/frontend/ui/models/Particles/components/atoms/RayLine/logic/{line.js => update.js} (62%)
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Raycaster/index.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/index.js
create mode 100644 src/frontend/ui/models/Particles/components/molecules/Controls/index.jsx
rename src/frontend/ui/models/Particles/components/molecules/{ParticleSystem.jsx => ParticlesSystem/index.jsx} (53%)
delete mode 100644 src/frontend/ui/models/Particles/components/organisms/ParticlesScene.jsx
delete mode 100644 src/frontend/ui/models/Particles/logic/effects/manager.js
delete mode 100644 src/frontend/ui/models/Particles/logic/effects/strategy.js
delete mode 100644 src/frontend/ui/models/Particles/logic/handlers/manager.js
delete mode 100644 src/frontend/ui/models/Particles/logic/handlers/strategy.js
delete mode 100644 src/frontend/ui/models/Particles/logic/listeners/manager.js
delete mode 100644 src/frontend/ui/models/Particles/logic/listeners/strategy.js
create mode 100644 src/frontend/ui/models/Particles/logic/manager.js
delete mode 100644 src/frontend/ui/models/Particles/logic/setups/manager.js
delete mode 100644 src/frontend/ui/models/Particles/logic/setups/strategy.js
delete mode 100644 src/frontend/ui/models/Particles/logic/updates/manager.js
delete mode 100644 src/frontend/ui/models/Particles/logic/updates/strategy.js
diff --git a/public/bimi.svg b/public/bimi.svg
new file mode 100644
index 0000000..af7dc2c
--- /dev/null
+++ b/public/bimi.svg
@@ -0,0 +1,20 @@
+
+
\ No newline at end of file
diff --git a/src/frontend/ui/components/molecules/Model/index.jsx b/src/frontend/ui/components/molecules/Model/index.jsx
index 80020bc..e85efc4 100644
--- a/src/frontend/ui/components/molecules/Model/index.jsx
+++ b/src/frontend/ui/components/molecules/Model/index.jsx
@@ -21,9 +21,9 @@
//* Imports
import React from "react";
import Canvas from "@semantyk/frontend/ui/components/molecules/Canvas";
-import ParticlesModel from "@semantyk/frontend/ui/models/Particles";
import GraphModel from "@semantyk/frontend/ui/models/Graph";
import { usePathname } from "next/navigation";
+import ParticlesModel from "@semantyk/frontend/ui/models/Particles";
//* Main
export default function Model() {
diff --git a/src/frontend/ui/components/molecules/Model/logic/manager.js b/src/frontend/ui/components/molecules/Model/logic/manager.js
new file mode 100644
index 0000000..aa03b56
--- /dev/null
+++ b/src/frontend/ui/components/molecules/Model/logic/manager.js
@@ -0,0 +1,56 @@
+/**
+ * Base manager class for models using the Strategy pattern
+ */
+export class ModelManager {
+ constructor() {
+ if (this.constructor === ModelManager) {
+ throw new Error('Abstract class ModelManager cannot be instantiated directly');
+ }
+ }
+
+ // Generic method to handle operations on collections
+ execute(collection, type, args) {
+ const item = collection[type];
+ if (item) {
+ return item.execute(args);
+ }
+ }
+
+ // Event listener methods
+ addEventListeners(args) {
+ Object.values(this.listeners).forEach(listener => {
+ listener.add(args);
+ });
+ }
+
+ removeEventListeners(args) {
+ Object.values(this.listeners).forEach(listener => {
+ listener.remove(args);
+ });
+ }
+
+ // Static helper method that automatically uses the correct instance
+ static execute(methodName, type, ...args) {
+ const instance = this.instance;
+ if (!instance) {
+ throw new Error(`No instance found for ${this.name}. Make sure to initialize the static instance property.`);
+ }
+
+ switch (methodName) {
+ case 'addEffect':
+ return instance.addEffect(type, args[0]);
+ case 'handleEvent':
+ return instance.handleEvent(type, args[0], args[1]);
+ case 'setupObject':
+ return instance.setupObject(type, args[0]);
+ case 'updateObject':
+ return instance.updateObject(type, args[0]);
+ case 'addEventListeners':
+ return instance.addEventListeners(type);
+ case 'removeEventListeners':
+ return instance.removeEventListeners(type);
+ default:
+ throw new Error(`Unknown method ${methodName}`);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/components/molecules/Model/logic/strategy.js b/src/frontend/ui/components/molecules/Model/logic/strategy.js
new file mode 100644
index 0000000..1c1fd7c
--- /dev/null
+++ b/src/frontend/ui/components/molecules/Model/logic/strategy.js
@@ -0,0 +1,31 @@
+/**
+ * Base class for model strategies following the Strategy Pattern
+ */
+export class ModelStrategy {
+ /**
+ * Add the event listener
+ * @param {Object} args - Event arguments
+ * @throws {Error} Must be implemented by child classes
+ */
+ add(args) {
+ throw new Error('Strategy must implement add method');
+ }
+
+ /**
+ * Execute the strategy
+ * @param {Object} args - Strategy arguments
+ * @throws {Error} Must be implemented by child classes
+ */
+ execute(args) {
+ throw new Error('Strategy must implement execute method');
+ }
+
+ /**
+ * Remove the event listener
+ * @param {Object} args - Event arguments
+ * @throws {Error} Must be implemented by child classes
+ */
+ remove(args) {
+ throw new Error('Strategy must implement remove method');
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Camera/index.jsx b/src/frontend/ui/models/Particles/components/atoms/Camera/index.jsx
index 636282d..2e5c7f0 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Camera/index.jsx
+++ b/src/frontend/ui/models/Particles/components/atoms/Camera/index.jsx
@@ -6,6 +6,9 @@
import { PerspectiveCamera } from "@react-three/drei";
import { CameraHelper } from "three";
import { useHelper } from "@react-three/drei";
+import { CameraSetup } from './logic/setup';
+
+export { CameraSetup };
export default function Camera({ config, refs }) {
// Props
diff --git a/src/frontend/ui/models/Particles/components/atoms/Camera/logic/setup.js b/src/frontend/ui/models/Particles/components/atoms/Camera/logic/setup.js
index 93ada07..1d0726f 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Camera/logic/setup.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Camera/logic/setup.js
@@ -1,7 +1,15 @@
-import { SetupStrategy } from '../../../../logic/setups/strategy';
+/**
+ * Camera setup strategy for particle system
+ */
-export class CameraSetup extends SetupStrategy {
- apply({ config, data: { unit }, refs: { camera } }) {
+import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
+
+export class CameraSetup extends ModelStrategy {
+ /**
+ * Execute camera setup
+ * @param {Object} args - Arguments containing config, data, and refs
+ */
+ execute({ config, data: { unit }, refs: { camera } }) {
const { camera: { margin } } = config;
const aspectRatio = window.innerWidth / window.innerHeight;
diff --git a/src/frontend/ui/models/Particles/components/atoms/Circle/index.jsx b/src/frontend/ui/models/Particles/components/atoms/Circle/index.jsx
index a253cd2..646bfa7 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Circle/index.jsx
+++ b/src/frontend/ui/models/Particles/components/atoms/Circle/index.jsx
@@ -3,6 +3,11 @@
* Atom component for the circle in the Particles model
*/
+//* Imports
+import { CircleUpdate } from './logic/update';
+
+export { CircleUpdate };
+
//* Main
export default function Circle({ config, data, refs }) {
// Props
diff --git a/src/frontend/ui/models/Particles/components/atoms/Circle/logic/update.js b/src/frontend/ui/models/Particles/components/atoms/Circle/logic/update.js
index c00e734..7845f40 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Circle/logic/update.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Circle/logic/update.js
@@ -1,7 +1,7 @@
-import { UpdateStrategy } from '../../../../logic/updates/strategy';
+import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
-export class CircleUpdate extends UpdateStrategy {
- apply({ objects, refs, target }) {
+export class CircleUpdate extends ModelStrategy {
+ execute({ objects, refs, target }) {
objects.raycaster.ray.intersectPlane(refs.plane.current, target);
refs.circle.current.position.copy(target);
}
diff --git a/src/frontend/ui/models/Particles/components/atoms/Controls/index.jsx b/src/frontend/ui/models/Particles/components/atoms/Controls/index.jsx
deleted file mode 100644
index bac1f01..0000000
--- a/src/frontend/ui/models/Particles/components/atoms/Controls/index.jsx
+++ /dev/null
@@ -1,10 +0,0 @@
-//* Imports
-import { OrbitControls } from "@react-three/drei";
-
-//* Main
-export default function Controls({ config }) {
- // Props
- const { general: { showHelpers } } = config;
- // Return
- return showHelpers && ;
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Mouse/index.js b/src/frontend/ui/models/Particles/components/atoms/Mouse/index.js
new file mode 100644
index 0000000..d1ba805
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Mouse/index.js
@@ -0,0 +1,3 @@
+export { MouseHandler } from './logic/handler';
+export { MouseListener } from './logic/listener';
+export { MouseUpdate } from './logic/update';
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/handler.js b/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/handler.js
index ec9c24d..3ef64a9 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/handler.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/handler.js
@@ -2,16 +2,16 @@
* Mouse handler strategy for particle system
*/
-import { HandlerStrategy } from '../../../../logic/handlers/strategy';
+import { Vector2 } from 'three';
+import { ModelStrategy } from '@semantyk/frontend/ui/components/molecules/Model/logic/strategy';
import { updateOnMouseMove } from '../../../../logic/index';
-export class MouseHandler extends HandlerStrategy {
+export class MouseHandler extends ModelStrategy {
/**
- * Handle mouse/touch move events
- * @param {MouseEvent|TouchEvent} event - Mouse or touch event
- * @param {Object} args - Particle system arguments
+ * Execute mouse/touch move events
+ * @param {Object} args - Arguments containing event and particle system data
*/
- handle(event, args) {
+ execute({ event, ...args }) {
const { mouse, moveMouseTimeout } = args.refs;
clearTimeout(moveMouseTimeout.current);
mouse.current.isMoving = true;
diff --git a/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/listener.js b/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/listener.js
index f5bdaa9..d9f1bfe 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/listener.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/listener.js
@@ -1,6 +1,6 @@
-import { ListenerStrategy } from '../../../../logic/listeners/strategy';
+import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
-export class MouseListener extends ListenerStrategy {
+export class MouseListener extends ModelStrategy {
add({ handleMouseMove }) {
window.addEventListener("mousemove", handleMouseMove);
window.addEventListener("touchmove", handleMouseMove);
diff --git a/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/update.js b/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/update.js
index 564efd0..b81889e 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/update.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/update.js
@@ -1,8 +1,8 @@
import { onMouseMove } from "@semantyk/frontend/logic/services/callbacks";
-import { UpdateStrategy } from '../../../../logic/updates/strategy';
+import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
-export class MouseUpdate extends UpdateStrategy {
- apply({ refs, events }) {
+export class MouseUpdate extends ModelStrategy {
+ execute({ refs, events }) {
const { x, y } = onMouseMove(events.mousemove);
refs.mouse.current.x = x * 2 - 1;
refs.mouse.current.y = -y * 2 + 1;
diff --git a/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/color.js b/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/color.js
index 57bd581..6623815 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/color.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/color.js
@@ -1,11 +1,11 @@
import { Color } from 'three';
-import { EffectManager } from '../../../../../logic/effects/manager';
-import { UpdateStrategy } from '../../../../../logic/updates/strategy';
+import { ParticleManager } from '../../../../../logic/manager';
+import { ParticleStrategy } from '../../../../../logic/strategy';
-export class ColorUpdate extends UpdateStrategy {
+export class ColorUpdate extends ParticleStrategy {
apply({ i, colors, particles, ...args }) {
const final = new Color();
- EffectManager.addEffect("color", { colors, particles, i, final, ...args });
+ ParticleManager.addEffect("color", { colors, particles, i, final, ...args });
colors.set(final.toArray(), i * 3);
}
}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/position.js b/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/position.js
index 18e09e8..b643b60 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/position.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/position.js
@@ -1,11 +1,11 @@
import { Vector3 } from 'three';
-import { EffectManager } from '../../../../../logic/effects/manager';
-import { UpdateStrategy } from '../../../../../logic/updates/strategy';
+import { ParticleManager } from '../../../../../logic/manager';
+import { ParticleStrategy } from '../../../../../logic/strategy';
-export class PositionUpdate extends UpdateStrategy {
+export class PositionUpdate extends ParticleStrategy {
apply({ object, positions, i, ...args }) {
const final = new Vector3();
- EffectManager.addEffect("position", { positions, object, i, final, ...args });
+ ParticleManager.addEffect("position", { positions, object, i, final, ...args });
positions.set(final.toArray(), i * 3);
}
}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos.js
new file mode 100644
index 0000000..56149f0
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos.js
@@ -0,0 +1,25 @@
+import { ModelStrategy } from '@semantyk/frontend/ui/components/molecules/Model/logic/strategy';
+
+export class ChaosEffect extends ModelStrategy {
+ execute({ config, data, i, idxs, final, objects: { clock }, refs: { mouse, particles } }) {
+ const { unit } = data;
+ const { animations: { chaos, order, interpolation } } = config;
+ const elapsedTime = clock.current.getElapsedTime();
+
+ if (elapsedTime < interpolation.duration) return;
+
+ let magnitude;
+ let currentChaos = particles.current.data.chaotic[i];
+
+ if (idxs.has(i) && mouse.current.isMoving) {
+ currentChaos += chaos.magnitude;
+ magnitude = Math.min(currentChaos, 1);
+ } else {
+ currentChaos -= order.magnitude / unit;
+ magnitude = Math.max(currentChaos, 0);
+ }
+
+ particles.current.data.chaotic[i] = magnitude;
+ final.multiplyScalar(magnitude);
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos/effect.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos/effect.js
deleted file mode 100644
index 59bacc9..0000000
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos/effect.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import { EffectStrategy } from '../../../../../logic/effects/strategy';
-
-export class ChaosEffect extends EffectStrategy {
- apply({ config, data, i, idxs, mouse, particles }) {
- const { unit } = data;
- const { animations: { chaos, order } } = config;
-
- let magnitude;
- let currentChaos = particles.data.chaotic[i];
-
- if (idxs.has(i) && mouse.current.isMoving) {
- currentChaos += chaos.magnitude;
- magnitude = Math.min(currentChaos, 1);
- } else {
- currentChaos -= order.magnitude / unit;
- magnitude = Math.max(currentChaos, 0);
- }
-
- particles.data.chaotic[i] = magnitude;
- }
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos/update.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos/update.js
deleted file mode 100644
index 1771b66..0000000
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos/update.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import { UpdateStrategy } from '../../../../../logic/updates/strategy';
-import { EffectManager } from '../../../../../logic/effects/manager';
-
-export class ChaosUpdate extends UpdateStrategy {
- apply(params) {
- EffectManager.addEffect("chaos", params);
- }
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/color.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/color.js
new file mode 100644
index 0000000..bc596fc
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/color.js
@@ -0,0 +1,12 @@
+import { Color } from 'three';
+import { ModelStrategy } from '@semantyk/frontend/ui/components/molecules/Model/logic/strategy';
+
+export class ColorEffect extends ModelStrategy {
+ execute({ data: { color }, i, ...args }) {
+ const chaoticValue = args.refs.particles.current.data.chaotic[i];
+ const final = color.clone();
+ const target = new Color(1, 0, 0);
+ final.lerp(target, chaoticValue);
+ args.refs.particles.current.geometry.attributes.color.set(final.toArray(), i * 3);
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/color/effect.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/color/effect.js
deleted file mode 100644
index 5db63fe..0000000
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/color/effect.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import { Color } from 'three';
-import { EffectStrategy } from '../../../../../logic/effects/strategy';
-
-export class ColorEffect extends EffectStrategy {
- apply({ particles, i, final, colors }) {
- const chaoticValue = particles.data.chaotic[i];
- const target = new Color(1, 0, 0);
- final.lerp(target, chaoticValue);
- colors.set(final.toArray(), i * 3);
- }
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/color/update.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/color/update.js
deleted file mode 100644
index 57bd581..0000000
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/color/update.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import { Color } from 'three';
-import { EffectManager } from '../../../../../logic/effects/manager';
-import { UpdateStrategy } from '../../../../../logic/updates/strategy';
-
-export class ColorUpdate extends UpdateStrategy {
- apply({ i, colors, particles, ...args }) {
- const final = new Color();
- EffectManager.addEffect("color", { colors, particles, i, final, ...args });
- colors.set(final.toArray(), i * 3);
- }
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/entropy.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/entropy.js
new file mode 100644
index 0000000..741e222
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/entropy.js
@@ -0,0 +1,20 @@
+import { Vector3 } from 'three';
+import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
+
+export class EntropyEffect extends ModelStrategy {
+ execute({ config, i, idxs, final, ...args }) {
+ const { animations: { expansion, interpolation } } = config;
+ const elapsedTime = args.objects.clock.current.getElapsedTime();
+
+ if (elapsedTime < interpolation.duration) return;
+ const { ideal } = args.refs.particles.current.data.positions;
+ const positions = args.refs.particles.current.geometry.attributes.position.array;
+
+ const source = new Vector3().fromArray(positions, i * 3);
+ const target = new Vector3().fromArray(ideal, i * 3);
+ const effect = new Vector3().subVectors(source, target);
+ effect.multiplyScalar(expansion.magnitude);
+
+ final.add(effect);
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/expansion/effect.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/expansion/effect.js
deleted file mode 100644
index ca14ba3..0000000
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/expansion/effect.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import { Vector3 } from 'three';
-import { EffectStrategy } from '../../../../../logic/effects/strategy';
-
-export class ExpansionEffect extends EffectStrategy {
- apply({ config, object, i, final }) {
- const { animations: { expansion } } = config;
- const chaosValue = object.data.chaotic[i];
- const { ideal } = object.data.positions;
- const positions = object.geometry.attributes.position.array;
-
- const source = new Vector3().fromArray(positions, i * 3);
- const target = new Vector3().fromArray(ideal, i * 3);
- const effect = new Vector3().subVectors(source, target);
- effect.multiplyScalar(chaosValue);
- effect.multiplyScalar(expansion.magnitude);
-
- final.add(effect);
- }
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/flotation.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/flotation.js
new file mode 100644
index 0000000..73a6bae
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/flotation.js
@@ -0,0 +1,20 @@
+import { Vector3 } from 'three';
+import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
+
+export class FlotationEffect extends ModelStrategy {
+ execute({ config, i, final, objects: { clock }, refs: { particles } }) {
+ const { offsets } = particles.current.data.positions;
+ const { animations: { flotation } } = config;
+ const elapsedTime = clock.current.getElapsedTime();
+
+ const vector = new Vector3().fromArray(offsets, i * 3);
+ vector.addScalar(elapsedTime * flotation.speed);
+ const effect = new Vector3(
+ Math.sin(vector.x),
+ Math.sin(vector.y)
+ );
+ effect.multiplyScalar(flotation.magnitude);
+
+ final.add(effect);
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/flotation/effect.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/flotation/effect.js
deleted file mode 100644
index a3d280e..0000000
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/flotation/effect.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import { Vector3 } from 'three';
-import { EffectStrategy } from '../../../../../logic/effects/strategy';
-
-export class FlotationEffect extends EffectStrategy {
- apply({ config, object, i, final, time }) {
- const { offsets } = object.data.positions;
- const { animations: { flotation } } = config;
-
- const vector = new Vector3().fromArray(offsets, i * 3);
- vector.addScalar(time * flotation.speed);
- const effect = new Vector3(
- Math.sin(vector.x),
- Math.sin(vector.y)
- );
- effect.multiplyScalar(flotation.magnitude);
-
- final.add(effect);
- }
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/index.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/index.js
new file mode 100644
index 0000000..f033d6b
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/index.js
@@ -0,0 +1,4 @@
+export { ChaosEffect } from './chaos';
+export { ColorEffect } from './color';
+export { EntropyEffect } from './entropy';
+export { PositionEffect } from './position';
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/interpolation/effect.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/interpolation.js
similarity index 52%
rename from src/frontend/ui/models/Particles/components/atoms/Particles/effects/interpolation/effect.js
rename to src/frontend/ui/models/Particles/components/atoms/Particles/effects/interpolation.js
index 3c138c3..882a536 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/interpolation/effect.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/interpolation.js
@@ -1,16 +1,17 @@
import { Vector3 } from 'three';
import { ease } from "@semantyk/frontend/ui/models/Particles/logic";
-import { EffectStrategy } from '../../../../../logic/effects/strategy';
+import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
-export class InterpolationEffect extends EffectStrategy {
- apply({ config, time, object, i, final }) {
- const { ideal, initial } = object.data.positions;
+export class InterpolationEffect extends ModelStrategy {
+ execute({ config, i, final, objects: { clock }, refs: { particles } }) {
+ const { ideal, initial } = particles.current.data.positions;
const { animations: { interpolation: { duration } } } = config;
const source = new Vector3().fromArray(initial, i * 3);
const target = new Vector3().fromArray(ideal, i * 3);
- const easedTime = ease(time, duration);
+ const elapsedTime = clock.current.getElapsedTime();
+ const easedTime = ease(elapsedTime, duration);
source.multiplyScalar(1 - easedTime);
target.multiplyScalar(easedTime);
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/position.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/position.js
new file mode 100644
index 0000000..06c4db6
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/position.js
@@ -0,0 +1,31 @@
+import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
+import { InterpolationEffect } from './interpolation';
+import { FlotationEffect } from './flotation';
+import { EntropyEffect } from './entropy';
+import { Vector3 } from 'three';
+import { ChaosEffect } from "./chaos";
+
+export class PositionEffect extends ModelStrategy {
+ constructor() {
+ super();
+ this.chaosEffect = new ChaosEffect();
+ this.entropyEffect = new EntropyEffect();
+ this.interpolationEffect = new InterpolationEffect();
+ this.flotationEffect = new FlotationEffect();
+ }
+
+ execute({ i, idxs, ...args }) {
+ const { particles } = args.refs;
+ const final = new Vector3()
+
+ //* Effects
+ //! Order Matters
+ this.entropyEffect.execute({ i, idxs, final, ...args });
+ this.chaosEffect.execute({ i, idxs, final, ...args });
+ this.interpolationEffect.execute({ i, final, ...args });
+ this.flotationEffect.execute({ i, final, ...args });
+
+ const positions = particles.current.geometry.attributes.position.array;
+ positions.set(final.toArray(), i * 3);
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/position/effect.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/position/effect.js
deleted file mode 100644
index 8962ab4..0000000
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/position/effect.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import { EffectStrategy } from '../../../../../logic/effects/strategy';
-import { InterpolationEffect } from '../interpolation/effect';
-import { FlotationEffect } from '../flotation/effect';
-import { ExpansionEffect } from '../expansion/effect';
-
-export class PositionEffect extends EffectStrategy {
- constructor() {
- super();
- this.interpolationEffect = new InterpolationEffect();
- this.flotationEffect = new FlotationEffect();
- this.expansionEffect = new ExpansionEffect();
- }
-
- apply(args) {
- const { animations: { interpolation } } = args.config;
-
- this.interpolationEffect.apply(args);
- this.flotationEffect.apply(args);
-
- if (args.time >= interpolation.duration) {
- this.expansionEffect.apply(args);
- }
- }
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/position/update.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/position/update.js
deleted file mode 100644
index 18e09e8..0000000
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/position/update.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import { Vector3 } from 'three';
-import { EffectManager } from '../../../../../logic/effects/manager';
-import { UpdateStrategy } from '../../../../../logic/updates/strategy';
-
-export class PositionUpdate extends UpdateStrategy {
- apply({ object, positions, i, ...args }) {
- const final = new Vector3();
- EffectManager.addEffect("position", { positions, object, i, final, ...args });
- positions.set(final.toArray(), i * 3);
- }
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/resize/resize.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/resize/resize.js
deleted file mode 100644
index 93f3b52..0000000
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/resize/resize.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/**
- * Resize handler strategy for particle system
- */
-
-import { HandlerStrategy } from '../../../../../logic/handlers/strategy';
-import { SetupManager } from '../../../../../logic/setups/manager';
-
-export class ResizeHandler extends HandlerStrategy {
- /**
- * Handle window resize events
- * @param {Event} event - Window resize event
- * @param {Object} args - Particle system arguments
- */
- handle(event, args) {
- const { particles } = args.refs;
- SetupManager.setupObject("camera", args);
- const { particle } = args.config;
- const ratio = window.innerWidth / window.innerHeight;
- const size = Math.min(Math.max(particle.size * ratio, 0), particle.size);
- particles.current.material.size = size;
- }
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/handlers/index.js b/src/frontend/ui/models/Particles/components/atoms/Particles/handlers/index.js
new file mode 100644
index 0000000..c514824
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/handlers/index.js
@@ -0,0 +1 @@
+export { ResizeHandler } from './resize';
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/handlers/resize.js b/src/frontend/ui/models/Particles/components/atoms/Particles/handlers/resize.js
new file mode 100644
index 0000000..eda995f
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/handlers/resize.js
@@ -0,0 +1,21 @@
+/**
+ * Resize handler strategy for particle system
+ */
+
+import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
+import { ParticlesModelManager } from '../../../../logic/manager';
+
+export class ResizeHandler extends ModelStrategy {
+ /**
+ * Execute window resize events
+ * @param {Object} args - Arguments containing event and particle system data
+ */
+ execute({ event, ...args }) {
+ const { particles } = args.refs;
+ ParticlesModelManager.execute('setupObject', "camera", args);
+ const { particle } = args.config;
+ const ratio = window.innerWidth / window.innerHeight;
+ const size = Math.min(Math.max(particle.size * ratio, 0), particle.size);
+ particles.current.material.size = size;
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/index.js b/src/frontend/ui/models/Particles/components/atoms/Particles/index.js
new file mode 100644
index 0000000..eae883e
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/index.js
@@ -0,0 +1,3 @@
+export * from './effects';
+export * from './handlers';
+export * from './logic';
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/logic/index.js b/src/frontend/ui/models/Particles/components/atoms/Particles/logic/index.js
new file mode 100644
index 0000000..b9ee04a5
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/logic/index.js
@@ -0,0 +1,2 @@
+export { ParticlesSetup } from './setup';
+export { ParticlesUpdate } from './update';
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/logic/setup.js b/src/frontend/ui/models/Particles/components/atoms/Particles/logic/setup.js
index 2fb3f56..afbe6e3 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/logic/setup.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/logic/setup.js
@@ -1,20 +1,25 @@
+/**
+ * Particles setup strategy for particle system
+ */
+
import { Float32BufferAttribute } from 'three';
-import { SetupStrategy } from '../../../../logic/setups/strategy';
+import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
import { getImageData } from '../../../../logic';
-
-export class ParticlesSetup extends SetupStrategy {
- apply({ config, data: { color, unit }, objects: { image }, refs }) {
+export class ParticlesSetup extends ModelStrategy {
+ /**
+ * Execute particles setup
+ * @param {Object} args - Arguments containing config, data, objects, and refs
+ */
+ execute({ config, data: { color, unit }, objects: { image }, refs }) {
const { particle } = config;
const particles = refs.particles.current;
const { data } = getImageData({ data: { unit }, objects: { image } });
particles.data = {
- label: "particles",
count: 0,
chaotic: [],
- color,
colors: [],
positions: { ideal: [], initial: [], offsets: [] },
};
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/logic/update.js b/src/frontend/ui/models/Particles/components/atoms/Particles/logic/update.js
index 42ddb81..4464974 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/logic/update.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/logic/update.js
@@ -1,41 +1,17 @@
-import { UpdateManager } from '../../../../logic/updates/manager';
-import { UpdateStrategy } from '../../../../logic/updates/strategy';
+import { ParticlesModelManager } from '../../../../logic/manager';
+import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
-export class ParticlesUpdate extends UpdateStrategy {
- apply({ config, objects, refs: { mouse, particles }, ...args }) {
- const { clock } = objects;
- const { animations: { interpolation } } = config;
-
- const object = particles.current;
- const time = clock.current.getElapsedTime();
- const intersects = objects.raycaster.intersectObject(object);
+export class ParticlesUpdate extends ModelStrategy {
+ execute(args) {
+ const intersects = args.objects.raycaster.intersectObject(args.refs.particles.current);
const idxs = new Set(intersects.map(({ index }) => index));
- const positions = object.geometry.attributes.position.array;
- for (let i = 0; i < object.data.count; i++) {
- if (time >= interpolation.duration) {
- UpdateManager.updateAttribute("chaos", {
- config,
- i,
- idxs,
- mouse,
- particles: object,
- ...args
- });
- }
- UpdateManager.updateAttribute("position", {
- config,
- i,
- idxs,
- object,
- positions,
- particles,
- time,
- ...args
- });
+ for (let i = 0; i < args.refs.particles.current.data.count; i++) {
+ ParticlesModelManager.execute('updateAttribute', "color", { i, ...args });
+ ParticlesModelManager.execute('updateAttribute', "position", { i, idxs, ...args });
}
- object.geometry.attributes.color.needsUpdate = true;
- object.geometry.attributes.position.needsUpdate = true;
+ args.refs.particles.current.geometry.attributes.color.needsUpdate = true;
+ args.refs.particles.current.geometry.attributes.position.needsUpdate = true;
}
}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Plane/index.jsx b/src/frontend/ui/models/Particles/components/atoms/Plane/index.jsx
index 9fff14d..a5b358c 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Plane/index.jsx
+++ b/src/frontend/ui/models/Particles/components/atoms/Plane/index.jsx
@@ -1,3 +1,8 @@
+//* Imports
+import { PlaneSetup } from './logic/setup';
+
+export { PlaneSetup };
+
//* Main
export default function Plane({ config, data, refs }) {
// Props
diff --git a/src/frontend/ui/models/Particles/components/atoms/Plane/logic/setup.js b/src/frontend/ui/models/Particles/components/atoms/Plane/logic/setup.js
index 68cb95d..d57c525 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Plane/logic/setup.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Plane/logic/setup.js
@@ -1,8 +1,16 @@
+/**
+ * Plane setup strategy for particle system
+ */
+
import { Plane, Vector3 } from 'three';
-import { SetupStrategy } from '../../../../logic/setups/strategy';
+import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
-export class PlaneSetup extends SetupStrategy {
- apply({ data: { unit }, refs: { plane } }) {
+export class PlaneSetup extends ModelStrategy {
+ /**
+ * Execute plane setup
+ * @param {Object} args - Arguments containing data and refs
+ */
+ execute({ data: { unit }, refs: { plane } }) {
const normal = new Vector3(0, 0, 1);
plane.current = new Plane(normal, unit / 2);
}
diff --git a/src/frontend/ui/models/Particles/components/atoms/RayLine/index.jsx b/src/frontend/ui/models/Particles/components/atoms/RayLine/index.jsx
index 20938db..361a4bf 100644
--- a/src/frontend/ui/models/Particles/components/atoms/RayLine/index.jsx
+++ b/src/frontend/ui/models/Particles/components/atoms/RayLine/index.jsx
@@ -3,6 +3,11 @@
* Atom component for the ray line in the Particles model
*/
+//* Imports
+import { LineUpdate } from './logic/update';
+
+export { LineUpdate };
+
//* Main
export default function RayLine({ config, refs }) {
// Props
diff --git a/src/frontend/ui/models/Particles/components/atoms/RayLine/logic/line.js b/src/frontend/ui/models/Particles/components/atoms/RayLine/logic/update.js
similarity index 62%
rename from src/frontend/ui/models/Particles/components/atoms/RayLine/logic/line.js
rename to src/frontend/ui/models/Particles/components/atoms/RayLine/logic/update.js
index bf8de0a..a6dbc36 100644
--- a/src/frontend/ui/models/Particles/components/atoms/RayLine/logic/line.js
+++ b/src/frontend/ui/models/Particles/components/atoms/RayLine/logic/update.js
@@ -1,8 +1,8 @@
import { BufferGeometry } from 'three';
-import { UpdateStrategy } from '../../../../logic/updates/strategy';
+import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
-export class LineUpdate extends UpdateStrategy {
- apply({ objects, refs, target }) {
+export class LineUpdate extends ModelStrategy {
+ execute({ objects, refs, target }) {
const { origin } = objects.raycaster.ray;
const points = [origin, target];
const geometry = new BufferGeometry().setFromPoints(points);
diff --git a/src/frontend/ui/models/Particles/components/atoms/Raycaster/index.js b/src/frontend/ui/models/Particles/components/atoms/Raycaster/index.js
new file mode 100644
index 0000000..d726742
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Raycaster/index.js
@@ -0,0 +1,2 @@
+export { RaycasterSetup } from './logic/setup';
+export { RaycasterUpdate } from './logic/update';
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Raycaster/logic/setup.js b/src/frontend/ui/models/Particles/components/atoms/Raycaster/logic/setup.js
index f3729ae..012ef54 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Raycaster/logic/setup.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Raycaster/logic/setup.js
@@ -1,7 +1,15 @@
-import { SetupStrategy } from '../../../../logic/setups/strategy';
+/**
+ * Raycaster setup strategy for particle system
+ */
-export class RaycasterSetup extends SetupStrategy {
- apply({ config, data: { unit }, objects: { raycaster } }) {
+import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
+
+export class RaycasterSetup extends ModelStrategy {
+ /**
+ * Execute raycaster setup
+ * @param {Object} args - Arguments containing config, data, and objects
+ */
+ execute({ config, data: { unit }, objects: { raycaster } }) {
const { animations: { chaos: { radius } } } = config;
raycaster.params.Points.threshold = radius * unit;
}
diff --git a/src/frontend/ui/models/Particles/components/atoms/Raycaster/logic/update.js b/src/frontend/ui/models/Particles/components/atoms/Raycaster/logic/update.js
index 092dd25..237c8a6 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Raycaster/logic/update.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Raycaster/logic/update.js
@@ -1,8 +1,8 @@
import { Vector2 } from 'three';
-import { UpdateStrategy } from '../../../../logic/updates/strategy';
+import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
-export class RaycasterUpdate extends UpdateStrategy {
- apply({ objects, refs }) {
+export class RaycasterUpdate extends ModelStrategy {
+ execute({ objects, refs }) {
const { raycaster } = objects;
const camera = refs.camera.current;
const mouse = refs.mouse.current;
diff --git a/src/frontend/ui/models/Particles/components/atoms/index.js b/src/frontend/ui/models/Particles/components/atoms/index.js
new file mode 100644
index 0000000..7227091
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/index.js
@@ -0,0 +1,9 @@
+export * from './Camera';
+export * from './Circle';
+export * from './Mouse';
+export * from './Plane';
+export * from './Particles/effects';
+export * from './Particles/handlers';
+export * from './Particles/logic';
+export * from './Raycaster';
+export * from './RayLine';
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/molecules/Controls/index.jsx b/src/frontend/ui/models/Particles/components/molecules/Controls/index.jsx
new file mode 100644
index 0000000..a0e2e3f
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/molecules/Controls/index.jsx
@@ -0,0 +1,22 @@
+//* Imports
+import { OrbitControls } from "@react-three/drei";
+import Box from "../../atoms/Box";
+import Circle from "../../atoms/Circle";
+import Plane from "../../atoms/Plane";
+import RayLine from "../../atoms/RayLine";
+import Camera from "../../atoms/Camera";
+
+//* Main
+export default function Controls(args) {
+ // Props
+ const { general: { showHelpers } } = args.config;
+ // Return
+ return (<>
+
+
+
+
+
+ {showHelpers && }
+ >);
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/molecules/ParticleSystem.jsx b/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/index.jsx
similarity index 53%
rename from src/frontend/ui/models/Particles/components/molecules/ParticleSystem.jsx
rename to src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/index.jsx
index 25f0389..7b0f9c6 100644
--- a/src/frontend/ui/models/Particles/components/molecules/ParticleSystem.jsx
+++ b/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/index.jsx
@@ -6,31 +6,29 @@
//* Imports
import { useEffect } from "react";
import { useFrame } from "@react-three/fiber";
-import Particles from "../atoms/Particles";
+import Particles from "../../atoms/Particles/index.jsx";
import {
setupObjects,
updateObjects,
} from "@semantyk/frontend/ui/models/Particles/logic";
-import { SetupManager } from "../../logic/setups/manager";
-import { ListenerManager } from "../../logic/listeners/manager";
-import { HandlerManager } from "../../logic/handlers/manager";
+import { ParticlesModelManager } from "../../../logic/manager.js";
//* Main
-export default function ParticleSystem(args) {
+export default function ParticlesSystem(args) {
// Logic
useEffect(() => {
setupObjects(args);
const handleMouseMove = (event) => {
- HandlerManager.handleMouseMove(event, args);
+ ParticlesModelManager.execute('handleEvent', 'mouse', event, args);
};
const handleResize = (event) => {
- HandlerManager.handleResize(event, args);
+ ParticlesModelManager.execute('handleEvent', 'resize', event, args);
};
- ListenerManager.addEventListeners({ handleMouseMove, handleResize });
- return () => ListenerManager.removeEventListeners({ handleMouseMove, handleResize });
+ ParticlesModelManager.execute('addEventListeners', { handleMouseMove, handleResize });
+ return () => ParticlesModelManager.execute('removeEventListeners', { handleMouseMove, handleResize });
}, [args]);
useFrame(({ clock }) => {
diff --git a/src/frontend/ui/models/Particles/components/organisms/ParticlesScene.jsx b/src/frontend/ui/models/Particles/components/organisms/ParticlesScene.jsx
deleted file mode 100644
index 0b70415..0000000
--- a/src/frontend/ui/models/Particles/components/organisms/ParticlesScene.jsx
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
- * # `ParticlesScene.jsx`
- * @organization: Semantyk
- * @project: Client
- *
- * @file: This file contains the logic for the ParticlesScene component.
- *
- * @created: Mar 13, 2025
- * @modified: Mar 13, 2025
- *
- * @author: Semantyk Team
- * @maintainer: Daniel Bakas
- *
- * @copyright: Semantyk © 2025. All rights reserved.
- * –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
- */
-
-//* Imports
-import { useArgs } from "@semantyk/frontend/ui/models/Particles/hooks/useArgs";
-import { config } from "@semantyk/frontend/ui/models/Particles/config";
-import Camera from "../atoms/Camera";
-import Controls from "../atoms/Controls";
-import Box from "../atoms/Box";
-import Circle from "../atoms/Circle";
-import ParticleSystem from "../molecules/ParticleSystem";
-import Plane from "../atoms/Plane";
-import RayLine from "../atoms/RayLine";
-
-//* Main
-export default function ParticlesScene() {
- // Hooks
- const args = useArgs();
- // Return
- return (<>
-
-
-
-
-
-
-
- >);
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/config/index.js b/src/frontend/ui/models/Particles/config/index.js
index 51d778e..3842e7d 100644
--- a/src/frontend/ui/models/Particles/config/index.js
+++ b/src/frontend/ui/models/Particles/config/index.js
@@ -20,7 +20,7 @@
export const config = {
// General
general: {
- showHelpers: true,
+ showHelpers: false,
scale: 1,
size: 150,
},
diff --git a/src/frontend/ui/models/Particles/hooks/useArgs.jsx b/src/frontend/ui/models/Particles/hooks/useArgs.jsx
index ca95f33..5f1b224 100644
--- a/src/frontend/ui/models/Particles/hooks/useArgs.jsx
+++ b/src/frontend/ui/models/Particles/hooks/useArgs.jsx
@@ -52,8 +52,8 @@ export function useArgs() {
box: useRef(),
camera: useRef(),
circle: useRef(),
- mouse: useRef({ x: 0, y: 0 }),
- moveMouseTimeout: useRef(),
+ mouse: useRef({ current: { x: 0, y: 0, isMoving: false } }),
+ moveMouseTimeout: useRef(null),
particles: useRef(),
plane: useRef(),
rayLine: useRef(),
diff --git a/src/frontend/ui/models/Particles/index.jsx b/src/frontend/ui/models/Particles/index.jsx
index e32ae97..b1427fe 100644
--- a/src/frontend/ui/models/Particles/index.jsx
+++ b/src/frontend/ui/models/Particles/index.jsx
@@ -1,13 +1,13 @@
/**
* –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
- * # `index.jsx` | `ParticlesModel`
+ * # `ParticlesScene.jsx`
* @organization: Semantyk
* @project: Client
*
- * @file: This file contains the main entry point for the Particles model.
+ * @file: This file contains the logic for the ParticlesScene component.
*
- * @created: Sep 12, 2024
- * @modified: Mar 12, 2025
+ * @created: Mar 13, 2025
+ * @modified: Mar 13, 2025
*
* @author: Semantyk Team
* @maintainer: Daniel Bakas
@@ -16,8 +16,19 @@
* –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
*/
-import ParticlesScene from "./components/organisms/ParticlesScene";
+//* Imports
+import { useArgs } from "@semantyk/frontend/ui/models/Particles/hooks/useArgs";
+import Controls from "./components/molecules/Controls";
+import ParticlesSystem from "./components/molecules/ParticlesSystem";
+import Camera from "./components/atoms/Camera";
+//* Main
export default function ParticlesModel() {
- return ;
+ // Hooks
+ const args = useArgs();
+ // Return
+ return (<>
+
+
+ >);
}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/effects/manager.js b/src/frontend/ui/models/Particles/logic/effects/manager.js
deleted file mode 100644
index 47437a9..0000000
--- a/src/frontend/ui/models/Particles/logic/effects/manager.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import { ChaosEffect } from '../../components/atoms/Particles/effects/chaos/effect';
-import { ColorEffect } from '../../components/atoms/Particles/effects/color/effect';
-import { PositionEffect } from '../../components/atoms/Particles/effects/position/effect';
-
-/**
- * Manager class that handles all particle effects using the Strategy pattern
- */
-export class EffectManager {
- static instance = new EffectManager();
-
- constructor() {
- this.strategies = {
- chaos: new ChaosEffect(),
- color: new ColorEffect(),
- position: new PositionEffect()
- };
- }
-
- addEffect(type, args) {
- const strategy = this.strategies[type];
- if (strategy) {
- strategy.apply(args);
- }
- }
-
- static addEffect(type, args) {
- return EffectManager.instance.addEffect(type, args);
- }
-}
-
-export const { addEffect } = EffectManager;
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/effects/strategy.js b/src/frontend/ui/models/Particles/logic/effects/strategy.js
deleted file mode 100644
index a283135..0000000
--- a/src/frontend/ui/models/Particles/logic/effects/strategy.js
+++ /dev/null
@@ -1,13 +0,0 @@
-/**
- * Base class for particle effects following the Strategy Pattern
- */
-export class EffectStrategy {
- /**
- * Apply the effect
- * @param {Object} args - Effect arguments
- * @throws {Error} Must be implemented by child classes
- */
- apply(args) {
- throw new Error('Effect strategy must implement apply method');
- }
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/handlers/manager.js b/src/frontend/ui/models/Particles/logic/handlers/manager.js
deleted file mode 100644
index 487fcf2..0000000
--- a/src/frontend/ui/models/Particles/logic/handlers/manager.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * Manager for particle system event handlers
- */
-
-import { MouseHandler } from '../../components/atoms/Mouse/logic/handler';
-import { ResizeHandler } from '../../components/atoms/Particles/effects/resize/resize';
-
-export class HandlerManager {
- static #instance = null;
- #mouseHandler = new MouseHandler();
- #resizeHandler = new ResizeHandler();
-
- /**
- * Get the singleton instance
- * @returns {HandlerManager}
- */
- static getInstance() {
- if (!HandlerManager.#instance) {
- HandlerManager.#instance = new HandlerManager();
- }
- return HandlerManager.#instance;
- }
-
- /**
- * Handle mouse/touch move event
- * @param {MouseEvent|TouchEvent} event - Mouse or touch event
- * @param {Object} args - Particle system arguments
- */
- handleMouseMove(event, args) {
- this.#mouseHandler.handle(event, args);
- }
-
- /**
- * Handle window resize event
- * @param {Event} event - Window resize event
- * @param {Object} args - Particle system arguments
- */
- handleResize(event, args) {
- this.#resizeHandler.handle(event, args);
- }
-
- /**
- * Static method to handle mouse/touch move event
- * @param {MouseEvent|TouchEvent} event - Mouse or touch event
- * @param {Object} args - Particle system arguments
- */
- static handleMouseMove(event, args) {
- HandlerManager.getInstance().handleMouseMove(event, args);
- }
-
- /**
- * Static method to handle window resize event
- * @param {Event} event - Window resize event
- * @param {Object} args - Particle system arguments
- */
- static handleResize(event, args) {
- HandlerManager.getInstance().handleResize(event, args);
- }
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/handlers/strategy.js b/src/frontend/ui/models/Particles/logic/handlers/strategy.js
deleted file mode 100644
index 1eafcd2..0000000
--- a/src/frontend/ui/models/Particles/logic/handlers/strategy.js
+++ /dev/null
@@ -1,14 +0,0 @@
-/**
- * Base class for particle event handlers following the Strategy Pattern
- */
-export class HandlerStrategy {
- /**
- * Handle the event
- * @param {Object} event - Event object
- * @param {Object} args - Additional arguments
- * @throws {Error} Must be implemented by child classes
- */
- handle(event, args) {
- throw new Error('Handler strategy must implement handle method');
- }
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/index.js b/src/frontend/ui/models/Particles/logic/index.js
index bf21a74..ed52cba 100644
--- a/src/frontend/ui/models/Particles/logic/index.js
+++ b/src/frontend/ui/models/Particles/logic/index.js
@@ -17,8 +17,7 @@
//* Imports
import { Vector3 } from "three";
//* Local Imports
-import { UpdateManager } from "./updates/manager";
-import { SetupManager } from "./setups/manager";
+import { ParticlesModelManager } from "./manager";
//* Main
export function getImageData(args) {
@@ -41,21 +40,21 @@ export function ease(time, duration) {
}
export function setupObjects(args) {
- SetupManager.setupObject("camera", args);
- SetupManager.setupObject("plane", args);
- SetupManager.setupObject("particles", args);
- SetupManager.setupObject("raycaster", args);
+ ParticlesModelManager.execute('setupObject', "camera", args);
+ ParticlesModelManager.execute('setupObject', "plane", args);
+ ParticlesModelManager.execute('setupObject', "particles", args);
+ ParticlesModelManager.execute('setupObject', "raycaster", args);
}
export function updateObjects(args) {
- UpdateManager.updateObject("particles", args);
+ ParticlesModelManager.execute('updateObject', "particles", args);
}
export function updateOnMouseMove(args) {
const target = new Vector3();
- UpdateManager.updateObject("camera", args);
- UpdateManager.updateObject("raycaster", args);
- UpdateManager.updateObject("mouse", args);
- UpdateManager.updateObject("circle", { target, ...args });
- UpdateManager.updateObject("line", { target, ...args });
+ ParticlesModelManager.execute('updateObject', "camera", args);
+ ParticlesModelManager.execute('updateObject', "raycaster", args);
+ ParticlesModelManager.execute('updateObject', "mouse", args);
+ ParticlesModelManager.execute('updateObject', "circle", { target, ...args });
+ ParticlesModelManager.execute('updateObject', "line", { target, ...args });
}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/listeners/manager.js b/src/frontend/ui/models/Particles/logic/listeners/manager.js
deleted file mode 100644
index 4faf509..0000000
--- a/src/frontend/ui/models/Particles/logic/listeners/manager.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import { MouseListener } from '../../components/atoms/Mouse/logic/listener';
-import { ResizeListener } from './resize';
-
-/**
- * Manager class that handles all particle event listeners using the Strategy pattern
- */
-export class ListenerManager {
- static instance = new ListenerManager();
-
- constructor() {
- this.strategies = {
- mouse: new MouseListener(),
- resize: new ResizeListener(),
- };
- }
-
- addEventListeners(args) {
- Object.values(this.strategies).forEach(strategy => {
- strategy.add(args);
- });
- }
-
- removeEventListeners(args) {
- Object.values(this.strategies).forEach(strategy => {
- strategy.remove(args);
- });
- }
-
- static addEventListeners(args) {
- return ListenerManager.instance.addEventListeners(args);
- }
-
- static removeEventListeners(args) {
- return ListenerManager.instance.removeEventListeners(args);
- }
-}
-
-export const { addEventListeners, removeEventListeners } = ListenerManager;
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/listeners/resize.js b/src/frontend/ui/models/Particles/logic/listeners/resize.js
index 9297517..2825069 100644
--- a/src/frontend/ui/models/Particles/logic/listeners/resize.js
+++ b/src/frontend/ui/models/Particles/logic/listeners/resize.js
@@ -1,6 +1,6 @@
-import { ListenerStrategy } from './strategy';
+import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
-export class ResizeListener extends ListenerStrategy {
+export class ResizeListener extends ModelStrategy {
add({ handleResize }) {
window.addEventListener("resize", handleResize);
}
diff --git a/src/frontend/ui/models/Particles/logic/listeners/strategy.js b/src/frontend/ui/models/Particles/logic/listeners/strategy.js
deleted file mode 100644
index f7b4f8c..0000000
--- a/src/frontend/ui/models/Particles/logic/listeners/strategy.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/**
- * Base class for particle event listeners following the Strategy Pattern
- */
-export class ListenerStrategy {
- /**
- * Add the event listener
- * @param {Object} args - Event arguments
- * @throws {Error} Must be implemented by child classes
- */
- add(args) {
- throw new Error('Listener strategy must implement add method');
- }
-
- /**
- * Remove the event listener
- * @param {Object} args - Event arguments
- * @throws {Error} Must be implemented by child classes
- */
- remove(args) {
- throw new Error('Listener strategy must implement remove method');
- }
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/manager.js b/src/frontend/ui/models/Particles/logic/manager.js
new file mode 100644
index 0000000..0995610
--- /dev/null
+++ b/src/frontend/ui/models/Particles/logic/manager.js
@@ -0,0 +1,88 @@
+import { ModelManager } from '@semantyk/frontend/ui/components/molecules/Model/logic/manager';
+import { ResizeListener } from './listeners/resize';
+import { CameraSetup } from '../components/atoms/Camera/logic/setup';
+import { CircleUpdate } from '../components/atoms/Circle/logic/update';
+import { MouseHandler, MouseListener, MouseUpdate } from '../components/atoms/Mouse';
+import { PlaneSetup } from '../components/atoms/Plane/logic/setup';
+import { RaycasterSetup, RaycasterUpdate } from '../components/atoms/Raycaster';
+import { LineUpdate } from '../components/atoms/RayLine/logic/update';
+import { ChaosEffect } from '../components/atoms/Particles/effects/chaos';
+import { ColorEffect } from '../components/atoms/Particles/effects/color';
+import { EntropyEffect } from '../components/atoms/Particles/effects/entropy';
+import { PositionEffect } from '../components/atoms/Particles/effects/position';
+import { ResizeHandler } from '../components/atoms/Particles/handlers/resize';
+import { ParticlesSetup } from '../components/atoms/Particles/logic/setup';
+import { ParticlesUpdate } from '../components/atoms/Particles/logic/update';
+
+/**
+ * Manager class for particle strategies using the Strategy pattern
+ */
+export class ParticlesModelManager extends ModelManager {
+ static instance = new ParticlesModelManager();
+
+ static execute(type, method, ...args) {
+ return this.instance[type](method, ...args);
+ }
+
+ constructor() {
+ super();
+ this.effects = {
+ chaos: new ChaosEffect(),
+ color: new ColorEffect(),
+ entropy: new EntropyEffect(),
+ position: new PositionEffect()
+ };
+
+ this.handlers = {
+ mouse: new MouseHandler(),
+ resize: new ResizeHandler()
+ };
+
+ this.setups = {
+ camera: new CameraSetup(),
+ particles: new ParticlesSetup(),
+ plane: new PlaneSetup(),
+ raycaster: new RaycasterSetup()
+ };
+
+ this.listeners = {
+ mouse: new MouseListener(),
+ resize: new ResizeListener()
+ };
+
+ this.updates = {
+ objects: {
+ circle: new CircleUpdate(),
+ line: new LineUpdate(),
+ mouse: new MouseUpdate(),
+ particles: new ParticlesUpdate(),
+ raycaster: new RaycasterUpdate(),
+ },
+ attributes: {
+ color: this.effects.color,
+ position: this.effects.position
+ }
+ };
+ }
+
+ // Instance methods
+ addEffect(type, args) {
+ return this.execute(this.effects, type, args);
+ }
+
+ handleEvent(type, event, args) {
+ return this.execute(this.handlers, type, { event, ...args });
+ }
+
+ setupObject(type, args) {
+ return this.execute(this.setups, type, args);
+ }
+
+ updateObject(type, args) {
+ return this.execute(this.updates.objects, type, args);
+ }
+
+ updateAttribute(type, args) {
+ return this.execute(this.updates.attributes, type, args);
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/setups/manager.js b/src/frontend/ui/models/Particles/logic/setups/manager.js
deleted file mode 100644
index 1e4c8e4..0000000
--- a/src/frontend/ui/models/Particles/logic/setups/manager.js
+++ /dev/null
@@ -1,33 +0,0 @@
-import { CameraSetup } from '../../components/atoms/Camera/logic/setup';
-import { ParticlesSetup } from '../../components/atoms/Particles/logic/setup';
-import { PlaneSetup } from '../../components/atoms/Plane/logic/setup';
-import { RaycasterSetup } from '../../components/atoms/Raycaster/logic/setup';
-
-/**
- * Manager class that handles all particle setups using the Strategy pattern
- */
-export class SetupManager {
- static instance = new SetupManager();
-
- constructor() {
- this.strategies = {
- camera: new CameraSetup(),
- particles: new ParticlesSetup(),
- plane: new PlaneSetup(),
- raycaster: new RaycasterSetup(),
- };
- }
-
- setupObject(type, args) {
- const strategy = this.strategies[type];
- if (strategy) {
- strategy.apply(args);
- }
- }
-
- static setupObject(type, args) {
- return SetupManager.instance.setupObject(type, args);
- }
-}
-
-export const { setupObject } = SetupManager;
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/setups/strategy.js b/src/frontend/ui/models/Particles/logic/setups/strategy.js
deleted file mode 100644
index 8a620b1..0000000
--- a/src/frontend/ui/models/Particles/logic/setups/strategy.js
+++ /dev/null
@@ -1,13 +0,0 @@
-/**
- * Base class for particle setups following the Strategy Pattern
- */
-export class SetupStrategy {
- /**
- * Apply the setup
- * @param {Object} args - Setup arguments
- * @throws {Error} Must be implemented by child classes
- */
- apply(args) {
- throw new Error('Setup strategy must implement apply method');
- }
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/updates/manager.js b/src/frontend/ui/models/Particles/logic/updates/manager.js
deleted file mode 100644
index 5a9ec9e..0000000
--- a/src/frontend/ui/models/Particles/logic/updates/manager.js
+++ /dev/null
@@ -1,55 +0,0 @@
-import { CircleUpdate } from '../../components/atoms/Circle/logic/update';
-import { LineUpdate } from '../../components/atoms/RayLine/logic/line';
-import { MouseUpdate } from '../../components/atoms/Mouse/logic/update';
-import { ParticlesUpdate } from '../../components/atoms/Particles/logic/update';
-import { RaycasterUpdate } from '../../components/atoms/Raycaster/logic/update';
-import { ChaosUpdate } from '../../components/atoms/Particles/effects/chaos/update';
-import { ColorUpdate } from '../../components/atoms/Particles/effects/color/update';
-import { PositionUpdate } from '../../components/atoms/Particles/effects/position/update';
-
-/**
- * Manager class that handles all particle updates using the Strategy pattern
- */
-export class UpdateManager {
- static instance = new UpdateManager();
-
- constructor() {
- this.objectStrategies = {
- circle: new CircleUpdate(),
- line: new LineUpdate(),
- mouse: new MouseUpdate(),
- particles: new ParticlesUpdate(),
- raycaster: new RaycasterUpdate(),
- };
-
- this.attributeStrategies = {
- chaos: new ChaosUpdate(),
- color: new ColorUpdate(),
- position: new PositionUpdate()
- };
- }
-
- updateObject(type, args) {
- const strategy = this.objectStrategies[type];
- if (strategy) {
- strategy.apply(args);
- }
- }
-
- updateAttribute(type, args) {
- const strategy = this.attributeStrategies[type];
- if (strategy) {
- strategy.apply(args);
- }
- }
-
- static updateObject(type, args) {
- return UpdateManager.instance.updateObject(type, args);
- }
-
- static updateAttribute(type, args) {
- return UpdateManager.instance.updateAttribute(type, args);
- }
-}
-
-export const { updateObject, updateAttribute } = UpdateManager;
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/updates/strategy.js b/src/frontend/ui/models/Particles/logic/updates/strategy.js
deleted file mode 100644
index 02695a1..0000000
--- a/src/frontend/ui/models/Particles/logic/updates/strategy.js
+++ /dev/null
@@ -1,13 +0,0 @@
-/**
- * Base class for particle updates following the Strategy Pattern
- */
-export class UpdateStrategy {
- /**
- * Apply the update
- * @param {Object} args - Update arguments
- * @throws {Error} Must be implemented by child classes
- */
- apply(args) {
- throw new Error('Update strategy must implement apply method');
- }
-}
\ No newline at end of file
From c20645c273e46490bbe29b073cfd94326820e706 Mon Sep 17 00:00:00 2001
From: "Daniel B."
Date: Thu, 13 Mar 2025 19:13:43 -0600
Subject: [PATCH 3/7] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20Refactor:=20Update=20P?=
=?UTF-8?q?articles=20model?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Simplify method calling
---
.../molecules/Model/logic/manager.js | 45 ++++--------
.../components/atoms/Mouse/updates/color.js | 4 +-
.../atoms/Mouse/updates/position.js | 2 +-
.../atoms/Particles/handlers/resize.js | 4 +-
.../atoms/Particles/logic/update.js | 6 +-
.../molecules/ParticlesSystem/index.jsx | 18 ++---
.../ui/models/Particles/logic/index.js | 25 ++++---
.../ui/models/Particles/logic/manager.js | 69 +++++++++----------
8 files changed, 72 insertions(+), 101 deletions(-)
diff --git a/src/frontend/ui/components/molecules/Model/logic/manager.js b/src/frontend/ui/components/molecules/Model/logic/manager.js
index aa03b56..55de217 100644
--- a/src/frontend/ui/components/molecules/Model/logic/manager.js
+++ b/src/frontend/ui/components/molecules/Model/logic/manager.js
@@ -9,48 +9,27 @@ export class ModelManager {
}
// Generic method to handle operations on collections
- execute(collection, type, args) {
- const item = collection[type];
+ execute(collection, key, args) {
+ const item = collection[key];
if (item) {
return item.execute(args);
}
}
+ // TODO: Add a method for `add` and `remove`
+
// Event listener methods
- addEventListeners(args) {
- Object.values(this.listeners).forEach(listener => {
- listener.add(args);
+ addAll(collectionName, args) {
+ const collection = this[collectionName];
+ Object.values(collection).forEach(item => {
+ item.add(args);
});
}
- removeEventListeners(args) {
- Object.values(this.listeners).forEach(listener => {
- listener.remove(args);
+ removeAll(collectionName, args) {
+ const collection = this[collectionName];
+ Object.values(collection).forEach(item => {
+ item.remove(args);
});
}
-
- // Static helper method that automatically uses the correct instance
- static execute(methodName, type, ...args) {
- const instance = this.instance;
- if (!instance) {
- throw new Error(`No instance found for ${this.name}. Make sure to initialize the static instance property.`);
- }
-
- switch (methodName) {
- case 'addEffect':
- return instance.addEffect(type, args[0]);
- case 'handleEvent':
- return instance.handleEvent(type, args[0], args[1]);
- case 'setupObject':
- return instance.setupObject(type, args[0]);
- case 'updateObject':
- return instance.updateObject(type, args[0]);
- case 'addEventListeners':
- return instance.addEventListeners(type);
- case 'removeEventListeners':
- return instance.removeEventListeners(type);
- default:
- throw new Error(`Unknown method ${methodName}`);
- }
- }
}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/color.js b/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/color.js
index 6623815..5528fc4 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/color.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/color.js
@@ -1,11 +1,11 @@
import { Color } from 'three';
-import { ParticleManager } from '../../../../../logic/manager';
import { ParticleStrategy } from '../../../../../logic/strategy';
+import { ParticlesManager } from '../../../../logic/manager';
export class ColorUpdate extends ParticleStrategy {
apply({ i, colors, particles, ...args }) {
const final = new Color();
- ParticleManager.addEffect("color", { colors, particles, i, final, ...args });
+ ParticlesManager.add("effects", "color", { colors, particles, i, final, ...args });
colors.set(final.toArray(), i * 3);
}
}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/position.js b/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/position.js
index b643b60..073b937 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/position.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/position.js
@@ -5,7 +5,7 @@ import { ParticleStrategy } from '../../../../../logic/strategy';
export class PositionUpdate extends ParticleStrategy {
apply({ object, positions, i, ...args }) {
const final = new Vector3();
- ParticleManager.addEffect("position", { positions, object, i, final, ...args });
+ ParticleManager.add("effects", "position", { positions, object, i, final, ...args });
positions.set(final.toArray(), i * 3);
}
}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/handlers/resize.js b/src/frontend/ui/models/Particles/components/atoms/Particles/handlers/resize.js
index eda995f..988cb52 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/handlers/resize.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/handlers/resize.js
@@ -3,7 +3,7 @@
*/
import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
-import { ParticlesModelManager } from '../../../../logic/manager';
+import { ParticlesManager } from '../../../../logic/manager';
export class ResizeHandler extends ModelStrategy {
/**
@@ -12,7 +12,7 @@ export class ResizeHandler extends ModelStrategy {
*/
execute({ event, ...args }) {
const { particles } = args.refs;
- ParticlesModelManager.execute('setupObject', "camera", args);
+ ParticlesManager.execute('setupObject', "camera", args);
const { particle } = args.config;
const ratio = window.innerWidth / window.innerHeight;
const size = Math.min(Math.max(particle.size * ratio, 0), particle.size);
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/logic/update.js b/src/frontend/ui/models/Particles/components/atoms/Particles/logic/update.js
index 4464974..7c011e2 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/logic/update.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/logic/update.js
@@ -1,4 +1,4 @@
-import { ParticlesModelManager } from '../../../../logic/manager';
+import { ParticlesManager } from '../../../../logic/manager';
import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
export class ParticlesUpdate extends ModelStrategy {
@@ -7,8 +7,8 @@ export class ParticlesUpdate extends ModelStrategy {
const idxs = new Set(intersects.map(({ index }) => index));
for (let i = 0; i < args.refs.particles.current.data.count; i++) {
- ParticlesModelManager.execute('updateAttribute', "color", { i, ...args });
- ParticlesModelManager.execute('updateAttribute', "position", { i, idxs, ...args });
+ ParticlesManager.add('effects', "color", { i, ...args });
+ ParticlesManager.add('effects', "position", { i, idxs, ...args });
}
args.refs.particles.current.geometry.attributes.color.needsUpdate = true;
diff --git a/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/index.jsx b/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/index.jsx
index 7b0f9c6..0990e00 100644
--- a/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/index.jsx
+++ b/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/index.jsx
@@ -8,32 +8,32 @@ import { useEffect } from "react";
import { useFrame } from "@react-three/fiber";
import Particles from "../../atoms/Particles/index.jsx";
import {
- setupObjects,
- updateObjects,
+ setup,
+ update,
} from "@semantyk/frontend/ui/models/Particles/logic";
-import { ParticlesModelManager } from "../../../logic/manager.js";
+import { ParticlesManager } from "../../../logic/manager.js";
//* Main
export default function ParticlesSystem(args) {
// Logic
useEffect(() => {
- setupObjects(args);
+ setup(args);
const handleMouseMove = (event) => {
- ParticlesModelManager.execute('handleEvent', 'mouse', event, args);
+ ParticlesManager.handle('mouseMove', { event, ...args });
};
const handleResize = (event) => {
- ParticlesModelManager.execute('handleEvent', 'resize', event, args);
+ ParticlesManager.handle('resize', { event, ...args });
};
- ParticlesModelManager.execute('addEventListeners', { handleMouseMove, handleResize });
- return () => ParticlesModelManager.execute('removeEventListeners', { handleMouseMove, handleResize });
+ ParticlesManager.execute('addAll', 'listener', { handleMouseMove, handleResize });
+ return () => ParticlesManager.execute('removeAll', 'listener', { handleMouseMove, handleResize });
}, [args]);
useFrame(({ clock }) => {
args.objects.clock.current = clock;
- updateObjects(args);
+ update(args);
});
return ;
diff --git a/src/frontend/ui/models/Particles/logic/index.js b/src/frontend/ui/models/Particles/logic/index.js
index ed52cba..905e258 100644
--- a/src/frontend/ui/models/Particles/logic/index.js
+++ b/src/frontend/ui/models/Particles/logic/index.js
@@ -17,7 +17,7 @@
//* Imports
import { Vector3 } from "three";
//* Local Imports
-import { ParticlesModelManager } from "./manager";
+import { ParticlesManager } from "./manager";
//* Main
export function getImageData(args) {
@@ -39,22 +39,21 @@ export function ease(time, duration) {
return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
}
-export function setupObjects(args) {
- ParticlesModelManager.execute('setupObject', "camera", args);
- ParticlesModelManager.execute('setupObject', "plane", args);
- ParticlesModelManager.execute('setupObject', "particles", args);
- ParticlesModelManager.execute('setupObject', "raycaster", args);
+export function setup(args) {
+ ParticlesManager.setup('camera', args);
+ ParticlesManager.setup('particles', args);
+ ParticlesManager.setup('plane', args);
+ ParticlesManager.setup('raycaster', args);
}
-export function updateObjects(args) {
- ParticlesModelManager.execute('updateObject', "particles", args);
+export function update(args) {
+ ParticlesManager.update("particles", args);
}
export function updateOnMouseMove(args) {
const target = new Vector3();
- ParticlesModelManager.execute('updateObject', "camera", args);
- ParticlesModelManager.execute('updateObject', "raycaster", args);
- ParticlesModelManager.execute('updateObject', "mouse", args);
- ParticlesModelManager.execute('updateObject', "circle", { target, ...args });
- ParticlesModelManager.execute('updateObject', "line", { target, ...args });
+ ParticlesManager.update("circle", { target, ...args });
+ ParticlesManager.update("line", { target, ...args });
+ ParticlesManager.update("mouse", args);
+ ParticlesManager.update("raycaster", args);
}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/manager.js b/src/frontend/ui/models/Particles/logic/manager.js
index 0995610..fa44f2b 100644
--- a/src/frontend/ui/models/Particles/logic/manager.js
+++ b/src/frontend/ui/models/Particles/logic/manager.js
@@ -17,11 +17,31 @@ import { ParticlesUpdate } from '../components/atoms/Particles/logic/update';
/**
* Manager class for particle strategies using the Strategy pattern
*/
-export class ParticlesModelManager extends ModelManager {
- static instance = new ParticlesModelManager();
+export class ParticlesManager extends ModelManager {
+ static instance = new ParticlesManager();
- static execute(type, method, ...args) {
- return this.instance[type](method, ...args);
+ static execute(method, item, ...args) {
+ return this.instance[method](item, ...args);
+ }
+
+ static add(collectionName, item, args) {
+ const collection = this.instance[collectionName];
+ return this.instance.execute(collection, item, args);
+ }
+
+ static handle(item, args) {
+ const collection = this.instance.handlers;
+ return this.instance.execute(collection, item, args);
+ }
+
+ static setup(item, args) {
+ const collection = this.instance.setups;
+ return this.instance.execute(collection, item, args);
+ }
+
+ static update(item, args) {
+ const collection = this.instance.updates;
+ return this.instance.execute(collection, item, args);
}
constructor() {
@@ -34,7 +54,7 @@ export class ParticlesModelManager extends ModelManager {
};
this.handlers = {
- mouse: new MouseHandler(),
+ mouseMove: new MouseHandler(),
resize: new ResizeHandler()
};
@@ -45,44 +65,17 @@ export class ParticlesModelManager extends ModelManager {
raycaster: new RaycasterSetup()
};
- this.listeners = {
+ this.listener = {
mouse: new MouseListener(),
resize: new ResizeListener()
};
this.updates = {
- objects: {
- circle: new CircleUpdate(),
- line: new LineUpdate(),
- mouse: new MouseUpdate(),
- particles: new ParticlesUpdate(),
- raycaster: new RaycasterUpdate(),
- },
- attributes: {
- color: this.effects.color,
- position: this.effects.position
- }
+ circle: new CircleUpdate(),
+ line: new LineUpdate(),
+ mouse: new MouseUpdate(),
+ particles: new ParticlesUpdate(),
+ raycaster: new RaycasterUpdate(),
};
}
-
- // Instance methods
- addEffect(type, args) {
- return this.execute(this.effects, type, args);
- }
-
- handleEvent(type, event, args) {
- return this.execute(this.handlers, type, { event, ...args });
- }
-
- setupObject(type, args) {
- return this.execute(this.setups, type, args);
- }
-
- updateObject(type, args) {
- return this.execute(this.updates.objects, type, args);
- }
-
- updateAttribute(type, args) {
- return this.execute(this.updates.attributes, type, args);
- }
}
\ No newline at end of file
From 0f5d40c83328aca6b484b91742298684df6c4f92 Mon Sep 17 00:00:00 2001
From: "Daniel B."
Date: Fri, 14 Mar 2025 00:21:08 -0600
Subject: [PATCH 4/7] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20Refactor:=20Update=20P?=
=?UTF-8?q?articles=20model?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Simplify model atomically
---
.../molecules/Model/logic/manager.js | 28 ++----
.../components/atoms/Mouse/updates/color.js | 2 +-
.../atoms/Particles/handlers/resize.js | 2 +-
.../atoms/Particles/logic/update.js | 4 +-
.../molecules/ParticlesSystem/index.jsx | 4 +-
.../ui/models/Particles/logic/index.js | 2 +-
.../ui/models/Particles/logic/manager.js | 94 +++++++++----------
7 files changed, 63 insertions(+), 73 deletions(-)
diff --git a/src/frontend/ui/components/molecules/Model/logic/manager.js b/src/frontend/ui/components/molecules/Model/logic/manager.js
index 55de217..07dcdb0 100644
--- a/src/frontend/ui/components/molecules/Model/logic/manager.js
+++ b/src/frontend/ui/components/molecules/Model/logic/manager.js
@@ -8,28 +8,20 @@ export class ModelManager {
}
}
- // Generic method to handle operations on collections
- execute(collection, key, args) {
- const item = collection[key];
- if (item) {
- return item.execute(args);
- }
+ static call(object, member, ...args) {
+ if (!object) return;
+ else object[member](...args);
}
- // TODO: Add a method for `add` and `remove`
-
- // Event listener methods
- addAll(collectionName, args) {
- const collection = this[collectionName];
- Object.values(collection).forEach(item => {
- item.add(args);
- });
+ static execute(collection, item, member, ...args) {
+ const object = collection[item];
+ if (!object) return;
+ else this.call(object, member, ...args);
}
- removeAll(collectionName, args) {
- const collection = this[collectionName];
- Object.values(collection).forEach(item => {
- item.remove(args);
+ static executeAll(collection, member, ...args) {
+ Object.values(collection).forEach(object => {
+ this.call(object, member, ...args);
});
}
}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/color.js b/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/color.js
index 5528fc4..f343d91 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/color.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Mouse/updates/color.js
@@ -5,7 +5,7 @@ import { ParticlesManager } from '../../../../logic/manager';
export class ColorUpdate extends ParticleStrategy {
apply({ i, colors, particles, ...args }) {
const final = new Color();
- ParticlesManager.add("effects", "color", { colors, particles, i, final, ...args });
+ ParticlesManager.affect("color", { colors, particles, i, final, ...args });
colors.set(final.toArray(), i * 3);
}
}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/handlers/resize.js b/src/frontend/ui/models/Particles/components/atoms/Particles/handlers/resize.js
index 988cb52..d1b750f 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/handlers/resize.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/handlers/resize.js
@@ -12,7 +12,7 @@ export class ResizeHandler extends ModelStrategy {
*/
execute({ event, ...args }) {
const { particles } = args.refs;
- ParticlesManager.execute('setupObject', "camera", args);
+ ParticlesManager.setup('camera', args);
const { particle } = args.config;
const ratio = window.innerWidth / window.innerHeight;
const size = Math.min(Math.max(particle.size * ratio, 0), particle.size);
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/logic/update.js b/src/frontend/ui/models/Particles/components/atoms/Particles/logic/update.js
index 7c011e2..d33249f 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/logic/update.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/logic/update.js
@@ -7,8 +7,8 @@ export class ParticlesUpdate extends ModelStrategy {
const idxs = new Set(intersects.map(({ index }) => index));
for (let i = 0; i < args.refs.particles.current.data.count; i++) {
- ParticlesManager.add('effects', "color", { i, ...args });
- ParticlesManager.add('effects', "position", { i, idxs, ...args });
+ ParticlesManager.affect('color', { i, ...args });
+ ParticlesManager.affect('position', { i, idxs, ...args });
}
args.refs.particles.current.geometry.attributes.color.needsUpdate = true;
diff --git a/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/index.jsx b/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/index.jsx
index 0990e00..2a23113 100644
--- a/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/index.jsx
+++ b/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/index.jsx
@@ -27,8 +27,8 @@ export default function ParticlesSystem(args) {
ParticlesManager.handle('resize', { event, ...args });
};
- ParticlesManager.execute('addAll', 'listener', { handleMouseMove, handleResize });
- return () => ParticlesManager.execute('removeAll', 'listener', { handleMouseMove, handleResize });
+ ParticlesManager.executeAll('add', { handleMouseMove, handleResize });
+ return () => ParticlesManager.executeAll('remove', { handleMouseMove, handleResize });
}, [args]);
useFrame(({ clock }) => {
diff --git a/src/frontend/ui/models/Particles/logic/index.js b/src/frontend/ui/models/Particles/logic/index.js
index 905e258..a7ce015 100644
--- a/src/frontend/ui/models/Particles/logic/index.js
+++ b/src/frontend/ui/models/Particles/logic/index.js
@@ -51,7 +51,7 @@ export function update(args) {
}
export function updateOnMouseMove(args) {
- const target = new Vector3();
+ const target = new Vector3()
ParticlesManager.update("circle", { target, ...args });
ParticlesManager.update("line", { target, ...args });
ParticlesManager.update("mouse", args);
diff --git a/src/frontend/ui/models/Particles/logic/manager.js b/src/frontend/ui/models/Particles/logic/manager.js
index fa44f2b..f2bccf9 100644
--- a/src/frontend/ui/models/Particles/logic/manager.js
+++ b/src/frontend/ui/models/Particles/logic/manager.js
@@ -20,62 +20,60 @@ import { ParticlesUpdate } from '../components/atoms/Particles/logic/update';
export class ParticlesManager extends ModelManager {
static instance = new ParticlesManager();
- static execute(method, item, ...args) {
- return this.instance[method](item, ...args);
- }
+ static effects = {
+ chaos: new ChaosEffect(),
+ color: new ColorEffect(),
+ entropy: new EntropyEffect(),
+ position: new PositionEffect()
+ };
- static add(collectionName, item, args) {
- const collection = this.instance[collectionName];
- return this.instance.execute(collection, item, args);
- }
+ static handlers = {
+ mouseMove: new MouseHandler(),
+ resize: new ResizeHandler()
+ };
- static handle(item, args) {
- const collection = this.instance.handlers;
- return this.instance.execute(collection, item, args);
- }
+ static setups = {
+ camera: new CameraSetup(),
+ particles: new ParticlesSetup(),
+ plane: new PlaneSetup(),
+ raycaster: new RaycasterSetup()
+ };
- static setup(item, args) {
- const collection = this.instance.setups;
- return this.instance.execute(collection, item, args);
- }
+ static listeners = {
+ mouse: new MouseListener(),
+ resize: new ResizeListener()
+ };
- static update(item, args) {
- const collection = this.instance.updates;
- return this.instance.execute(collection, item, args);
- }
+ static updates = {
+ circle: new CircleUpdate(),
+ line: new LineUpdate(),
+ mouse: new MouseUpdate(),
+ particles: new ParticlesUpdate(),
+ raycaster: new RaycasterUpdate(),
+ };
- constructor() {
- super();
- this.effects = {
- chaos: new ChaosEffect(),
- color: new ColorEffect(),
- entropy: new EntropyEffect(),
- position: new PositionEffect()
- };
+ static affect(item, ...args) {
+ const collection = this.effects;
+ return super.execute(collection, item, 'execute', ...args);
+ }
- this.handlers = {
- mouseMove: new MouseHandler(),
- resize: new ResizeHandler()
- };
+ static handle(item, ...args) {
+ const collection = this.handlers;
+ return super.execute(collection, item, 'execute', ...args);
+ }
- this.setups = {
- camera: new CameraSetup(),
- particles: new ParticlesSetup(),
- plane: new PlaneSetup(),
- raycaster: new RaycasterSetup()
- };
+ static setup(item, ...args) {
+ const collection = this.setups;
+ return super.execute(collection, item, 'execute', ...args);
+ }
- this.listener = {
- mouse: new MouseListener(),
- resize: new ResizeListener()
- };
+ static update(item, ...args) {
+ const collection = this.updates;
+ return super.execute(collection, item, 'execute', ...args);
+ }
- this.updates = {
- circle: new CircleUpdate(),
- line: new LineUpdate(),
- mouse: new MouseUpdate(),
- particles: new ParticlesUpdate(),
- raycaster: new RaycasterUpdate(),
- };
+ static executeAll(member, ...args) {
+ const collection = this.listeners;
+ return super.executeAll(collection, member, ...args);
}
}
\ No newline at end of file
From a2d481550f9398afeaa70b9d034b6f17a12c78c3 Mon Sep 17 00:00:00 2001
From: "Daniel B."
Date: Fri, 14 Mar 2025 21:47:19 -0600
Subject: [PATCH 5/7] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20Refactor:=20Perform=20?=
=?UTF-8?q?major=20refactor=20on=20Particles=20model?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Implement atomic components architecture
---
.../atoms/Box/{index.jsx => Box.jsx} | 4 +-
.../Particles/components/atoms/Box/index.js | 2 +
.../atoms/Camera/{index.jsx => Camera.jsx} | 13 ++--
.../{logic/setup.js => Camera.logic.js} | 12 +---
.../components/atoms/Camera/index.js | 2 +
.../atoms/Circle/{index.jsx => Circle.jsx} | 13 ++--
.../{logic/update.js => Circle.logic.js} | 4 +-
.../components/atoms/Circle/index.js | 2 +
.../Particles/components/atoms/Mouse/Mouse.js | 7 ++
.../components/atoms/Mouse/Mouse.logic.js | 42 ++++++++++++
.../Particles/components/atoms/Mouse/index.js | 5 +-
.../components/atoms/Mouse/logic/handler.js | 34 ----------
.../components/atoms/Mouse/logic/listener.js | 13 ----
.../components/atoms/Mouse/logic/update.js | 10 ---
.../Particles/{index.jsx => Particles.jsx} | 7 +-
.../{logic/setup.js => Particles.logic.js} | 40 +++++++----
.../atoms/Particles/effects/interpolation.js | 2 +-
.../atoms/Particles/handlers/index.js | 1 -
.../atoms/Particles/handlers/resize.js | 21 ------
.../components/atoms/Particles/index.js | 4 +-
.../components/atoms/Particles/logic/index.js | 2 -
.../atoms/Particles/logic/update.js | 17 -----
.../atoms/Plane/{index.jsx => Plane.jsx} | 12 ++--
.../components/atoms/Plane/Plane.logic.js | 9 +++
.../Particles/components/atoms/Plane/index.js | 2 +
.../components/atoms/Plane/logic/setup.js | 17 -----
.../atoms/RayLine/{index.jsx => RayLine.jsx} | 12 ++--
.../{logic/update.js => RayLine.logic.js} | 6 +-
.../components/atoms/RayLine/index.js | 2 +
.../components/atoms/Raycaster/Raycaster.js | 12 ++++
.../{logic/update.js => Raycaster.logic.js} | 11 ++-
.../components/atoms/Raycaster/index.js | 4 +-
.../components/atoms/Raycaster/index.jsx | 8 ---
.../components/atoms/Raycaster/logic/setup.js | 16 -----
.../Particles/components/atoms/index.js | 5 +-
.../Controls/{index.jsx => Controls.jsx} | 8 +--
.../components/molecules/Controls/index.js | 2 +
.../{index.jsx => ParticlesSystem.jsx} | 14 ++--
.../ParticlesSystem/ParticlesSystem.logic.js | 23 +++++++
.../molecules/ParticlesSystem/index.js | 2 +
.../Particles/components/molecules/index.js | 2 +
.../ui/models/Particles/config/index.js | 2 +-
src/frontend/ui/models/Particles/index.jsx | 4 +-
.../ui/models/Particles/logic/index.js | 21 +-----
.../Particles/logic/listeners/resize.js | 11 ---
.../ui/models/Particles/logic/manager.js | 67 ++++++++-----------
.../ui/models/Particles/utils/ease.js | 4 ++
.../ui/models/Particles/utils/image.js | 17 +++++
48 files changed, 259 insertions(+), 291 deletions(-)
rename src/frontend/ui/models/Particles/components/atoms/Box/{index.jsx => Box.jsx} (88%)
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Box/index.js
rename src/frontend/ui/models/Particles/components/atoms/Camera/{index.jsx => Camera.jsx} (78%)
rename src/frontend/ui/models/Particles/components/atoms/Camera/{logic/setup.js => Camera.logic.js} (65%)
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Camera/index.js
rename src/frontend/ui/models/Particles/components/atoms/Circle/{index.jsx => Circle.jsx} (81%)
rename src/frontend/ui/models/Particles/components/atoms/Circle/{logic/update.js => Circle.logic.js} (70%)
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Circle/index.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Mouse/Mouse.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Mouse/Mouse.logic.js
delete mode 100644 src/frontend/ui/models/Particles/components/atoms/Mouse/logic/handler.js
delete mode 100644 src/frontend/ui/models/Particles/components/atoms/Mouse/logic/listener.js
delete mode 100644 src/frontend/ui/models/Particles/components/atoms/Mouse/logic/update.js
rename src/frontend/ui/models/Particles/components/atoms/Particles/{index.jsx => Particles.jsx} (79%)
rename src/frontend/ui/models/Particles/components/atoms/Particles/{logic/setup.js => Particles.logic.js} (65%)
delete mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/handlers/index.js
delete mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/handlers/resize.js
delete mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/logic/index.js
delete mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/logic/update.js
rename src/frontend/ui/models/Particles/components/atoms/Plane/{index.jsx => Plane.jsx} (78%)
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Plane/Plane.logic.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Plane/index.js
delete mode 100644 src/frontend/ui/models/Particles/components/atoms/Plane/logic/setup.js
rename src/frontend/ui/models/Particles/components/atoms/RayLine/{index.jsx => RayLine.jsx} (71%)
rename src/frontend/ui/models/Particles/components/atoms/RayLine/{logic/update.js => RayLine.logic.js} (72%)
create mode 100644 src/frontend/ui/models/Particles/components/atoms/RayLine/index.js
create mode 100644 src/frontend/ui/models/Particles/components/atoms/Raycaster/Raycaster.js
rename src/frontend/ui/models/Particles/components/atoms/Raycaster/{logic/update.js => Raycaster.logic.js} (51%)
delete mode 100644 src/frontend/ui/models/Particles/components/atoms/Raycaster/index.jsx
delete mode 100644 src/frontend/ui/models/Particles/components/atoms/Raycaster/logic/setup.js
rename src/frontend/ui/models/Particles/components/molecules/Controls/{index.jsx => Controls.jsx} (69%)
create mode 100644 src/frontend/ui/models/Particles/components/molecules/Controls/index.js
rename src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/{index.jsx => ParticlesSystem.jsx} (70%)
create mode 100644 src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/ParticlesSystem.logic.js
create mode 100644 src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/index.js
create mode 100644 src/frontend/ui/models/Particles/components/molecules/index.js
delete mode 100644 src/frontend/ui/models/Particles/logic/listeners/resize.js
create mode 100644 src/frontend/ui/models/Particles/utils/ease.js
create mode 100644 src/frontend/ui/models/Particles/utils/image.js
diff --git a/src/frontend/ui/models/Particles/components/atoms/Box/index.jsx b/src/frontend/ui/models/Particles/components/atoms/Box/Box.jsx
similarity index 88%
rename from src/frontend/ui/models/Particles/components/atoms/Box/index.jsx
rename to src/frontend/ui/models/Particles/components/atoms/Box/Box.jsx
index a29a3bd..162fb2c 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Box/index.jsx
+++ b/src/frontend/ui/models/Particles/components/atoms/Box/Box.jsx
@@ -6,9 +6,7 @@
//* Main
export default function Box({ config, data, refs }) {
// Props
- const {
- general: { showHelpers }
- } = config;
+ const { general: { showHelpers } } = config;
// Return
return (
diff --git a/src/frontend/ui/models/Particles/components/atoms/Box/index.js b/src/frontend/ui/models/Particles/components/atoms/Box/index.js
new file mode 100644
index 0000000..6f296f0
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Box/index.js
@@ -0,0 +1,2 @@
+export { default } from './Box';
+export { default as Box } from './Box';
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Camera/index.jsx b/src/frontend/ui/models/Particles/components/atoms/Camera/Camera.jsx
similarity index 78%
rename from src/frontend/ui/models/Particles/components/atoms/Camera/index.jsx
rename to src/frontend/ui/models/Particles/components/atoms/Camera/Camera.jsx
index 2e5c7f0..a9f1681 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Camera/index.jsx
+++ b/src/frontend/ui/models/Particles/components/atoms/Camera/Camera.jsx
@@ -6,11 +6,8 @@
import { PerspectiveCamera } from "@react-three/drei";
import { CameraHelper } from "three";
import { useHelper } from "@react-three/drei";
-import { CameraSetup } from './logic/setup';
-
-export { CameraSetup };
-
-export default function Camera({ config, refs }) {
+import CameraLogic from "./Camera.logic";
+function Camera({ config, refs }) {
// Props
const {
general: { showHelpers }
@@ -24,4 +21,8 @@ export default function Camera({ config, refs }) {
{...config.camera}
/>
);
-}
\ No newline at end of file
+}
+
+Camera.logic = new CameraLogic();
+
+export default Camera;
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Camera/logic/setup.js b/src/frontend/ui/models/Particles/components/atoms/Camera/Camera.logic.js
similarity index 65%
rename from src/frontend/ui/models/Particles/components/atoms/Camera/logic/setup.js
rename to src/frontend/ui/models/Particles/components/atoms/Camera/Camera.logic.js
index 1d0726f..79811c0 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Camera/logic/setup.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Camera/Camera.logic.js
@@ -1,15 +1,7 @@
-/**
- * Camera setup strategy for particle system
- */
-
import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
-export class CameraSetup extends ModelStrategy {
- /**
- * Execute camera setup
- * @param {Object} args - Arguments containing config, data, and refs
- */
- execute({ config, data: { unit }, refs: { camera } }) {
+export default class CameraLogic extends ModelStrategy {
+ setup({ config, data: { unit }, refs: { camera } }) {
const { camera: { margin } } = config;
const aspectRatio = window.innerWidth / window.innerHeight;
diff --git a/src/frontend/ui/models/Particles/components/atoms/Camera/index.js b/src/frontend/ui/models/Particles/components/atoms/Camera/index.js
new file mode 100644
index 0000000..7247c9a
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Camera/index.js
@@ -0,0 +1,2 @@
+export { default } from './Camera';
+export { default as Camera } from './Camera';
diff --git a/src/frontend/ui/models/Particles/components/atoms/Circle/index.jsx b/src/frontend/ui/models/Particles/components/atoms/Circle/Circle.jsx
similarity index 81%
rename from src/frontend/ui/models/Particles/components/atoms/Circle/index.jsx
rename to src/frontend/ui/models/Particles/components/atoms/Circle/Circle.jsx
index 646bfa7..96d0f66 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Circle/index.jsx
+++ b/src/frontend/ui/models/Particles/components/atoms/Circle/Circle.jsx
@@ -4,12 +4,9 @@
*/
//* Imports
-import { CircleUpdate } from './logic/update';
-
-export { CircleUpdate };
-
+import CircleLogic from "./Circle.logic";
//* Main
-export default function Circle({ config, data, refs }) {
+function Circle({ config, data, refs }) {
// Props
const {
general: { showHelpers },
@@ -31,4 +28,8 @@ export default function Circle({ config, data, refs }) {
/>
);
-}
\ No newline at end of file
+}
+
+Circle.logic = new CircleLogic();
+
+export default Circle;
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Circle/logic/update.js b/src/frontend/ui/models/Particles/components/atoms/Circle/Circle.logic.js
similarity index 70%
rename from src/frontend/ui/models/Particles/components/atoms/Circle/logic/update.js
rename to src/frontend/ui/models/Particles/components/atoms/Circle/Circle.logic.js
index 7845f40..c12521e 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Circle/logic/update.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Circle/Circle.logic.js
@@ -1,7 +1,7 @@
import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
-export class CircleUpdate extends ModelStrategy {
- execute({ objects, refs, target }) {
+export default class CircleLogic extends ModelStrategy {
+ update({ objects, refs, target }) {
objects.raycaster.ray.intersectPlane(refs.plane.current, target);
refs.circle.current.position.copy(target);
}
diff --git a/src/frontend/ui/models/Particles/components/atoms/Circle/index.js b/src/frontend/ui/models/Particles/components/atoms/Circle/index.js
new file mode 100644
index 0000000..fefad1e
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Circle/index.js
@@ -0,0 +1,2 @@
+export { default } from './Circle';
+export { default as Circle } from './Circle';
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Mouse/Mouse.js b/src/frontend/ui/models/Particles/components/atoms/Mouse/Mouse.js
new file mode 100644
index 0000000..7915baa
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Mouse/Mouse.js
@@ -0,0 +1,7 @@
+import MouseLogic from './Mouse.logic';
+
+const Mouse = {
+ logic: new MouseLogic()
+};
+
+export default Mouse;
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Mouse/Mouse.logic.js b/src/frontend/ui/models/Particles/components/atoms/Mouse/Mouse.logic.js
new file mode 100644
index 0000000..f9722c5
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Mouse/Mouse.logic.js
@@ -0,0 +1,42 @@
+import { onMouseMove } from "@semantyk/frontend/logic/services/callbacks";
+import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
+import { updateOnMouseMove } from "../../../logic";
+
+export default class MouseLogic extends ModelStrategy {
+ add({ handleMouseMove }) {
+ window.addEventListener("mousemove", handleMouseMove);
+ window.addEventListener("touchmove", handleMouseMove);
+ }
+
+ remove({ handleMouseMove }) {
+ window.removeEventListener("mousemove", handleMouseMove);
+ window.removeEventListener("touchmove", handleMouseMove);
+ }
+
+ handle({ event, ...args }) {
+ const { mouse, moveMouseTimeout } = args.refs;
+ clearTimeout(moveMouseTimeout.current);
+ mouse.current.isMoving = true;
+ moveMouseTimeout.current = setTimeout(() => mouse.current.isMoving = false, 1);
+
+ let clientX, clientY;
+ if (event.type === "mousemove") {
+ clientX = event.clientX;
+ clientY = event.clientY;
+ } else if (event.type === "touchmove") {
+ clientX = event.touches[0].clientX;
+ clientY = event.touches[0].clientY;
+ }
+
+ updateOnMouseMove({
+ events: { mousemove: { clientX, clientY } },
+ ...args
+ });
+ }
+
+ update({ refs, events }) {
+ const { x, y } = onMouseMove(events.mousemove);
+ refs.mouse.current.x = x * 2 - 1;
+ refs.mouse.current.y = -y * 2 + 1;
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Mouse/index.js b/src/frontend/ui/models/Particles/components/atoms/Mouse/index.js
index d1ba805..a2301c1 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Mouse/index.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Mouse/index.js
@@ -1,3 +1,2 @@
-export { MouseHandler } from './logic/handler';
-export { MouseListener } from './logic/listener';
-export { MouseUpdate } from './logic/update';
\ No newline at end of file
+export { default } from './Mouse';
+export { default as Mouse } from './Mouse';
diff --git a/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/handler.js b/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/handler.js
deleted file mode 100644
index 3ef64a9..0000000
--- a/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/handler.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * Mouse handler strategy for particle system
- */
-
-import { Vector2 } from 'three';
-import { ModelStrategy } from '@semantyk/frontend/ui/components/molecules/Model/logic/strategy';
-import { updateOnMouseMove } from '../../../../logic/index';
-
-export class MouseHandler extends ModelStrategy {
- /**
- * Execute mouse/touch move events
- * @param {Object} args - Arguments containing event and particle system data
- */
- execute({ event, ...args }) {
- const { mouse, moveMouseTimeout } = args.refs;
- clearTimeout(moveMouseTimeout.current);
- mouse.current.isMoving = true;
- moveMouseTimeout.current = setTimeout(() => mouse.current.isMoving = false, 1);
-
- let clientX, clientY;
- if (event.type === "mousemove") {
- clientX = event.clientX;
- clientY = event.clientY;
- } else if (event.type === "touchmove") {
- clientX = event.touches[0].clientX;
- clientY = event.touches[0].clientY;
- }
-
- updateOnMouseMove({
- events: { mousemove: { clientX, clientY } },
- ...args
- });
- }
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/listener.js b/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/listener.js
deleted file mode 100644
index d9f1bfe..0000000
--- a/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/listener.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
-
-export class MouseListener extends ModelStrategy {
- add({ handleMouseMove }) {
- window.addEventListener("mousemove", handleMouseMove);
- window.addEventListener("touchmove", handleMouseMove);
- }
-
- remove({ handleMouseMove }) {
- window.removeEventListener("mousemove", handleMouseMove);
- window.removeEventListener("touchmove", handleMouseMove);
- }
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/update.js b/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/update.js
deleted file mode 100644
index b81889e..0000000
--- a/src/frontend/ui/models/Particles/components/atoms/Mouse/logic/update.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import { onMouseMove } from "@semantyk/frontend/logic/services/callbacks";
-import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
-
-export class MouseUpdate extends ModelStrategy {
- execute({ refs, events }) {
- const { x, y } = onMouseMove(events.mousemove);
- refs.mouse.current.x = x * 2 - 1;
- refs.mouse.current.y = -y * 2 + 1;
- }
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/index.jsx b/src/frontend/ui/models/Particles/components/atoms/Particles/Particles.jsx
similarity index 79%
rename from src/frontend/ui/models/Particles/components/atoms/Particles/index.jsx
rename to src/frontend/ui/models/Particles/components/atoms/Particles/Particles.jsx
index 8a5fa42..b2406fa 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/index.jsx
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/Particles.jsx
@@ -3,7 +3,8 @@
* Atom component for the particles in the Particles model
*/
-export default function Particles({ config, refs }) {
+//* Main
+function Particles({ config, refs }) {
return (
@@ -13,4 +14,6 @@ export default function Particles({ config, refs }) {
/>
);
-}
\ No newline at end of file
+}
+
+export default Particles;
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/logic/setup.js b/src/frontend/ui/models/Particles/components/atoms/Particles/Particles.logic.js
similarity index 65%
rename from src/frontend/ui/models/Particles/components/atoms/Particles/logic/setup.js
rename to src/frontend/ui/models/Particles/components/atoms/Particles/Particles.logic.js
index afbe6e3..a4a6f8e 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/logic/setup.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/Particles.logic.js
@@ -1,18 +1,19 @@
-/**
- * Particles setup strategy for particle system
- */
-
-import { Float32BufferAttribute } from 'three';
-
import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
-import { getImageData } from '../../../../logic';
+import { getImageData } from "../../../utils/image";
+import { Float32BufferAttribute } from "three";
+import { ParticlesManager } from "../../../logic/manager";
+
+export default class ParticlesLogic extends ModelStrategy {
+ handle({ event, ...args }) {
+ const { particles } = args.refs;
+ ParticlesManager.setup('camera', args);
+ const { particle } = args.config;
+ const ratio = window.innerWidth / window.innerHeight;
+ const size = Math.min(Math.max(particle.size * ratio, 0), particle.size);
+ particles.current.material.size = size;
+ }
-export class ParticlesSetup extends ModelStrategy {
- /**
- * Execute particles setup
- * @param {Object} args - Arguments containing config, data, objects, and refs
- */
- execute({ config, data: { color, unit }, objects: { image }, refs }) {
+ setup({ config, data: { color, unit }, objects: { image }, refs }) {
const { particle } = config;
const particles = refs.particles.current;
const { data } = getImageData({ data: { unit }, objects: { image } });
@@ -67,4 +68,17 @@ export class ParticlesSetup extends ModelStrategy {
const size = Math.min(Math.max(particle.size * ratio, 0), particle.size);
particles.material.size = size;
}
+
+ update(args) {
+ const intersects = args.objects.raycaster.intersectObject(args.refs.particles.current);
+ const idxs = new Set(intersects.map(({ index }) => index));
+
+ for (let i = 0; i < args.refs.particles.current.data.count; i++) {
+ ParticlesManager.affect('color', { i, ...args });
+ ParticlesManager.affect('position', { i, idxs, ...args });
+ }
+
+ args.refs.particles.current.geometry.attributes.color.needsUpdate = true;
+ args.refs.particles.current.geometry.attributes.position.needsUpdate = true;
+ }
}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/interpolation.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/interpolation.js
index 882a536..47b59e0 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/interpolation.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/interpolation.js
@@ -1,5 +1,5 @@
import { Vector3 } from 'three';
-import { ease } from "@semantyk/frontend/ui/models/Particles/logic";
+import { ease } from "@semantyk/frontend/ui/models/Particles/utils/ease";
import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
export class InterpolationEffect extends ModelStrategy {
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/handlers/index.js b/src/frontend/ui/models/Particles/components/atoms/Particles/handlers/index.js
deleted file mode 100644
index c514824..0000000
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/handlers/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export { ResizeHandler } from './resize';
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/handlers/resize.js b/src/frontend/ui/models/Particles/components/atoms/Particles/handlers/resize.js
deleted file mode 100644
index d1b750f..0000000
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/handlers/resize.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * Resize handler strategy for particle system
- */
-
-import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
-import { ParticlesManager } from '../../../../logic/manager';
-
-export class ResizeHandler extends ModelStrategy {
- /**
- * Execute window resize events
- * @param {Object} args - Arguments containing event and particle system data
- */
- execute({ event, ...args }) {
- const { particles } = args.refs;
- ParticlesManager.setup('camera', args);
- const { particle } = args.config;
- const ratio = window.innerWidth / window.innerHeight;
- const size = Math.min(Math.max(particle.size * ratio, 0), particle.size);
- particles.current.material.size = size;
- }
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/index.js b/src/frontend/ui/models/Particles/components/atoms/Particles/index.js
index eae883e..0cb9b8f 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/index.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/index.js
@@ -1,3 +1,3 @@
export * from './effects';
-export * from './handlers';
-export * from './logic';
\ No newline at end of file
+export { default } from './Particles'
+export { default as Particles } from './Particles';
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/logic/index.js b/src/frontend/ui/models/Particles/components/atoms/Particles/logic/index.js
deleted file mode 100644
index b9ee04a5..0000000
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/logic/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-export { ParticlesSetup } from './setup';
-export { ParticlesUpdate } from './update';
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/logic/update.js b/src/frontend/ui/models/Particles/components/atoms/Particles/logic/update.js
deleted file mode 100644
index d33249f..0000000
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/logic/update.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import { ParticlesManager } from '../../../../logic/manager';
-import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
-
-export class ParticlesUpdate extends ModelStrategy {
- execute(args) {
- const intersects = args.objects.raycaster.intersectObject(args.refs.particles.current);
- const idxs = new Set(intersects.map(({ index }) => index));
-
- for (let i = 0; i < args.refs.particles.current.data.count; i++) {
- ParticlesManager.affect('color', { i, ...args });
- ParticlesManager.affect('position', { i, idxs, ...args });
- }
-
- args.refs.particles.current.geometry.attributes.color.needsUpdate = true;
- args.refs.particles.current.geometry.attributes.position.needsUpdate = true;
- }
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Plane/index.jsx b/src/frontend/ui/models/Particles/components/atoms/Plane/Plane.jsx
similarity index 78%
rename from src/frontend/ui/models/Particles/components/atoms/Plane/index.jsx
rename to src/frontend/ui/models/Particles/components/atoms/Plane/Plane.jsx
index a5b358c..d212590 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Plane/index.jsx
+++ b/src/frontend/ui/models/Particles/components/atoms/Plane/Plane.jsx
@@ -1,10 +1,8 @@
//* Imports
-import { PlaneSetup } from './logic/setup';
-
-export { PlaneSetup };
+import PlaneLogic from "./Plane.logic";
//* Main
-export default function Plane({ config, data, refs }) {
+function Plane({ config, data, refs }) {
// Props
const {
general: { showHelpers }
@@ -25,4 +23,8 @@ export default function Plane({ config, data, refs }) {
/>
);
-}
\ No newline at end of file
+}
+
+Plane.logic = new PlaneLogic();
+
+export default Plane;
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Plane/Plane.logic.js b/src/frontend/ui/models/Particles/components/atoms/Plane/Plane.logic.js
new file mode 100644
index 0000000..3737ef0
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Plane/Plane.logic.js
@@ -0,0 +1,9 @@
+import { Plane, Vector3 } from "three";
+import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
+
+export default class PlaneLogic extends ModelStrategy {
+ setup({ data: { unit }, refs: { plane } }) {
+ const normal = new Vector3(0, 0, 1);
+ plane.current = new Plane(normal, unit / 2);
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Plane/index.js b/src/frontend/ui/models/Particles/components/atoms/Plane/index.js
new file mode 100644
index 0000000..c83936e
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Plane/index.js
@@ -0,0 +1,2 @@
+export { default } from './Plane';
+export { default as Plane } from './Plane';
diff --git a/src/frontend/ui/models/Particles/components/atoms/Plane/logic/setup.js b/src/frontend/ui/models/Particles/components/atoms/Plane/logic/setup.js
deleted file mode 100644
index d57c525..0000000
--- a/src/frontend/ui/models/Particles/components/atoms/Plane/logic/setup.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
- * Plane setup strategy for particle system
- */
-
-import { Plane, Vector3 } from 'three';
-import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
-
-export class PlaneSetup extends ModelStrategy {
- /**
- * Execute plane setup
- * @param {Object} args - Arguments containing data and refs
- */
- execute({ data: { unit }, refs: { plane } }) {
- const normal = new Vector3(0, 0, 1);
- plane.current = new Plane(normal, unit / 2);
- }
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/RayLine/index.jsx b/src/frontend/ui/models/Particles/components/atoms/RayLine/RayLine.jsx
similarity index 71%
rename from src/frontend/ui/models/Particles/components/atoms/RayLine/index.jsx
rename to src/frontend/ui/models/Particles/components/atoms/RayLine/RayLine.jsx
index 361a4bf..edd1a6a 100644
--- a/src/frontend/ui/models/Particles/components/atoms/RayLine/index.jsx
+++ b/src/frontend/ui/models/Particles/components/atoms/RayLine/RayLine.jsx
@@ -4,12 +4,10 @@
*/
//* Imports
-import { LineUpdate } from './logic/update';
-
-export { LineUpdate };
+import RayLineLogic from './RayLine.logic';
//* Main
-export default function RayLine({ config, refs }) {
+function RayLine({ config, refs }) {
// Props
const {
general: { showHelpers }
@@ -21,4 +19,8 @@ export default function RayLine({ config, refs }) {
);
-}
\ No newline at end of file
+}
+
+RayLine.logic = new RayLineLogic();
+
+export default RayLine;
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/RayLine/logic/update.js b/src/frontend/ui/models/Particles/components/atoms/RayLine/RayLine.logic.js
similarity index 72%
rename from src/frontend/ui/models/Particles/components/atoms/RayLine/logic/update.js
rename to src/frontend/ui/models/Particles/components/atoms/RayLine/RayLine.logic.js
index a6dbc36..989854e 100644
--- a/src/frontend/ui/models/Particles/components/atoms/RayLine/logic/update.js
+++ b/src/frontend/ui/models/Particles/components/atoms/RayLine/RayLine.logic.js
@@ -1,8 +1,8 @@
-import { BufferGeometry } from 'three';
import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
+import { BufferGeometry } from "three";
-export class LineUpdate extends ModelStrategy {
- execute({ objects, refs, target }) {
+export default class RayLineLogic extends ModelStrategy {
+ update({ objects, refs, target }) {
const { origin } = objects.raycaster.ray;
const points = [origin, target];
const geometry = new BufferGeometry().setFromPoints(points);
diff --git a/src/frontend/ui/models/Particles/components/atoms/RayLine/index.js b/src/frontend/ui/models/Particles/components/atoms/RayLine/index.js
new file mode 100644
index 0000000..d13cae3
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/RayLine/index.js
@@ -0,0 +1,2 @@
+export { default } from './RayLine'
+export { default as RayLine } from './RayLine';
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Raycaster/Raycaster.js b/src/frontend/ui/models/Particles/components/atoms/Raycaster/Raycaster.js
new file mode 100644
index 0000000..ebac016
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/atoms/Raycaster/Raycaster.js
@@ -0,0 +1,12 @@
+/**
+ * Raycaster.jsx
+ * Atom component for the raycaster in the Particles model
+ */
+
+import RaycasterLogic from "./Raycaster.logic";
+
+const Raycaster = {
+ logic: new RaycasterLogic()
+};
+
+export default Raycaster;
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Raycaster/logic/update.js b/src/frontend/ui/models/Particles/components/atoms/Raycaster/Raycaster.logic.js
similarity index 51%
rename from src/frontend/ui/models/Particles/components/atoms/Raycaster/logic/update.js
rename to src/frontend/ui/models/Particles/components/atoms/Raycaster/Raycaster.logic.js
index 237c8a6..ffdad7e 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Raycaster/logic/update.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Raycaster/Raycaster.logic.js
@@ -1,8 +1,13 @@
-import { Vector2 } from 'three';
import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
+import { Vector2 } from "three";
-export class RaycasterUpdate extends ModelStrategy {
- execute({ objects, refs }) {
+export default class RaycasterLogic extends ModelStrategy {
+ setup({ config, data: { unit }, objects: { raycaster } }) {
+ const { animations: { chaos: { radius } } } = config;
+ raycaster.params.Points.threshold = radius * unit;
+ }
+
+ update({ objects, refs }) {
const { raycaster } = objects;
const camera = refs.camera.current;
const mouse = refs.mouse.current;
diff --git a/src/frontend/ui/models/Particles/components/atoms/Raycaster/index.js b/src/frontend/ui/models/Particles/components/atoms/Raycaster/index.js
index d726742..e803f87 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Raycaster/index.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Raycaster/index.js
@@ -1,2 +1,2 @@
-export { RaycasterSetup } from './logic/setup';
-export { RaycasterUpdate } from './logic/update';
\ No newline at end of file
+export { default as Raycaster } from './Raycaster';
+export { default as RaycasterLogic } from './Raycaster.logic';
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Raycaster/index.jsx b/src/frontend/ui/models/Particles/components/atoms/Raycaster/index.jsx
deleted file mode 100644
index a6b2b5b..0000000
--- a/src/frontend/ui/models/Particles/components/atoms/Raycaster/index.jsx
+++ /dev/null
@@ -1,8 +0,0 @@
-/**
- * Raycaster.jsx
- * Atom component for the raycaster in the Particles model
- */
-
-export default function Raycaster() {
- return null;
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Raycaster/logic/setup.js b/src/frontend/ui/models/Particles/components/atoms/Raycaster/logic/setup.js
deleted file mode 100644
index 012ef54..0000000
--- a/src/frontend/ui/models/Particles/components/atoms/Raycaster/logic/setup.js
+++ /dev/null
@@ -1,16 +0,0 @@
-/**
- * Raycaster setup strategy for particle system
- */
-
-import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
-
-export class RaycasterSetup extends ModelStrategy {
- /**
- * Execute raycaster setup
- * @param {Object} args - Arguments containing config, data, and objects
- */
- execute({ config, data: { unit }, objects: { raycaster } }) {
- const { animations: { chaos: { radius } } } = config;
- raycaster.params.Points.threshold = radius * unit;
- }
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/index.js b/src/frontend/ui/models/Particles/components/atoms/index.js
index 7227091..49d0f0f 100644
--- a/src/frontend/ui/models/Particles/components/atoms/index.js
+++ b/src/frontend/ui/models/Particles/components/atoms/index.js
@@ -1,9 +1,8 @@
+export * from './Box';
export * from './Camera';
export * from './Circle';
export * from './Mouse';
export * from './Plane';
-export * from './Particles/effects';
-export * from './Particles/handlers';
-export * from './Particles/logic';
+export * from './Particles';
export * from './Raycaster';
export * from './RayLine';
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/molecules/Controls/index.jsx b/src/frontend/ui/models/Particles/components/molecules/Controls/Controls.jsx
similarity index 69%
rename from src/frontend/ui/models/Particles/components/molecules/Controls/index.jsx
rename to src/frontend/ui/models/Particles/components/molecules/Controls/Controls.jsx
index a0e2e3f..2500829 100644
--- a/src/frontend/ui/models/Particles/components/molecules/Controls/index.jsx
+++ b/src/frontend/ui/models/Particles/components/molecules/Controls/Controls.jsx
@@ -1,10 +1,10 @@
//* Imports
import { OrbitControls } from "@react-three/drei";
import Box from "../../atoms/Box";
-import Circle from "../../atoms/Circle";
-import Plane from "../../atoms/Plane";
-import RayLine from "../../atoms/RayLine";
-import Camera from "../../atoms/Camera";
+import Circle from "../../atoms/Circle/Circle";
+import Plane from "../../atoms/Plane/Plane";
+import RayLine from "../../atoms/RayLine/RayLine";
+import Camera from "../../atoms/Camera/Camera";
//* Main
export default function Controls(args) {
diff --git a/src/frontend/ui/models/Particles/components/molecules/Controls/index.js b/src/frontend/ui/models/Particles/components/molecules/Controls/index.js
new file mode 100644
index 0000000..71b5b47
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/molecules/Controls/index.js
@@ -0,0 +1,2 @@
+export { default } from './Controls';
+export { default as Controls } from './Controls';
diff --git a/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/index.jsx b/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/ParticlesSystem.jsx
similarity index 70%
rename from src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/index.jsx
rename to src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/ParticlesSystem.jsx
index 2a23113..9708797 100644
--- a/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/index.jsx
+++ b/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/ParticlesSystem.jsx
@@ -6,7 +6,7 @@
//* Imports
import { useEffect } from "react";
import { useFrame } from "@react-three/fiber";
-import Particles from "../../atoms/Particles/index.jsx";
+import Particles from "../../atoms/Particles/Particles.jsx";
import {
setup,
update,
@@ -14,10 +14,10 @@ import {
import { ParticlesManager } from "../../../logic/manager.js";
//* Main
-export default function ParticlesSystem(args) {
+function ParticlesSystem(args) {
// Logic
useEffect(() => {
- setup(args);
+ ParticlesManager.setup('particlesSystem', args);
const handleMouseMove = (event) => {
ParticlesManager.handle('mouseMove', { event, ...args });
@@ -27,8 +27,8 @@ export default function ParticlesSystem(args) {
ParticlesManager.handle('resize', { event, ...args });
};
- ParticlesManager.executeAll('add', { handleMouseMove, handleResize });
- return () => ParticlesManager.executeAll('remove', { handleMouseMove, handleResize });
+ ParticlesManager.addAll({ handleMouseMove, handleResize });
+ return () => ParticlesManager.removeAll({ handleMouseMove, handleResize });
}, [args]);
useFrame(({ clock }) => {
@@ -37,4 +37,6 @@ export default function ParticlesSystem(args) {
});
return ;
-}
\ No newline at end of file
+}
+
+export default ParticlesSystem;
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/ParticlesSystem.logic.js b/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/ParticlesSystem.logic.js
new file mode 100644
index 0000000..9b84c08
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/ParticlesSystem.logic.js
@@ -0,0 +1,23 @@
+import { ParticlesManager } from "../../../logic/manager";
+import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
+
+export default class ParticlesSystemLogic extends ModelStrategy {
+ add({ handleResize }) {
+ window.addEventListener("resize", handleResize);
+ }
+
+ remove({ handleResize }) {
+ window.removeEventListener("resize", handleResize);
+ }
+
+ setup(args) {
+ ParticlesManager.setup('camera', args);
+ ParticlesManager.setup('particles', args);
+ ParticlesManager.setup('plane', args);
+ ParticlesManager.setup('raycaster', args);
+ }
+
+ update(args) {
+ ParticlesManager.update("particles", args);
+ }
+}
diff --git a/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/index.js b/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/index.js
new file mode 100644
index 0000000..cc9fa22
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/index.js
@@ -0,0 +1,2 @@
+export { default } from './ParticlesSystem';
+export { default as ParticlesSystem } from './ParticlesSystem';
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/molecules/index.js b/src/frontend/ui/models/Particles/components/molecules/index.js
new file mode 100644
index 0000000..2365e40
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/molecules/index.js
@@ -0,0 +1,2 @@
+export * from './Controls';
+export * from './ParticlesSystem';
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/config/index.js b/src/frontend/ui/models/Particles/config/index.js
index 3842e7d..51d778e 100644
--- a/src/frontend/ui/models/Particles/config/index.js
+++ b/src/frontend/ui/models/Particles/config/index.js
@@ -20,7 +20,7 @@
export const config = {
// General
general: {
- showHelpers: false,
+ showHelpers: true,
scale: 1,
size: 150,
},
diff --git a/src/frontend/ui/models/Particles/index.jsx b/src/frontend/ui/models/Particles/index.jsx
index b1427fe..f130bbd 100644
--- a/src/frontend/ui/models/Particles/index.jsx
+++ b/src/frontend/ui/models/Particles/index.jsx
@@ -18,9 +18,7 @@
//* Imports
import { useArgs } from "@semantyk/frontend/ui/models/Particles/hooks/useArgs";
-import Controls from "./components/molecules/Controls";
-import ParticlesSystem from "./components/molecules/ParticlesSystem";
-import Camera from "./components/atoms/Camera";
+import { Controls, ParticlesSystem } from "./components/molecules";
//* Main
export default function ParticlesModel() {
diff --git a/src/frontend/ui/models/Particles/logic/index.js b/src/frontend/ui/models/Particles/logic/index.js
index a7ce015..1ba1147 100644
--- a/src/frontend/ui/models/Particles/logic/index.js
+++ b/src/frontend/ui/models/Particles/logic/index.js
@@ -20,25 +20,6 @@ import { Vector3 } from "three";
import { ParticlesManager } from "./manager";
//* Main
-export function getImageData(args) {
- // Args
- const { data: { unit }, objects: { image } } = args;
- // Logic
- let { width, height } = image;
- const canvas = document.createElement("canvas");
- const context = canvas.getContext("2d");
- canvas.width = unit;
- canvas.height = (height / width) * unit;
- context.drawImage(image, 0, 0, canvas.width, canvas.height);
- // Return
- return context.getImageData(0, 0, canvas.width, canvas.height);
-}
-
-export function ease(time, duration) {
- const t = Math.min(time / duration, 1);
- return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
-}
-
export function setup(args) {
ParticlesManager.setup('camera', args);
ParticlesManager.setup('particles', args);
@@ -53,7 +34,7 @@ export function update(args) {
export function updateOnMouseMove(args) {
const target = new Vector3()
ParticlesManager.update("circle", { target, ...args });
- ParticlesManager.update("line", { target, ...args });
+ ParticlesManager.update("rayLine", { target, ...args });
ParticlesManager.update("mouse", args);
ParticlesManager.update("raycaster", args);
}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/listeners/resize.js b/src/frontend/ui/models/Particles/logic/listeners/resize.js
deleted file mode 100644
index 2825069..0000000
--- a/src/frontend/ui/models/Particles/logic/listeners/resize.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
-
-export class ResizeListener extends ModelStrategy {
- add({ handleResize }) {
- window.addEventListener("resize", handleResize);
- }
-
- remove({ handleResize }) {
- window.removeEventListener("resize", handleResize);
- }
-}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/manager.js b/src/frontend/ui/models/Particles/logic/manager.js
index f2bccf9..4a9b033 100644
--- a/src/frontend/ui/models/Particles/logic/manager.js
+++ b/src/frontend/ui/models/Particles/logic/manager.js
@@ -1,24 +1,25 @@
import { ModelManager } from '@semantyk/frontend/ui/components/molecules/Model/logic/manager';
-import { ResizeListener } from './listeners/resize';
-import { CameraSetup } from '../components/atoms/Camera/logic/setup';
-import { CircleUpdate } from '../components/atoms/Circle/logic/update';
-import { MouseHandler, MouseListener, MouseUpdate } from '../components/atoms/Mouse';
-import { PlaneSetup } from '../components/atoms/Plane/logic/setup';
-import { RaycasterSetup, RaycasterUpdate } from '../components/atoms/Raycaster';
-import { LineUpdate } from '../components/atoms/RayLine/logic/update';
import { ChaosEffect } from '../components/atoms/Particles/effects/chaos';
import { ColorEffect } from '../components/atoms/Particles/effects/color';
import { EntropyEffect } from '../components/atoms/Particles/effects/entropy';
import { PositionEffect } from '../components/atoms/Particles/effects/position';
-import { ResizeHandler } from '../components/atoms/Particles/handlers/resize';
-import { ParticlesSetup } from '../components/atoms/Particles/logic/setup';
-import { ParticlesUpdate } from '../components/atoms/Particles/logic/update';
-
+import { Camera, Circle, Mouse, Particles, Plane, Raycaster, RayLine } from '../components/atoms';
+import ParticlesSystemLogic from '../components/molecules/ParticlesSystem/ParticlesSystem.logic';
+import ParticlesLogic from '../components/atoms/Particles/Particles.logic';
/**
* Manager class for particle strategies using the Strategy pattern
*/
export class ParticlesManager extends ModelManager {
- static instance = new ParticlesManager();
+ static logic = {
+ camera: Camera.logic,
+ circle: Circle.logic,
+ mouse: Mouse.logic,
+ plane: Plane.logic,
+ particles: new ParticlesLogic(), // TODO: Remove hack to get logic to work
+ particlesSystem: new ParticlesSystemLogic(), // TODO: Remove hack to get logic to work
+ raycaster: Raycaster.logic,
+ rayLine: RayLine.logic
+ }
static effects = {
chaos: new ChaosEffect(),
@@ -28,28 +29,13 @@ export class ParticlesManager extends ModelManager {
};
static handlers = {
- mouseMove: new MouseHandler(),
- resize: new ResizeHandler()
- };
-
- static setups = {
- camera: new CameraSetup(),
- particles: new ParticlesSetup(),
- plane: new PlaneSetup(),
- raycaster: new RaycasterSetup()
+ mouseMove: Mouse.logic,
+ resize: Particles.logic
};
static listeners = {
- mouse: new MouseListener(),
- resize: new ResizeListener()
- };
-
- static updates = {
- circle: new CircleUpdate(),
- line: new LineUpdate(),
- mouse: new MouseUpdate(),
- particles: new ParticlesUpdate(),
- raycaster: new RaycasterUpdate(),
+ mouse: Mouse.logic,
+ resize: new ParticlesSystemLogic()
};
static affect(item, ...args) {
@@ -59,21 +45,26 @@ export class ParticlesManager extends ModelManager {
static handle(item, ...args) {
const collection = this.handlers;
- return super.execute(collection, item, 'execute', ...args);
+ return super.execute(collection, item, 'handle', ...args);
}
static setup(item, ...args) {
- const collection = this.setups;
- return super.execute(collection, item, 'execute', ...args);
+ const collection = this.logic;
+ return super.execute(collection, item, 'setup', ...args);
}
static update(item, ...args) {
- const collection = this.updates;
- return super.execute(collection, item, 'execute', ...args);
+ const collection = this.logic;
+ return super.execute(collection, item, 'update', ...args);
+ }
+
+ static addAll(...args) {
+ const collection = this.listeners;
+ return super.executeAll(collection, "add", ...args);
}
- static executeAll(member, ...args) {
+ static removeAll(...args) {
const collection = this.listeners;
- return super.executeAll(collection, member, ...args);
+ return super.executeAll(collection, "remove", ...args);
}
}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/utils/ease.js b/src/frontend/ui/models/Particles/utils/ease.js
new file mode 100644
index 0000000..64a4da0
--- /dev/null
+++ b/src/frontend/ui/models/Particles/utils/ease.js
@@ -0,0 +1,4 @@
+export function ease(time, duration) {
+ const t = Math.min(time / duration, 1);
+ return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/utils/image.js b/src/frontend/ui/models/Particles/utils/image.js
new file mode 100644
index 0000000..7b6567f
--- /dev/null
+++ b/src/frontend/ui/models/Particles/utils/image.js
@@ -0,0 +1,17 @@
+/**
+ * Image utilities for Particles
+ */
+
+export function getImageData(args) {
+ // Args
+ const { data: { unit }, objects: { image } } = args;
+ // Logic
+ let { width, height } = image;
+ const canvas = document.createElement("canvas");
+ const context = canvas.getContext("2d");
+ canvas.width = unit;
+ canvas.height = (height / width) * unit;
+ context.drawImage(image, 0, 0, canvas.width, canvas.height);
+ // Return
+ return context.getImageData(0, 0, canvas.width, canvas.height);
+}
\ No newline at end of file
From 9ca176afbb245b7254a9fe70e7b9834a01839d5a Mon Sep 17 00:00:00 2001
From: "Daniel B."
Date: Fri, 14 Mar 2025 22:31:49 -0600
Subject: [PATCH 6/7] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20Chore:=20Perfect=20ref?=
=?UTF-8?q?actor=20on=20Particles=20model?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../molecules/Model/logic/strategy.js | 15 ++++++++++++---
.../components/atoms/Camera/Camera.jsx | 2 +-
.../components/atoms/Camera/Camera.logic.js | 2 +-
.../components/atoms/Circle/Circle.jsx | 2 +-
.../components/atoms/Circle/Circle.logic.js | 2 +-
.../Particles/components/atoms/Mouse/Mouse.js | 4 +---
.../components/atoms/Mouse/Mouse.logic.js | 8 ++++----
.../atoms/Particles/Particles.logic.js | 11 ++++++-----
.../atoms/Particles/effects/chaos.js | 2 +-
.../atoms/Particles/effects/color.js | 2 +-
.../atoms/Particles/effects/entropy.js | 2 +-
.../atoms/Particles/effects/flotation.js | 2 +-
.../atoms/Particles/effects/interpolation.js | 2 +-
.../atoms/Particles/effects/position.js | 18 +++++-------------
.../components/atoms/Particles/index.js | 3 ++-
.../Particles/components/atoms/Plane/Plane.jsx | 2 +-
.../components/atoms/Plane/Plane.logic.js | 2 +-
.../components/atoms/RayLine/RayLine.jsx | 2 +-
.../components/atoms/RayLine/RayLine.logic.js | 2 +-
.../components/atoms/Raycaster/Raycaster.js | 2 +-
.../atoms/Raycaster/Raycaster.logic.js | 4 ++--
.../ParticlesSystem/ParticlesSystem.jsx | 9 ++-------
.../ParticlesSystem/ParticlesSystem.logic.js | 8 ++++----
.../ui/models/Particles/logic/manager.js | 17 ++++++++---------
24 files changed, 60 insertions(+), 65 deletions(-)
diff --git a/src/frontend/ui/components/molecules/Model/logic/strategy.js b/src/frontend/ui/components/molecules/Model/logic/strategy.js
index 1c1fd7c..4c8e189 100644
--- a/src/frontend/ui/components/molecules/Model/logic/strategy.js
+++ b/src/frontend/ui/components/molecules/Model/logic/strategy.js
@@ -7,16 +7,25 @@ export class ModelStrategy {
* @param {Object} args - Event arguments
* @throws {Error} Must be implemented by child classes
*/
- add(args) {
+ static add(args) {
throw new Error('Strategy must implement add method');
}
+ /**
+ * Handle the event
+ * @param {Object} args - Event arguments
+ * @throws {Error} Must be implemented by child classes
+ */
+ static handle(args) {
+ throw new Error('Strategy must implement handle method');
+ }
+
/**
* Execute the strategy
* @param {Object} args - Strategy arguments
* @throws {Error} Must be implemented by child classes
*/
- execute(args) {
+ static execute(args) {
throw new Error('Strategy must implement execute method');
}
@@ -25,7 +34,7 @@ export class ModelStrategy {
* @param {Object} args - Event arguments
* @throws {Error} Must be implemented by child classes
*/
- remove(args) {
+ static remove(args) {
throw new Error('Strategy must implement remove method');
}
}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Camera/Camera.jsx b/src/frontend/ui/models/Particles/components/atoms/Camera/Camera.jsx
index a9f1681..c78e394 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Camera/Camera.jsx
+++ b/src/frontend/ui/models/Particles/components/atoms/Camera/Camera.jsx
@@ -23,6 +23,6 @@ function Camera({ config, refs }) {
);
}
-Camera.logic = new CameraLogic();
+Camera.logic = CameraLogic;
export default Camera;
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Camera/Camera.logic.js b/src/frontend/ui/models/Particles/components/atoms/Camera/Camera.logic.js
index 79811c0..e92dc39 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Camera/Camera.logic.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Camera/Camera.logic.js
@@ -1,7 +1,7 @@
import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
export default class CameraLogic extends ModelStrategy {
- setup({ config, data: { unit }, refs: { camera } }) {
+ static setup({ config, data: { unit }, refs: { camera } }) {
const { camera: { margin } } = config;
const aspectRatio = window.innerWidth / window.innerHeight;
diff --git a/src/frontend/ui/models/Particles/components/atoms/Circle/Circle.jsx b/src/frontend/ui/models/Particles/components/atoms/Circle/Circle.jsx
index 96d0f66..5ad601e 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Circle/Circle.jsx
+++ b/src/frontend/ui/models/Particles/components/atoms/Circle/Circle.jsx
@@ -30,6 +30,6 @@ function Circle({ config, data, refs }) {
);
}
-Circle.logic = new CircleLogic();
+Circle.logic = CircleLogic;
export default Circle;
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Circle/Circle.logic.js b/src/frontend/ui/models/Particles/components/atoms/Circle/Circle.logic.js
index c12521e..ba5073c 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Circle/Circle.logic.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Circle/Circle.logic.js
@@ -1,7 +1,7 @@
import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
export default class CircleLogic extends ModelStrategy {
- update({ objects, refs, target }) {
+ static update({ objects, refs, target }) {
objects.raycaster.ray.intersectPlane(refs.plane.current, target);
refs.circle.current.position.copy(target);
}
diff --git a/src/frontend/ui/models/Particles/components/atoms/Mouse/Mouse.js b/src/frontend/ui/models/Particles/components/atoms/Mouse/Mouse.js
index 7915baa..5a5e3d6 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Mouse/Mouse.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Mouse/Mouse.js
@@ -1,7 +1,5 @@
import MouseLogic from './Mouse.logic';
-const Mouse = {
- logic: new MouseLogic()
-};
+const Mouse = { logic: MouseLogic };
export default Mouse;
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Mouse/Mouse.logic.js b/src/frontend/ui/models/Particles/components/atoms/Mouse/Mouse.logic.js
index f9722c5..f42fa60 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Mouse/Mouse.logic.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Mouse/Mouse.logic.js
@@ -3,17 +3,17 @@ import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/
import { updateOnMouseMove } from "../../../logic";
export default class MouseLogic extends ModelStrategy {
- add({ handleMouseMove }) {
+ static add({ handleMouseMove }) {
window.addEventListener("mousemove", handleMouseMove);
window.addEventListener("touchmove", handleMouseMove);
}
- remove({ handleMouseMove }) {
+ static remove({ handleMouseMove }) {
window.removeEventListener("mousemove", handleMouseMove);
window.removeEventListener("touchmove", handleMouseMove);
}
- handle({ event, ...args }) {
+ static handle({ event, ...args }) {
const { mouse, moveMouseTimeout } = args.refs;
clearTimeout(moveMouseTimeout.current);
mouse.current.isMoving = true;
@@ -34,7 +34,7 @@ export default class MouseLogic extends ModelStrategy {
});
}
- update({ refs, events }) {
+ static update({ refs, events }) {
const { x, y } = onMouseMove(events.mousemove);
refs.mouse.current.x = x * 2 - 1;
refs.mouse.current.y = -y * 2 + 1;
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/Particles.logic.js b/src/frontend/ui/models/Particles/components/atoms/Particles/Particles.logic.js
index a4a6f8e..4d562d3 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/Particles.logic.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/Particles.logic.js
@@ -2,9 +2,10 @@ import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/
import { getImageData } from "../../../utils/image";
import { Float32BufferAttribute } from "three";
import { ParticlesManager } from "../../../logic/manager";
+import { ColorEffect, PositionEffect } from "./effects";
export default class ParticlesLogic extends ModelStrategy {
- handle({ event, ...args }) {
+ static handle({ event, ...args }) {
const { particles } = args.refs;
ParticlesManager.setup('camera', args);
const { particle } = args.config;
@@ -13,7 +14,7 @@ export default class ParticlesLogic extends ModelStrategy {
particles.current.material.size = size;
}
- setup({ config, data: { color, unit }, objects: { image }, refs }) {
+ static setup({ config, data: { color, unit }, objects: { image }, refs }) {
const { particle } = config;
const particles = refs.particles.current;
const { data } = getImageData({ data: { unit }, objects: { image } });
@@ -69,13 +70,13 @@ export default class ParticlesLogic extends ModelStrategy {
particles.material.size = size;
}
- update(args) {
+ static update(args) {
const intersects = args.objects.raycaster.intersectObject(args.refs.particles.current);
const idxs = new Set(intersects.map(({ index }) => index));
for (let i = 0; i < args.refs.particles.current.data.count; i++) {
- ParticlesManager.affect('color', { i, ...args });
- ParticlesManager.affect('position', { i, idxs, ...args });
+ ColorEffect.execute({ i, ...args });
+ PositionEffect.execute({ i, idxs, ...args });
}
args.refs.particles.current.geometry.attributes.color.needsUpdate = true;
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos.js
index 56149f0..82d941c 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos.js
@@ -1,7 +1,7 @@
import { ModelStrategy } from '@semantyk/frontend/ui/components/molecules/Model/logic/strategy';
export class ChaosEffect extends ModelStrategy {
- execute({ config, data, i, idxs, final, objects: { clock }, refs: { mouse, particles } }) {
+ static execute({ config, data, i, idxs, final, objects: { clock }, refs: { mouse, particles } }) {
const { unit } = data;
const { animations: { chaos, order, interpolation } } = config;
const elapsedTime = clock.current.getElapsedTime();
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/color.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/color.js
index bc596fc..e48df30 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/color.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/color.js
@@ -2,7 +2,7 @@ import { Color } from 'three';
import { ModelStrategy } from '@semantyk/frontend/ui/components/molecules/Model/logic/strategy';
export class ColorEffect extends ModelStrategy {
- execute({ data: { color }, i, ...args }) {
+ static execute({ data: { color }, i, ...args }) {
const chaoticValue = args.refs.particles.current.data.chaotic[i];
const final = color.clone();
const target = new Color(1, 0, 0);
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/entropy.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/entropy.js
index 741e222..b63e6b8 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/entropy.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/entropy.js
@@ -2,7 +2,7 @@ import { Vector3 } from 'three';
import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
export class EntropyEffect extends ModelStrategy {
- execute({ config, i, idxs, final, ...args }) {
+ static execute({ config, i, idxs, final, ...args }) {
const { animations: { expansion, interpolation } } = config;
const elapsedTime = args.objects.clock.current.getElapsedTime();
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/flotation.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/flotation.js
index 73a6bae..e5a8307 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/flotation.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/flotation.js
@@ -2,7 +2,7 @@ import { Vector3 } from 'three';
import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
export class FlotationEffect extends ModelStrategy {
- execute({ config, i, final, objects: { clock }, refs: { particles } }) {
+ static execute({ config, i, final, objects: { clock }, refs: { particles } }) {
const { offsets } = particles.current.data.positions;
const { animations: { flotation } } = config;
const elapsedTime = clock.current.getElapsedTime();
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/interpolation.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/interpolation.js
index 47b59e0..675baa9 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/interpolation.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/interpolation.js
@@ -3,7 +3,7 @@ import { ease } from "@semantyk/frontend/ui/models/Particles/utils/ease";
import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
export class InterpolationEffect extends ModelStrategy {
- execute({ config, i, final, objects: { clock }, refs: { particles } }) {
+ static execute({ config, i, final, objects: { clock }, refs: { particles } }) {
const { ideal, initial } = particles.current.data.positions;
const { animations: { interpolation: { duration } } } = config;
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/position.js b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/position.js
index 06c4db6..0cea872 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/position.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/effects/position.js
@@ -6,24 +6,16 @@ import { Vector3 } from 'three';
import { ChaosEffect } from "./chaos";
export class PositionEffect extends ModelStrategy {
- constructor() {
- super();
- this.chaosEffect = new ChaosEffect();
- this.entropyEffect = new EntropyEffect();
- this.interpolationEffect = new InterpolationEffect();
- this.flotationEffect = new FlotationEffect();
- }
-
- execute({ i, idxs, ...args }) {
+ static execute({ i, idxs, ...args }) {
const { particles } = args.refs;
const final = new Vector3()
//* Effects
//! Order Matters
- this.entropyEffect.execute({ i, idxs, final, ...args });
- this.chaosEffect.execute({ i, idxs, final, ...args });
- this.interpolationEffect.execute({ i, final, ...args });
- this.flotationEffect.execute({ i, final, ...args });
+ EntropyEffect.execute({ i, idxs, final, ...args });
+ ChaosEffect.execute({ i, idxs, final, ...args });
+ InterpolationEffect.execute({ i, final, ...args });
+ FlotationEffect.execute({ i, final, ...args });
const positions = particles.current.geometry.attributes.position.array;
positions.set(final.toArray(), i * 3);
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/index.js b/src/frontend/ui/models/Particles/components/atoms/Particles/index.js
index 0cb9b8f..64fa614 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/index.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Particles/index.js
@@ -1,3 +1,4 @@
export * from './effects';
-export { default } from './Particles'
+
+export { default } from './Particles';
export { default as Particles } from './Particles';
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Plane/Plane.jsx b/src/frontend/ui/models/Particles/components/atoms/Plane/Plane.jsx
index d212590..8137aa1 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Plane/Plane.jsx
+++ b/src/frontend/ui/models/Particles/components/atoms/Plane/Plane.jsx
@@ -25,6 +25,6 @@ function Plane({ config, data, refs }) {
);
}
-Plane.logic = new PlaneLogic();
+Plane.logic = PlaneLogic;
export default Plane;
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Plane/Plane.logic.js b/src/frontend/ui/models/Particles/components/atoms/Plane/Plane.logic.js
index 3737ef0..b98e6b8 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Plane/Plane.logic.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Plane/Plane.logic.js
@@ -2,7 +2,7 @@ import { Plane, Vector3 } from "three";
import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
export default class PlaneLogic extends ModelStrategy {
- setup({ data: { unit }, refs: { plane } }) {
+ static setup({ data: { unit }, refs: { plane } }) {
const normal = new Vector3(0, 0, 1);
plane.current = new Plane(normal, unit / 2);
}
diff --git a/src/frontend/ui/models/Particles/components/atoms/RayLine/RayLine.jsx b/src/frontend/ui/models/Particles/components/atoms/RayLine/RayLine.jsx
index edd1a6a..894c096 100644
--- a/src/frontend/ui/models/Particles/components/atoms/RayLine/RayLine.jsx
+++ b/src/frontend/ui/models/Particles/components/atoms/RayLine/RayLine.jsx
@@ -21,6 +21,6 @@ function RayLine({ config, refs }) {
);
}
-RayLine.logic = new RayLineLogic();
+RayLine.logic = RayLineLogic;
export default RayLine;
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/RayLine/RayLine.logic.js b/src/frontend/ui/models/Particles/components/atoms/RayLine/RayLine.logic.js
index 989854e..53dfb44 100644
--- a/src/frontend/ui/models/Particles/components/atoms/RayLine/RayLine.logic.js
+++ b/src/frontend/ui/models/Particles/components/atoms/RayLine/RayLine.logic.js
@@ -2,7 +2,7 @@ import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/
import { BufferGeometry } from "three";
export default class RayLineLogic extends ModelStrategy {
- update({ objects, refs, target }) {
+ static update({ objects, refs, target }) {
const { origin } = objects.raycaster.ray;
const points = [origin, target];
const geometry = new BufferGeometry().setFromPoints(points);
diff --git a/src/frontend/ui/models/Particles/components/atoms/Raycaster/Raycaster.js b/src/frontend/ui/models/Particles/components/atoms/Raycaster/Raycaster.js
index ebac016..0307992 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Raycaster/Raycaster.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Raycaster/Raycaster.js
@@ -6,7 +6,7 @@
import RaycasterLogic from "./Raycaster.logic";
const Raycaster = {
- logic: new RaycasterLogic()
+ logic: RaycasterLogic
};
export default Raycaster;
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Raycaster/Raycaster.logic.js b/src/frontend/ui/models/Particles/components/atoms/Raycaster/Raycaster.logic.js
index ffdad7e..49d8765 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Raycaster/Raycaster.logic.js
+++ b/src/frontend/ui/models/Particles/components/atoms/Raycaster/Raycaster.logic.js
@@ -2,12 +2,12 @@ import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/
import { Vector2 } from "three";
export default class RaycasterLogic extends ModelStrategy {
- setup({ config, data: { unit }, objects: { raycaster } }) {
+ static setup({ config, data: { unit }, objects: { raycaster } }) {
const { animations: { chaos: { radius } } } = config;
raycaster.params.Points.threshold = radius * unit;
}
- update({ objects, refs }) {
+ static update({ objects, refs }) {
const { raycaster } = objects;
const camera = refs.camera.current;
const mouse = refs.mouse.current;
diff --git a/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/ParticlesSystem.jsx b/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/ParticlesSystem.jsx
index 9708797..8fc5714 100644
--- a/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/ParticlesSystem.jsx
+++ b/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/ParticlesSystem.jsx
@@ -8,7 +8,6 @@ import { useEffect } from "react";
import { useFrame } from "@react-three/fiber";
import Particles from "../../atoms/Particles/Particles.jsx";
import {
- setup,
update,
} from "@semantyk/frontend/ui/models/Particles/logic";
import { ParticlesManager } from "../../../logic/manager.js";
@@ -23,12 +22,8 @@ function ParticlesSystem(args) {
ParticlesManager.handle('mouseMove', { event, ...args });
};
- const handleResize = (event) => {
- ParticlesManager.handle('resize', { event, ...args });
- };
-
- ParticlesManager.addAll({ handleMouseMove, handleResize });
- return () => ParticlesManager.removeAll({ handleMouseMove, handleResize });
+ ParticlesManager.addAll({ handleMouseMove });
+ return () => ParticlesManager.removeAll({ handleMouseMove });
}, [args]);
useFrame(({ clock }) => {
diff --git a/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/ParticlesSystem.logic.js b/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/ParticlesSystem.logic.js
index 9b84c08..6ddf60a 100644
--- a/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/ParticlesSystem.logic.js
+++ b/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/ParticlesSystem.logic.js
@@ -2,15 +2,15 @@ import { ParticlesManager } from "../../../logic/manager";
import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
export default class ParticlesSystemLogic extends ModelStrategy {
- add({ handleResize }) {
+ static add({ handleResize }) {
window.addEventListener("resize", handleResize);
}
- remove({ handleResize }) {
+ static remove({ handleResize }) {
window.removeEventListener("resize", handleResize);
}
- setup(args) {
+ static setup(args) {
ParticlesManager.setup('camera', args);
ParticlesManager.setup('particles', args);
ParticlesManager.setup('plane', args);
@@ -20,4 +20,4 @@ export default class ParticlesSystemLogic extends ModelStrategy {
update(args) {
ParticlesManager.update("particles", args);
}
-}
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/manager.js b/src/frontend/ui/models/Particles/logic/manager.js
index 4a9b033..522e326 100644
--- a/src/frontend/ui/models/Particles/logic/manager.js
+++ b/src/frontend/ui/models/Particles/logic/manager.js
@@ -15,27 +15,26 @@ export class ParticlesManager extends ModelManager {
circle: Circle.logic,
mouse: Mouse.logic,
plane: Plane.logic,
- particles: new ParticlesLogic(), // TODO: Remove hack to get logic to work
- particlesSystem: new ParticlesSystemLogic(), // TODO: Remove hack to get logic to work
+ particles: ParticlesLogic, // TODO: Improve this fix
+ particlesSystem: ParticlesSystemLogic, // TODO: Improve this fix
raycaster: Raycaster.logic,
rayLine: RayLine.logic
}
static effects = {
- chaos: new ChaosEffect(),
- color: new ColorEffect(),
- entropy: new EntropyEffect(),
- position: new PositionEffect()
+ chaos: ChaosEffect,
+ color: ColorEffect,
+ entropy: EntropyEffect,
+ position: PositionEffect
};
static handlers = {
- mouseMove: Mouse.logic,
- resize: Particles.logic
+ mouseMove: Mouse.logic
};
static listeners = {
mouse: Mouse.logic,
- resize: new ParticlesSystemLogic()
+ resize: ParticlesSystemLogic
};
static affect(item, ...args) {
From dc1bc7f33d2588f41638f76a5f664fb7692f3c1b Mon Sep 17 00:00:00 2001
From: "Daniel B."
Date: Fri, 14 Mar 2025 23:58:08 -0600
Subject: [PATCH 7/7] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20Refactor:=20Finish=20r?=
=?UTF-8?q?efactor=20on=20Particles=20Model?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
public/404.svg | 9 +++++
src/app/layout.jsx | 2 +-
.../molecules/Model/{index.jsx => Model.jsx} | 22 +++++++---
.../Particles/{index.jsx => Particles.jsx} | 10 +++--
.../{logic/manager.js => Particles.logic.js} | 25 ++----------
.../Particles/components/atoms/Box/Box.jsx | 4 +-
.../components/atoms/Camera/Camera.jsx | 4 +-
.../components/atoms/Circle/Circle.jsx | 4 +-
.../components/atoms/Circle/Circle.logic.js | 6 +--
.../components/atoms/Mouse/Mouse.logic.js | 13 +++---
.../components/atoms/Mouse/updates/color.js | 11 -----
.../atoms/Mouse/updates/position.js | 11 -----
.../atoms/Particles/effects/index.js | 4 --
.../components/atoms/Plane/Plane.jsx | 4 +-
.../components/atoms/RayLine/RayLine.jsx | 4 +-
.../Particles/components/atoms/index.js | 2 +-
.../molecules/Controls/Controls.jsx | 4 +-
.../Particles/Particles.jsx | 0
.../Particles/Particles.logic.js | 15 ++-----
.../Particles/effects/chaos.js | 0
.../Particles/effects/color.js | 6 +--
.../Particles/effects/entropy.js | 0
.../Particles/effects/flotation.js | 0
.../molecules/Particles/effects/index.js | 4 ++
.../Particles/effects/interpolation.js | 0
.../Particles/effects/position.js | 2 +-
.../{atoms => molecules}/Particles/index.js | 1 -
.../molecules/ParticlesSystem/index.js | 2 -
.../Particles/components/molecules/index.js | 3 +-
.../System/System.jsx} | 16 ++++----
.../System/System.logic.js} | 14 +------
.../components/organisms/System/index.js | 2 +
.../Particles/components/organisms/index.js | 1 +
.../ui/models/Particles/config/index.js | 6 +--
.../ui/models/Particles/hooks/useArgs.jsx | 6 +--
.../ui/models/Particles/logic/index.js | 40 -------------------
36 files changed, 86 insertions(+), 171 deletions(-)
create mode 100644 public/404.svg
rename src/frontend/ui/components/molecules/Model/{index.jsx => Model.jsx} (71%)
rename src/frontend/ui/models/Particles/{index.jsx => Particles.jsx} (82%)
rename src/frontend/ui/models/Particles/{logic/manager.js => Particles.logic.js} (56%)
delete mode 100644 src/frontend/ui/models/Particles/components/atoms/Mouse/updates/color.js
delete mode 100644 src/frontend/ui/models/Particles/components/atoms/Mouse/updates/position.js
delete mode 100644 src/frontend/ui/models/Particles/components/atoms/Particles/effects/index.js
rename src/frontend/ui/models/Particles/components/{atoms => molecules}/Particles/Particles.jsx (100%)
rename src/frontend/ui/models/Particles/components/{atoms => molecules}/Particles/Particles.logic.js (84%)
rename src/frontend/ui/models/Particles/components/{atoms => molecules}/Particles/effects/chaos.js (100%)
rename src/frontend/ui/models/Particles/components/{atoms => molecules}/Particles/effects/color.js (58%)
rename src/frontend/ui/models/Particles/components/{atoms => molecules}/Particles/effects/entropy.js (100%)
rename src/frontend/ui/models/Particles/components/{atoms => molecules}/Particles/effects/flotation.js (100%)
create mode 100644 src/frontend/ui/models/Particles/components/molecules/Particles/effects/index.js
rename src/frontend/ui/models/Particles/components/{atoms => molecules}/Particles/effects/interpolation.js (100%)
rename src/frontend/ui/models/Particles/components/{atoms => molecules}/Particles/effects/position.js (94%)
rename src/frontend/ui/models/Particles/components/{atoms => molecules}/Particles/index.js (99%)
delete mode 100644 src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/index.js
rename src/frontend/ui/models/Particles/components/{molecules/ParticlesSystem/ParticlesSystem.jsx => organisms/System/System.jsx} (64%)
rename src/frontend/ui/models/Particles/components/{molecules/ParticlesSystem/ParticlesSystem.logic.js => organisms/System/System.logic.js} (53%)
create mode 100644 src/frontend/ui/models/Particles/components/organisms/System/index.js
create mode 100644 src/frontend/ui/models/Particles/components/organisms/index.js
delete mode 100644 src/frontend/ui/models/Particles/logic/index.js
diff --git a/public/404.svg b/public/404.svg
new file mode 100644
index 0000000..d4bd90e
--- /dev/null
+++ b/public/404.svg
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/src/app/layout.jsx b/src/app/layout.jsx
index 5251ab1..460c292 100644
--- a/src/app/layout.jsx
+++ b/src/app/layout.jsx
@@ -26,7 +26,7 @@ import Head from "@semantyk/frontend/ui/components/atoms/Head";
import Body from "@semantyk/frontend/ui/components/molecules/Body";
import { getLang } from "@semantyk/frontend/logic/services/getLang";
import Content from "@semantyk/frontend/ui/components/molecules/Content";
-import Model from "@semantyk/frontend/ui/components/molecules/Model";
+import Model from "@semantyk/frontend/ui/components/molecules/Model/Model";
//* Main
diff --git a/src/frontend/ui/components/molecules/Model/index.jsx b/src/frontend/ui/components/molecules/Model/Model.jsx
similarity index 71%
rename from src/frontend/ui/components/molecules/Model/index.jsx
rename to src/frontend/ui/components/molecules/Model/Model.jsx
index e85efc4..aacf6d3 100644
--- a/src/frontend/ui/components/molecules/Model/index.jsx
+++ b/src/frontend/ui/components/molecules/Model/Model.jsx
@@ -22,18 +22,28 @@
import React from "react";
import Canvas from "@semantyk/frontend/ui/components/molecules/Canvas";
import GraphModel from "@semantyk/frontend/ui/models/Graph";
-import { usePathname } from "next/navigation";
-import ParticlesModel from "@semantyk/frontend/ui/models/Particles";
+import { usePathname, useRouter } from "next/navigation";
+import Particles from "@semantyk/frontend/ui/models/Particles/Particles";
//* Main
export default function Model() {
- // Logic
+ // Hooks
const pathname = usePathname();
+ // Logic
+ const model = () => {
+ switch (pathname) {
+ case "/":
+ return ;
+ case "/knowledge":
+ return ;
+ default:
+ return ;
+ }
+ };
// Return
return (
);
-};
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/index.jsx b/src/frontend/ui/models/Particles/Particles.jsx
similarity index 82%
rename from src/frontend/ui/models/Particles/index.jsx
rename to src/frontend/ui/models/Particles/Particles.jsx
index f130bbd..ee68122 100644
--- a/src/frontend/ui/models/Particles/index.jsx
+++ b/src/frontend/ui/models/Particles/Particles.jsx
@@ -18,15 +18,17 @@
//* Imports
import { useArgs } from "@semantyk/frontend/ui/models/Particles/hooks/useArgs";
-import { Controls, ParticlesSystem } from "./components/molecules";
+import { Controls } from "./components/molecules";
+import { System } from "./components/organisms";
+
//* Main
-export default function ParticlesModel() {
+export default function Particles({ path }) {
// Hooks
- const args = useArgs();
+ const args = useArgs({ path });
// Return
return (<>
-
+
>);
}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/logic/manager.js b/src/frontend/ui/models/Particles/Particles.logic.js
similarity index 56%
rename from src/frontend/ui/models/Particles/logic/manager.js
rename to src/frontend/ui/models/Particles/Particles.logic.js
index 522e326..23edd40 100644
--- a/src/frontend/ui/models/Particles/logic/manager.js
+++ b/src/frontend/ui/models/Particles/Particles.logic.js
@@ -1,11 +1,6 @@
import { ModelManager } from '@semantyk/frontend/ui/components/molecules/Model/logic/manager';
-import { ChaosEffect } from '../components/atoms/Particles/effects/chaos';
-import { ColorEffect } from '../components/atoms/Particles/effects/color';
-import { EntropyEffect } from '../components/atoms/Particles/effects/entropy';
-import { PositionEffect } from '../components/atoms/Particles/effects/position';
-import { Camera, Circle, Mouse, Particles, Plane, Raycaster, RayLine } from '../components/atoms';
-import ParticlesSystemLogic from '../components/molecules/ParticlesSystem/ParticlesSystem.logic';
-import ParticlesLogic from '../components/atoms/Particles/Particles.logic';
+import { Camera, Circle, Mouse, Plane, Raycaster, RayLine } from './components/atoms';
+import ParticlesLogic from './components/molecules/Particles/Particles.logic';
/**
* Manager class for particle strategies using the Strategy pattern
*/
@@ -16,32 +11,18 @@ export class ParticlesManager extends ModelManager {
mouse: Mouse.logic,
plane: Plane.logic,
particles: ParticlesLogic, // TODO: Improve this fix
- particlesSystem: ParticlesSystemLogic, // TODO: Improve this fix
raycaster: Raycaster.logic,
rayLine: RayLine.logic
}
- static effects = {
- chaos: ChaosEffect,
- color: ColorEffect,
- entropy: EntropyEffect,
- position: PositionEffect
- };
-
static handlers = {
mouseMove: Mouse.logic
};
static listeners = {
- mouse: Mouse.logic,
- resize: ParticlesSystemLogic
+ mouse: Mouse.logic
};
- static affect(item, ...args) {
- const collection = this.effects;
- return super.execute(collection, item, 'execute', ...args);
- }
-
static handle(item, ...args) {
const collection = this.handlers;
return super.execute(collection, item, 'handle', ...args);
diff --git a/src/frontend/ui/models/Particles/components/atoms/Box/Box.jsx b/src/frontend/ui/models/Particles/components/atoms/Box/Box.jsx
index 162fb2c..b8210d0 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Box/Box.jsx
+++ b/src/frontend/ui/models/Particles/components/atoms/Box/Box.jsx
@@ -6,10 +6,10 @@
//* Main
export default function Box({ config, data, refs }) {
// Props
- const { general: { showHelpers } } = config;
+ const { general: { showControls } } = config;
// Return
return (
-
+
+
diff --git a/src/frontend/ui/models/Particles/components/atoms/index.js b/src/frontend/ui/models/Particles/components/atoms/index.js
index 49d0f0f..052689e 100644
--- a/src/frontend/ui/models/Particles/components/atoms/index.js
+++ b/src/frontend/ui/models/Particles/components/atoms/index.js
@@ -3,6 +3,6 @@ export * from './Camera';
export * from './Circle';
export * from './Mouse';
export * from './Plane';
-export * from './Particles';
+export * from '../molecules/Particles';
export * from './Raycaster';
export * from './RayLine';
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/molecules/Controls/Controls.jsx b/src/frontend/ui/models/Particles/components/molecules/Controls/Controls.jsx
index 2500829..bff466a 100644
--- a/src/frontend/ui/models/Particles/components/molecules/Controls/Controls.jsx
+++ b/src/frontend/ui/models/Particles/components/molecules/Controls/Controls.jsx
@@ -9,7 +9,7 @@ import Camera from "../../atoms/Camera/Camera";
//* Main
export default function Controls(args) {
// Props
- const { general: { showHelpers } } = args.config;
+ const { general: { showControls } } = args.config;
// Return
return (<>
@@ -17,6 +17,6 @@ export default function Controls(args) {
- {showHelpers && }
+ {showControls && }
>);
}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/Particles.jsx b/src/frontend/ui/models/Particles/components/molecules/Particles/Particles.jsx
similarity index 100%
rename from src/frontend/ui/models/Particles/components/atoms/Particles/Particles.jsx
rename to src/frontend/ui/models/Particles/components/molecules/Particles/Particles.jsx
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/Particles.logic.js b/src/frontend/ui/models/Particles/components/molecules/Particles/Particles.logic.js
similarity index 84%
rename from src/frontend/ui/models/Particles/components/atoms/Particles/Particles.logic.js
rename to src/frontend/ui/models/Particles/components/molecules/Particles/Particles.logic.js
index 4d562d3..fca5c5d 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/Particles.logic.js
+++ b/src/frontend/ui/models/Particles/components/molecules/Particles/Particles.logic.js
@@ -1,19 +1,10 @@
import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
import { getImageData } from "../../../utils/image";
import { Float32BufferAttribute } from "three";
-import { ParticlesManager } from "../../../logic/manager";
+import { ParticlesManager } from "../../../Particles.logic";
import { ColorEffect, PositionEffect } from "./effects";
export default class ParticlesLogic extends ModelStrategy {
- static handle({ event, ...args }) {
- const { particles } = args.refs;
- ParticlesManager.setup('camera', args);
- const { particle } = args.config;
- const ratio = window.innerWidth / window.innerHeight;
- const size = Math.min(Math.max(particle.size * ratio, 0), particle.size);
- particles.current.material.size = size;
- }
-
static setup({ config, data: { color, unit }, objects: { image }, refs }) {
const { particle } = config;
const particles = refs.particles.current;
@@ -75,11 +66,11 @@ export default class ParticlesLogic extends ModelStrategy {
const idxs = new Set(intersects.map(({ index }) => index));
for (let i = 0; i < args.refs.particles.current.data.count; i++) {
- ColorEffect.execute({ i, ...args });
+ // ColorEffect.execute({ i, ...args });
PositionEffect.execute({ i, idxs, ...args });
}
- args.refs.particles.current.geometry.attributes.color.needsUpdate = true;
+ // args.refs.particles.current.geometry.attributes.color.needsUpdate = true;
args.refs.particles.current.geometry.attributes.position.needsUpdate = true;
}
}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos.js b/src/frontend/ui/models/Particles/components/molecules/Particles/effects/chaos.js
similarity index 100%
rename from src/frontend/ui/models/Particles/components/atoms/Particles/effects/chaos.js
rename to src/frontend/ui/models/Particles/components/molecules/Particles/effects/chaos.js
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/color.js b/src/frontend/ui/models/Particles/components/molecules/Particles/effects/color.js
similarity index 58%
rename from src/frontend/ui/models/Particles/components/atoms/Particles/effects/color.js
rename to src/frontend/ui/models/Particles/components/molecules/Particles/effects/color.js
index e48df30..a81d467 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/color.js
+++ b/src/frontend/ui/models/Particles/components/molecules/Particles/effects/color.js
@@ -2,11 +2,11 @@ import { Color } from 'three';
import { ModelStrategy } from '@semantyk/frontend/ui/components/molecules/Model/logic/strategy';
export class ColorEffect extends ModelStrategy {
- static execute({ data: { color }, i, ...args }) {
- const chaoticValue = args.refs.particles.current.data.chaotic[i];
+ static execute({ data: { color }, i, refs: { particles } }) {
+ const chaoticValue = particles.current.data.chaotic[i];
const final = color.clone();
const target = new Color(1, 0, 0);
final.lerp(target, chaoticValue);
- args.refs.particles.current.geometry.attributes.color.set(final.toArray(), i * 3);
+ particles.current.geometry.attributes.color.set(final.toArray(), i * 3);
}
}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/entropy.js b/src/frontend/ui/models/Particles/components/molecules/Particles/effects/entropy.js
similarity index 100%
rename from src/frontend/ui/models/Particles/components/atoms/Particles/effects/entropy.js
rename to src/frontend/ui/models/Particles/components/molecules/Particles/effects/entropy.js
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/flotation.js b/src/frontend/ui/models/Particles/components/molecules/Particles/effects/flotation.js
similarity index 100%
rename from src/frontend/ui/models/Particles/components/atoms/Particles/effects/flotation.js
rename to src/frontend/ui/models/Particles/components/molecules/Particles/effects/flotation.js
diff --git a/src/frontend/ui/models/Particles/components/molecules/Particles/effects/index.js b/src/frontend/ui/models/Particles/components/molecules/Particles/effects/index.js
new file mode 100644
index 0000000..3ad4338
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/molecules/Particles/effects/index.js
@@ -0,0 +1,4 @@
+export { ChaosEffect } from './chaos';
+export { EntropyEffect } from './entropy';
+export { PositionEffect } from './position';
+export { ColorEffect } from './color';
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/interpolation.js b/src/frontend/ui/models/Particles/components/molecules/Particles/effects/interpolation.js
similarity index 100%
rename from src/frontend/ui/models/Particles/components/atoms/Particles/effects/interpolation.js
rename to src/frontend/ui/models/Particles/components/molecules/Particles/effects/interpolation.js
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/position.js b/src/frontend/ui/models/Particles/components/molecules/Particles/effects/position.js
similarity index 94%
rename from src/frontend/ui/models/Particles/components/atoms/Particles/effects/position.js
rename to src/frontend/ui/models/Particles/components/molecules/Particles/effects/position.js
index 0cea872..273ab23 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/effects/position.js
+++ b/src/frontend/ui/models/Particles/components/molecules/Particles/effects/position.js
@@ -6,7 +6,7 @@ import { Vector3 } from 'three';
import { ChaosEffect } from "./chaos";
export class PositionEffect extends ModelStrategy {
- static execute({ i, idxs, ...args }) {
+ static execute({ object, i, idxs, ...args }) {
const { particles } = args.refs;
const final = new Vector3()
diff --git a/src/frontend/ui/models/Particles/components/atoms/Particles/index.js b/src/frontend/ui/models/Particles/components/molecules/Particles/index.js
similarity index 99%
rename from src/frontend/ui/models/Particles/components/atoms/Particles/index.js
rename to src/frontend/ui/models/Particles/components/molecules/Particles/index.js
index 64fa614..0a7f788 100644
--- a/src/frontend/ui/models/Particles/components/atoms/Particles/index.js
+++ b/src/frontend/ui/models/Particles/components/molecules/Particles/index.js
@@ -1,4 +1,3 @@
export * from './effects';
-
export { default } from './Particles';
export { default as Particles } from './Particles';
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/index.js b/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/index.js
deleted file mode 100644
index cc9fa22..0000000
--- a/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-export { default } from './ParticlesSystem';
-export { default as ParticlesSystem } from './ParticlesSystem';
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/molecules/index.js b/src/frontend/ui/models/Particles/components/molecules/index.js
index 2365e40..4d69a19 100644
--- a/src/frontend/ui/models/Particles/components/molecules/index.js
+++ b/src/frontend/ui/models/Particles/components/molecules/index.js
@@ -1,2 +1 @@
-export * from './Controls';
-export * from './ParticlesSystem';
\ No newline at end of file
+export * from './Controls';
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/ParticlesSystem.jsx b/src/frontend/ui/models/Particles/components/organisms/System/System.jsx
similarity index 64%
rename from src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/ParticlesSystem.jsx
rename to src/frontend/ui/models/Particles/components/organisms/System/System.jsx
index 8fc5714..35916cb 100644
--- a/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/ParticlesSystem.jsx
+++ b/src/frontend/ui/models/Particles/components/organisms/System/System.jsx
@@ -6,17 +6,15 @@
//* Imports
import { useEffect } from "react";
import { useFrame } from "@react-three/fiber";
-import Particles from "../../atoms/Particles/Particles.jsx";
-import {
- update,
-} from "@semantyk/frontend/ui/models/Particles/logic";
-import { ParticlesManager } from "../../../logic/manager.js";
+import Particles from "../../molecules/Particles/Particles.jsx";
+import { ParticlesManager } from "../../../Particles.logic.js";
+import ParticlesSystemLogic from "./System.logic.js";
//* Main
-function ParticlesSystem(args) {
+function System(args) {
// Logic
useEffect(() => {
- ParticlesManager.setup('particlesSystem', args);
+ ParticlesSystemLogic.setup(args);
const handleMouseMove = (event) => {
ParticlesManager.handle('mouseMove', { event, ...args });
@@ -28,10 +26,10 @@ function ParticlesSystem(args) {
useFrame(({ clock }) => {
args.objects.clock.current = clock;
- update(args);
+ ParticlesManager.update("particles", args);
});
return ;
}
-export default ParticlesSystem;
\ No newline at end of file
+export default System;
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/ParticlesSystem.logic.js b/src/frontend/ui/models/Particles/components/organisms/System/System.logic.js
similarity index 53%
rename from src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/ParticlesSystem.logic.js
rename to src/frontend/ui/models/Particles/components/organisms/System/System.logic.js
index 6ddf60a..5b15dc8 100644
--- a/src/frontend/ui/models/Particles/components/molecules/ParticlesSystem/ParticlesSystem.logic.js
+++ b/src/frontend/ui/models/Particles/components/organisms/System/System.logic.js
@@ -1,23 +1,11 @@
-import { ParticlesManager } from "../../../logic/manager";
+import { ParticlesManager } from "../../../Particles.logic";
import { ModelStrategy } from "@semantyk/frontend/ui/components/molecules/Model/logic/strategy";
export default class ParticlesSystemLogic extends ModelStrategy {
- static add({ handleResize }) {
- window.addEventListener("resize", handleResize);
- }
-
- static remove({ handleResize }) {
- window.removeEventListener("resize", handleResize);
- }
-
static setup(args) {
ParticlesManager.setup('camera', args);
ParticlesManager.setup('particles', args);
ParticlesManager.setup('plane', args);
ParticlesManager.setup('raycaster', args);
}
-
- update(args) {
- ParticlesManager.update("particles", args);
- }
}
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/organisms/System/index.js b/src/frontend/ui/models/Particles/components/organisms/System/index.js
new file mode 100644
index 0000000..5c3ae48
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/organisms/System/index.js
@@ -0,0 +1,2 @@
+export { default } from './System';
+export { default as System } from './System';
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/components/organisms/index.js b/src/frontend/ui/models/Particles/components/organisms/index.js
new file mode 100644
index 0000000..4cc07e7
--- /dev/null
+++ b/src/frontend/ui/models/Particles/components/organisms/index.js
@@ -0,0 +1 @@
+export * from "./System";
\ No newline at end of file
diff --git a/src/frontend/ui/models/Particles/config/index.js b/src/frontend/ui/models/Particles/config/index.js
index 51d778e..6b4e4cd 100644
--- a/src/frontend/ui/models/Particles/config/index.js
+++ b/src/frontend/ui/models/Particles/config/index.js
@@ -20,7 +20,7 @@
export const config = {
// General
general: {
- showHelpers: true,
+ showControls: false,
scale: 1,
size: 150,
},
@@ -49,10 +49,6 @@ export const config = {
duration: 5
}
},
- // Image
- image: {
- path: "/favicon.png"
- },
// Particles
particle: {
density: 1,
diff --git a/src/frontend/ui/models/Particles/hooks/useArgs.jsx b/src/frontend/ui/models/Particles/hooks/useArgs.jsx
index 5f1b224..f52fc11 100644
--- a/src/frontend/ui/models/Particles/hooks/useArgs.jsx
+++ b/src/frontend/ui/models/Particles/hooks/useArgs.jsx
@@ -23,9 +23,9 @@ import { config } from "@semantyk/frontend/ui/models/Particles/config";
import useColorScheme from "@semantyk/frontend/hooks/useColorScheme";
//* Main
-export function useArgs() {
+export function useArgs({ path }) {
// Props
- const { general: { scale, size }, image: { path } } = config;
+ const { general: { scale, size } } = config;
// Hooks
const { colorScheme } = useColorScheme();
const { image } = useLoader(TextureLoader, path);
@@ -53,7 +53,7 @@ export function useArgs() {
camera: useRef(),
circle: useRef(),
mouse: useRef({ current: { x: 0, y: 0, isMoving: false } }),
- moveMouseTimeout: useRef(null),
+ moveMouseTimeout: useRef(),
particles: useRef(),
plane: useRef(),
rayLine: useRef(),
diff --git a/src/frontend/ui/models/Particles/logic/index.js b/src/frontend/ui/models/Particles/logic/index.js
deleted file mode 100644
index 1ba1147..0000000
--- a/src/frontend/ui/models/Particles/logic/index.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
- * # `logic.js`
- * @organization: Semantyk
- * @project: Client
- *
- * @created: Jul 17, 2024
- * @modified: Mar 7, 2025
- *
- * @author: Semantyk Team
- * @maintainer: Daniel Bakas
- *
- * @copyright: Semantyk © 2025. All rights reserved.
- * –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
- */
-
-//* Imports
-import { Vector3 } from "three";
-//* Local Imports
-import { ParticlesManager } from "./manager";
-
-//* Main
-export function setup(args) {
- ParticlesManager.setup('camera', args);
- ParticlesManager.setup('particles', args);
- ParticlesManager.setup('plane', args);
- ParticlesManager.setup('raycaster', args);
-}
-
-export function update(args) {
- ParticlesManager.update("particles", args);
-}
-
-export function updateOnMouseMove(args) {
- const target = new Vector3()
- ParticlesManager.update("circle", { target, ...args });
- ParticlesManager.update("rayLine", { target, ...args });
- ParticlesManager.update("mouse", args);
- ParticlesManager.update("raycaster", args);
-}
\ No newline at end of file