diff --git a/gabau.github.io/src/components/games/SortVisualizer.tsx b/gabau.github.io/src/components/games/SortVisualizer.tsx
new file mode 100644
index 0000000..9741797
--- /dev/null
+++ b/gabau.github.io/src/components/games/SortVisualizer.tsx
@@ -0,0 +1,59 @@
+import { Stage } from "@pixi/react";
+import { Graphics as GraphicComponent } from "@pixi/react";
+import { Color, Graphics } from "pixi.js";
+import { useCallback, useContext } from "react";
+import ThemeContext from "../../context/ThemeContext";
+
+const sortingColor = {
+ dark: {
+ bgColor: new Color("black"),
+ barColor: new Color("green"),
+ selectedColor: new Color("white")
+ },
+ light: {
+ bgColor: new Color("white"),
+ barColor: new Color("black"),
+ selectedColor: new Color("grey")
+ }
+}
+
+const SortVisualizer: React.FC<{
+ values: number[],
+ currentPosition: number,
+ width: number,
+ height: number,
+ base_offset?: number,
+ gap?: number
+}> = ({ gap, values, width, height, currentPosition, base_offset }) => {
+ const {theme} = useContext(ThemeContext);
+ const currColors = theme === "dark" ? sortingColor.dark : sortingColor.light;
+ const m = base_offset ? base_offset : 100;
+ const draw = useCallback((g: Graphics) => {
+ g.clear();
+ g.beginFill(currColors.bgColor);
+ g.drawRect(0, 0, width, height);
+ // render each of the values in the item
+ let max_val = values[0];
+ let min_val = values[0];
+ for (const v of values) {
+ max_val = Math.max(v, max_val);
+ min_val = Math.min(v, min_val);
+ }
+ const w = width / values.length;
+
+ const gapWrapper = gap ? gap : 0.5 * w;
+ for (let i = 0; i < values.length; ++i) {
+ const perc = Math.round( (values[i] - min_val) / (max_val - min_val) * (height - m)) + m;
+ g.beginFill(currColors.barColor);
+ if (currentPosition === i) {
+ g.beginFill(currColors.selectedColor);
+ }
+ g.drawRect(i*w, height - perc, w - gapWrapper, perc);
+ }
+ }, [currColors.bgColor, currColors.barColor, currColors.selectedColor, width, height, values, gap, m, currentPosition]);
+ return
+
+
+}
+
+export default SortVisualizer;
\ No newline at end of file
diff --git a/gabau.github.io/src/components/layouts/CenteredDivLayout.tsx b/gabau.github.io/src/components/layouts/CenteredDivLayout.tsx
new file mode 100644
index 0000000..51f645a
--- /dev/null
+++ b/gabau.github.io/src/components/layouts/CenteredDivLayout.tsx
@@ -0,0 +1,11 @@
+
+
+export default function CenteredDivLayout({ children }: {
+ children: JSX.Element | string
+}) {
+ return
+}
diff --git a/gabau.github.io/src/pages/Playground.tsx b/gabau.github.io/src/pages/Playground.tsx
index 2a93f1c..9d67359 100644
--- a/gabau.github.io/src/pages/Playground.tsx
+++ b/gabau.github.io/src/pages/Playground.tsx
@@ -1,5 +1,6 @@
import { Link } from "react-router-dom";
import TypeWriterHeader from "../components/TypeWriterHeader";
+import { playgroundRoutes } from "../routes/playground";
const PlayGroundCard = ({
title,
@@ -29,33 +30,6 @@ const PlayGroundCard = ({
// };
// }
-const playgrounds = [
- {
- title: "Terminal",
- description: "Simple terminal that runs in the browser",
- link: "/play/terminal",
- },
- {
- title: "A Page",
- description: "Just a page",
- link: "/play/apage",
- },
- {
- title: "Repeating text",
- description: "Simple repeating animation",
- link: "/play/rotating",
- },
- {
- title: "Animated Sand",
- description: "Simple sand falling in pixi.js",
- link: "/play/sand",
- },
- {
- title: "Pong",
- description: "Pong game",
- link: "/play/pong",
- },
-];
export default function PlayGround() {
return (
@@ -63,13 +37,13 @@ export default function PlayGround() {
For the miscellaneous stuff
- {playgrounds.map((v) => {
+ {playgroundRoutes.map((v) => {
return (
);
})}
diff --git a/gabau.github.io/src/pages/fun/SortVisPage.tsx b/gabau.github.io/src/pages/fun/SortVisPage.tsx
new file mode 100644
index 0000000..734028e
--- /dev/null
+++ b/gabau.github.io/src/pages/fun/SortVisPage.tsx
@@ -0,0 +1,193 @@
+import { useEffect, useState } from "react";
+import SortVisualizer from "../../components/games/SortVisualizer";
+import CenteredDivLayout from "../../components/layouts/CenteredDivLayout";
+
+// stores the states for partition sort
+class PartitionSortState {
+ partitions: { start: number; end: number }[];
+ currPos: number;
+ frontPointer: number;
+ start: number;
+ end: number;
+ constructor() {
+ this.partitions = [];
+ this.currPos = 0;
+ this.frontPointer = 0;
+ this.start = 0;
+ this.end = 0;
+ }
+
+ swap(values: number[], i: number, j: number) {
+ if (i >= values.length || j >= values.length) return;
+ const tmp = values[i];
+ values[i] = values[j];
+ values[j] = tmp;
+ }
+
+ getNextStep(values: number[]) {
+ if (
+ this.currPos >= this.end ||
+ this.frontPointer >= this.end ||
+ this.start >= this.end
+ ) {
+ // push the current partitions onto the stack
+ if (this.start < this.end) {
+ if (this.frontPointer !== this.end) {
+ this.partitions.push({
+ start: this.start,
+ end: this.frontPointer,
+ });
+ }
+ if (this.start !== this.frontPointer + 1) {
+ this.partitions.push({
+ start: this.frontPointer + 1,
+ end: this.end,
+ });
+ }
+ }
+
+ // console.log(values);
+ // return "finished"
+ // reset the position to the partitions
+ // Finshed sorting
+ if (this.partitions.length === 0) {
+ return "finished";
+ }
+ this.currPos = this.partitions[0].start + 1;
+ this.frontPointer = this.partitions[0].start;
+ this.end = this.partitions[0].end;
+ this.start = this.frontPointer;
+ this.partitions = this.partitions.slice(1);
+ }
+
+ // if (values[this.frontPointer] > values[this.frontPointer + 1]) {
+ // this.swap(values, this.frontPointer, this.frontPointer + 1);
+ // this.frontPointer += 1;
+ // this.currPos = Math.max(this.frontPointer + 1, this.currPos);
+ // return values;
+ // }
+ if (values[this.currPos] <= values[this.frontPointer]) {
+ this.swap(values, this.currPos, this.frontPointer + 1);
+ this.swap(values, this.frontPointer, this.frontPointer + 1);
+ this.frontPointer += 1;
+ }
+ this.currPos += 1;
+ return values;
+ }
+}
+
+export default function SortVisPage() {
+ const [values, setValues] = useState
([4, 0]);
+ const [partSort] = useState(new PartitionSortState());
+ const [startAnim, setStartAnim] = useState(false);
+ const [currPosition, setCurrPosition] = useState(0);
+ const [arraySize, setArraySize] = useState(40);
+ const [animating, setAnimating] = useState(false);
+ const [intervalTime, setIntervalTime] = useState(10);
+ const [currTimeout, setCurrTimeout] = useState(null);
+ useEffect(() => {
+ setValues(Array.from({ length: 40 }, () => Math.floor(Math.random() * 40)));
+ }, []);
+
+ useEffect(() => {
+ if (!startAnim) return;
+ partSort.start = 0;
+ partSort.end = values.length;
+ partSort.frontPointer = 0;
+ partSort.currPos = 1;
+ const f = () => {
+ if (!animating) return;
+ const r = partSort.getNextStep(values);
+ if (r === "finished") {
+ setAnimating(false);
+ return;
+ }
+ setCurrPosition(partSort.currPos);
+ setCurrTimeout(setTimeout(f, intervalTime));
+ };
+ const t = setTimeout(f, intervalTime);
+ return () => clearTimeout(t);
+ }, [partSort, startAnim, values, animating, intervalTime]);
+
+ return (
+
+
+
+ );
+}
diff --git a/gabau.github.io/src/routes.tsx b/gabau.github.io/src/routes.tsx
index 7284dbd..00e9f11 100644
--- a/gabau.github.io/src/routes.tsx
+++ b/gabau.github.io/src/routes.tsx
@@ -6,12 +6,7 @@ import About from "./pages/About";
import Chess from "./components/games/Chess";
import PlayGround from "./pages/Playground";
import NavBarWrapper from "./components/NavBarWrapper";
-import Terminal from "./components/Terminal";
-import TypeWriterHeader from "./components/TypeWriterHeader";
-import APage from "./pages/fun/APage";
-import RepeatingBannerPage from "./pages/fun/RepeatingBannerPage";
-import AnimatedSandPage from "./pages/fun/AnimatedSandPage";
-import PongPage from "./pages/fun/PongPage";
+import { playgroundRoutes } from "./routes/playground";
const routes = [
{
@@ -45,60 +40,7 @@ const routes = [
},
{
path: "/play",
- children: [
- {
- path: "terminal",
- element: (
-
-
-
Basic unix-like terminal. No persistant storage
-
-
- ),
- },
- {
- path: "apage",
- element: (
-
- ),
- },
- {
- path: "rotating",
- element: ,
- },
- {
- path: "sand",
- element: ,
- },
- {
- path: "pong",
- element:
- },
- ],
+ children: playgroundRoutes,
},
],
},
diff --git a/gabau.github.io/src/routes/playground.tsx b/gabau.github.io/src/routes/playground.tsx
new file mode 100644
index 0000000..5db6b98
--- /dev/null
+++ b/gabau.github.io/src/routes/playground.tsx
@@ -0,0 +1,76 @@
+import Terminal from "../components/Terminal";
+import TypeWriterHeader from "../components/TypeWriterHeader";
+import AnimatedSandPage from "../pages/fun/AnimatedSandPage";
+import APage from "../pages/fun/APage";
+import PongPage from "../pages/fun/PongPage";
+import RepeatingBannerPage from "../pages/fun/RepeatingBannerPage";
+import SortVisPage from "../pages/fun/SortVisPage";
+
+export const playgroundRoutes = [
+ {
+ path: "terminal",
+ title: "Terminal",
+ description: "Simple terminal that runs in the browser",
+ element: (
+
+
+
Basic unix-like terminal. No persistant storage
+
+
+ ),
+ },
+ {
+ path: "apage",
+ title: "A page",
+ description: "Just a page",
+ element: (
+
+ ),
+ },
+ {
+ path: "rotating",
+ title: "Repeating Text",
+ description: "Simple repeating Text",
+ element: ,
+ },
+ {
+ path: "sand",
+ title: "Sand",
+ description: "Simple sand falling in pixi.js",
+ element: ,
+ },
+ {
+ path: "pong",
+ title: "Pong",
+ description: "Pong game",
+ element: ,
+ },
+ {
+ path: "sort",
+ title: "Sort visualisation",
+ description: "Simple sorting visualisation of quick sort. It is pure quick sort which makes it slow on sorted array",
+ element:
+ }
+];
+
+
diff --git a/gabau.github.io/tsconfig.app.tsbuildinfo b/gabau.github.io/tsconfig.app.tsbuildinfo
index 89df9d6..5b96dbd 100644
--- a/gabau.github.io/tsconfig.app.tsbuildinfo
+++ b/gabau.github.io/tsconfig.app.tsbuildinfo
@@ -1 +1 @@
-{"root":["./src/app.tsx","./src/errorpage.tsx","./src/main.tsx","./src/routes.tsx","./src/vite-env.d.ts","./src/components/codeblock.tsx","./src/components/modalmanager.tsx","./src/components/moonsuntoggle.tsx","./src/components/navbar.tsx","./src/components/navbarwrapper.tsx","./src/components/terminal.tsx","./src/components/typewriterheader.tsx","./src/components/animated/fuzzytext.tsx","./src/components/animated/repeatingbanner.tsx","./src/components/games/animatedsand.tsx","./src/components/games/chess.tsx","./src/components/games/pong.tsx","./src/context/modalcontext.ts","./src/context/themecontext.ts","./src/hooks/usemodals.ts","./src/pages/about.tsx","./src/pages/contact.tsx","./src/pages/playground.tsx","./src/pages/projects.tsx","./src/pages/root.tsx","./src/pages/fun/apage.tsx","./src/pages/fun/animatedsandpage.tsx","./src/pages/fun/pongpage.tsx","./src/pages/fun/repeatingbannerpage.tsx","./src/types/modals.d.ts","./src/types/themes.d.ts","./src/types/virtfile.d.ts"],"version":"5.6.2"}
\ No newline at end of file
+{"root":["./src/app.tsx","./src/errorpage.tsx","./src/main.tsx","./src/routes.tsx","./src/vite-env.d.ts","./src/components/codeblock.tsx","./src/components/modalmanager.tsx","./src/components/moonsuntoggle.tsx","./src/components/navbar.tsx","./src/components/navbarwrapper.tsx","./src/components/terminal.tsx","./src/components/typewriterheader.tsx","./src/components/animated/fuzzytext.tsx","./src/components/animated/repeatingbanner.tsx","./src/components/games/animatedsand.tsx","./src/components/games/chess.tsx","./src/components/games/pong.tsx","./src/components/games/sortvisualizer.tsx","./src/components/layouts/centereddivlayout.tsx","./src/context/modalcontext.ts","./src/context/themecontext.ts","./src/hooks/usemodals.ts","./src/pages/about.tsx","./src/pages/contact.tsx","./src/pages/playground.tsx","./src/pages/projects.tsx","./src/pages/root.tsx","./src/pages/fun/apage.tsx","./src/pages/fun/animatedsandpage.tsx","./src/pages/fun/pongpage.tsx","./src/pages/fun/repeatingbannerpage.tsx","./src/pages/fun/sortvispage.tsx","./src/routes/playground.tsx","./src/types/modals.d.ts","./src/types/themes.d.ts","./src/types/virtfile.d.ts"],"version":"5.6.2"}
\ No newline at end of file