Skip to content

Commit

Permalink
feat: ✨ Animation is now connected to slider, but doesnt fully work. …
Browse files Browse the repository at this point in the history
…Some bugs and improvements necessary.

#3
  • Loading branch information
jmnorheim committed Aug 10, 2024
1 parent 29416b4 commit c421d69
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -1,29 +1,65 @@
import React, { useState } from "react";
import React, { useState, useEffect } from "react";
import "./AlgorithmStepSlider.css";
import { algorithmStepSliderSignal } from "../../pages/homePage/HomePage";
import {
clearPreviousAnimations,
renderStep,
} from "../../services/animationService"; // Import the clear function and renderStep

const AlgorithmStepSlider = () => {
const [size, setSize] = useState<number>(algorithmStepSliderSignal.value);
const [size, setSize] = useState<number>(
algorithmStepSliderSignal.value.currentValue
);

const handleSliderChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setSize(parseInt(e.target.value));
const newValue = parseInt(e.target.value);
setSize(newValue);

// Create a copy of the signal and update currentValue
const updatedSignal = { ...algorithmStepSliderSignal.value };
updatedSignal.currentValue = newValue;
algorithmStepSliderSignal.value = updatedSignal;

// Abort the ongoing animation
clearPreviousAnimations();

// Render the specific step based on the slider value
renderStep(newValue);
};

const handleCommitChange = () => {
console.log("Size = ", size);
algorithmStepSliderSignal.value = size;
const updatedSignal = { ...algorithmStepSliderSignal.value };
updatedSignal.currentValue = size;
algorithmStepSliderSignal.value = updatedSignal;
};

useEffect(() => {
// Dynamically update the slider's max value based on the signal's max value
const slider = document.getElementById("myRange") as HTMLInputElement;
console.log("Slider = ", slider);
if (slider) {
slider.max = algorithmStepSliderSignal.value.max.toString();
slider.min = algorithmStepSliderSignal.value.min.toString();
}
}, [algorithmStepSliderSignal.value.max]);

useEffect(() => {
console.log(
"AlgorithmStepSliderSignal = ",
algorithmStepSliderSignal.value
);
}, [algorithmStepSliderSignal.value]);

return (
<div className="algorithm-step-slider-container">
<label htmlFor="myRange" className="slider-label">
Adjust step
</label>
<input
type="range"
min="0"
max="50"
value={size}
min={algorithmStepSliderSignal.value.min}
max={algorithmStepSliderSignal.value.max}
value={algorithmStepSliderSignal.value.currentValue}
className="slider"
id="myRange"
onChange={handleSliderChange}
Expand Down
8 changes: 7 additions & 1 deletion frontend/src/pages/homePage/HomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,16 @@ import AnimationSpeedSlider from "../../components/animationStepSlider/Animation

export const mapSizeSliderSignal = signal<number>(50);
export const animationSpeed = signal<number>(1);
export const algorithmStepSliderSignal = signal<number>(0);
// export const algorithmStepSliderSignal = signal<number>(0);
export const selectedAlgorithm = signal<string>("");
export const selectedHeuristic = signal<string>("");

export const algorithmStepSliderSignal = signal({
currentValue: 0,
min: 0,
max: 0,
});

const HomePage = () => {
//TODO: Make a global colors.css-file and import this in the CSS instead

Expand Down
58 changes: 46 additions & 12 deletions frontend/src/services/animationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import {
selectedAlgorithm,
selectedHeuristic,
animationSpeed,
algorithmStepSliderSignal,
} from "../pages/homePage/HomePage";
import { PostTraversalProps, PostTraversalResponse } from "../types";
import { postTraversal } from "./postTraversal";
import { Node } from "../types";

let timeoutIds: number[] = [];
let nodeOrder: Node[] = [];

export const handleTraverse = () => {
console.log("Traversing the grid");
Expand All @@ -34,10 +36,18 @@ export const handleTraverse = () => {
try {
// Parse the path and nodeOrder JSON strings into arrays
const parsedPath: Node[] = JSON.parse(res.path);
const parsedNodeOrder: Node[] = JSON.parse(res.nodeOrder);
nodeOrder = JSON.parse(res.nodeOrder); // Store nodeOrder for later use
console.log("NodeOrder = ", nodeOrder);

// Create a copy of the signal and update min, max, and currentValue
const updatedSignal = { ...algorithmStepSliderSignal.value };
updatedSignal.currentValue = 0;
updatedSignal.min = 0;
updatedSignal.max = nodeOrder.length - 1;
algorithmStepSliderSignal.value = updatedSignal;

// Animate node exploration
animateNodeOrder(parsedNodeOrder, () => {
animateNodeOrder(nodeOrder, () => {
// After node exploration, animate the path
animatePath(parsedPath);
});
Expand All @@ -50,28 +60,52 @@ export const handleTraverse = () => {
.catch((err) => console.log(err));
};

const clearPreviousAnimations = () => {
export const clearPreviousAnimations = () => {
// Clear all timeouts stored in the timeoutIds array
timeoutIds.forEach(clearTimeout);
timeoutIds = []; // Reset the array
};

// Function to render a specific step
export const renderStep = (step: number) => {
tiles.value = tiles.value.map((tile) => {
const node = nodeOrder[step];
if (node && tile.x === node.x && tile.y === node.y) {
return { ...tile, isPath: false, isExplored: true }; // Mark as explored up to the specified step
}
return tile;
});
};

// Function to animate the nodeOrder
const animateNodeOrder = (nodeOrder: Node[], callback: () => void) => {
const delay = 10 / (animationSpeed.value * 100); // Calculate delay based on steps per second

nodeOrder.forEach((node, index) => {
const timeoutId = setTimeout(() => {
tiles.value = tiles.value.map((tile) => {
if (tile.x === node.x && tile.y === node.y) {
return { ...tile, isPath: false, isExplored: true }; // Mark as explored
}
return tile;
});
// Check if the current index matches the slider value
if (index === algorithmStepSliderSignal.value.currentValue) {
tiles.value = tiles.value.map((tile) => {
if (tile.x === node.x && tile.y === node.y) {
return { ...tile, isPath: false, isExplored: true }; // Mark as explored
}
return tile;
});

// If this is the last node, call the callback to start animating the path
if (index === nodeOrder.length - 1) {
callback();
// Increment the algorithm step slider signal
const updatedSignal = { ...algorithmStepSliderSignal.value };
updatedSignal.currentValue += 1;
algorithmStepSliderSignal.value = updatedSignal;

console.log(
"Current value: ",
algorithmStepSliderSignal.value.currentValue
);

// If this is the last node, call the callback to start animating the path
if (index === nodeOrder.length - 1) {
callback();
}
}
}, index * delay); // Apply calculated delay

Expand Down

0 comments on commit c421d69

Please sign in to comment.