From 7f49abd5e15f68e547bf0183c20c5ca4080aa94c Mon Sep 17 00:00:00 2001 From: Accusedbold Date: Sat, 2 May 2026 17:14:40 -0400 Subject: [PATCH] starting rendering, adding web sockets --- main.py | 24 ++++---- requirements.txt | 4 +- www/background.js | 138 +++++++++++++++++++++++++++++++++++++++++++++ www/data/data.json | 1 + www/overlay.html | 16 ++++++ www/problem.js | 79 ++++++++++++++++++++++++++ www/styles.css | 32 +++++++++++ 7 files changed, 281 insertions(+), 13 deletions(-) create mode 100644 www/background.js create mode 100644 www/data/data.json create mode 100644 www/overlay.html create mode 100644 www/problem.js create mode 100644 www/styles.css diff --git a/main.py b/main.py index d286468..0dacccd 100644 --- a/main.py +++ b/main.py @@ -4,22 +4,23 @@ from problem_generator import generate_problem from steps_generator import generate_steps from sympy import init_printing, sympify +import time +import json #define the entry point to the programs def main(): init_printing(order='lex') + count = -1 no_problem = True - test=sympify('-2') - while(no_problem): - problem = generate_problem() - steps = generate_steps(problem); + + problem = generate_problem() + problem["steps"] = generate_steps(problem); - print("Generated Problem:") - print(problem) - - print("Steps:") - pretty_print_steps(steps) - no_problem = check_solution(steps[-1]["after"], problem["solution"]) + + no_problem = check_solution(problem["steps"][-1]["after"], problem["solution"]) + if no_problem: + with open("www/data/data.json", "w") as f: + json.dump(problem, f) def check_solution(got, solution): values = set([sympify(r.split("=")[1].strip()) for r in got.split(",")]) @@ -29,7 +30,6 @@ def check_solution(got, solution): solutions_list = [] solutions_list.append(sympify(solution)) solutions = set(solutions_list) - print(f"values:{values}, solutions:{solutions}") return solutions == values @@ -45,7 +45,7 @@ def pretty_print_steps(steps): for key in step: if key not in ("before", "after"): print(f"{key.capitalize()}: {step[key]}") - + print("\n" + "=" * 50) def is_iterable(obj): diff --git a/requirements.txt b/requirements.txt index 2425d3a..f0a4901 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,3 @@ -sympy \ No newline at end of file +sympy +fastapi +uvicorn \ No newline at end of file diff --git a/www/background.js b/www/background.js new file mode 100644 index 0000000..8678003 --- /dev/null +++ b/www/background.js @@ -0,0 +1,138 @@ +const canvas = document.getElementById("waveCanvas"); +const ctx = canvas.getContext("2d"); + +const pCanvas = document.getElementById("particleCanvas"); +const pctx = pCanvas.getContext("2d"); + +let t = 0; + +// Draw the left anchored Waves +function drawLeftWaves(){ + + // angle controls diagonal direction + const angle = -Math.PI * t / 10 + Math.PI * 2/5; // oscilation + + const cos = Math.cos(angle); + const sin = Math.sin(angle); + + for (let i = 0; i < 3; i++) { + ctx.beginPath(); + + let offset = i * canvas.height * (5/12); // spacing + + for (let x = 0; x < canvas.width; x += 10) { + // rotate coordinate system + let rx = x * cos; + let ry = x * sin; + + let wave = + Math.sin((rx + ry) * 0.01 + t + i) * 40 + + Math.sin((rx + ry) * 0.005 + t * 0.5) * 25; + + let y = ry + wave + offset; + + ctx.lineTo(x, y); + } + + ctx.stroke(); + } +} + +// Draw the right anchored waves +function drawRightWaves() { + + // angle controls diagonal direction + const angle = Math.PI * t / 8; // oscilation + + const cos = Math.cos(angle); + const sin = Math.sin(angle); + + for (let i = 0; i < 3; i++) { + ctx.beginPath(); + + let offset = i * canvas.height * (5/12); // spacing + + for (let x = 0; x < canvas.width; x += 10) { + // rotate coordinate system + let rx = x * cos; + let ry = x * sin; + + let wave = + -Math.sin((rx + ry) * 0.01 + t + i) * 40 - + Math.sin((rx + ry) * 0.005 + t * 0.5) * 25; + + let y = ry + wave + offset; + + ctx.lineTo(canvas.width - x, y); + } + + ctx.stroke(); + } +} + +// Draw the waves +function drawWaves() { + + ctx.clearRect(0, 0, canvas.width, canvas.height); + + // Horizontal Waves + ctx.globalAlpha = 0.15; + ctx.strokeStyle = "#ffffff"; + ctx.lineWidth = 2; + drawLeftWaves(); + + // Vertical Waves + ctx.globalAlpha = 0.12; + ctx.strokeStyle = "#ffffff"; + ctx.lineWidth = 2; + drawRightWaves() + + t += 0.01; + requestAnimationFrame(drawWaves); +} + +// Draw the particles +function drawParticles() { + pctx.clearRect(0, 0, pCanvas.width, pCanvas.height); + + pctx.fillStyle = "rgba(255,255,255,0.4)"; + + for (let p of particles) { + p.x += p.dx; + p.y += p.dy; + + if (p.x < 0) p.x = pCanvas.width; + if (p.x > pCanvas.width) p.x = 0; + if (p.y < 0) p.y = pCanvas.height; + if (p.y > pCanvas.height) p.y = 0; + + pctx.beginPath(); + pctx.arc(p.x, p.y, p.r, 0, Math.PI * 2); + pctx.fill(); + } + + requestAnimationFrame(drawParticles); +} + +// resize function +function resize() { + canvas.width = window.innerWidth; + canvas.height = window.innerHeight; + pCanvas.width = window.innerWidth; + pCanvas.height = window.innerHeight; +} + + +resize(); +// Define the particles +const particles = Array.from({ length: 80 }, () => ({ + x: Math.random() * window.innerWidth, + y: Math.random() * window.innerHeight, + r: Math.random() * 2 + 1, + dx: (Math.random() - 0.5) * 0.3, + dy: (Math.random() - 0.5) * 0.3 +})); +drawParticles(); +drawWaves(); + +window.addEventListener("resize", resize); \ No newline at end of file diff --git a/www/data/data.json b/www/data/data.json new file mode 100644 index 0000000..43d4989 --- /dev/null +++ b/www/data/data.json @@ -0,0 +1 @@ +{"type": "two_sides", "problem": "-4*x - 3 = x + 32", "solution": -7, "steps": [{"before": "-4*x - 3 = x + 32", "after": "-5*x - 3 = 32", "step": "Subtract x from both sides", "rule": "Subtraction Property of Equality"}, {"before": "-5*x - 3 = 32", "after": "-5*x = 35", "step": "Add 3 to both sides", "rule": "Addition Property of Equality"}, {"before": "-5*x = 35", "after": "x = -7", "step": "Divide both sides by -5", "rule": "Division Property of Equality"}]} \ No newline at end of file diff --git a/www/overlay.html b/www/overlay.html new file mode 100644 index 0000000..140c2b1 --- /dev/null +++ b/www/overlay.html @@ -0,0 +1,16 @@ + + + + + + + + + +
Loading...
+
+ + + + + \ No newline at end of file diff --git a/www/problem.js b/www/problem.js new file mode 100644 index 0000000..0308ecb --- /dev/null +++ b/www/problem.js @@ -0,0 +1,79 @@ +let state = "problem"; // problem | steps | done +let stepIndex = 0; +let currentData = null; + +// Load the data to draw +async function loadData() { + const res = await fetch("data/data.json"); + currentData = await res.json(); + + state = "problem"; + stepIndex = 0; + + render(); +} + +function render() { + if (!currentData) return; + + const problemEl = document.getElementById("problem"); + const stepsEl = document.getElementById("steps"); + + if (state === "problem") { + problemEl.innerHTML = `\\(${currentData.problem}\\)`; + stepsEl.innerHTML = ""; + } + + if (state === "step") { + problemEl.innerHTML = `\\(${currentData.problem}\\)`; + + let html = ""; + for (let i = 0; i <= stepIndex; i++) { + const s = currentData.steps[i]; + html += ` +
+
\\(${s.before}\\)
+
${s.step}
+
\\(${s.after}\\)
+
+
+ `; + } + + stepsEl.innerHTML = html; + } + + MathJax.typesetPromise(); +} + +function startSequence() { + // 1. show problem + state = "problem"; + render(); + + setTimeout(() => { + state = "step"; + stepIndex = 0; + render(); + + let interval = setInterval(() => { + stepIndex++; + + render(); + + if (stepIndex >= currentData.steps.length - 1) { + clearInterval(interval); + + setTimeout(() => { + loadData(); // next problem + }, 3000); + } + }, 2000); // time between steps + + }, 4000); // thinking time before reveal +} + +loadData().then(() => { + startSequence(); +}); + diff --git a/www/styles.css b/www/styles.css new file mode 100644 index 0000000..4da1c9d --- /dev/null +++ b/www/styles.css @@ -0,0 +1,32 @@ +body { + margin: 0; + height: 100vh; + overflow: hidden; + + background: linear-gradient(-45deg, #0f172a, #1e293b, #0ea5e9, #22c55e); + background-size: 400% 400%; + animation: gradientShift 12s ease infinite; + + color: white; + font-family: Arial; +} + +#waveCanvas { + position: absolute; + top: 0; + left: 0; + z-index: 0; +} + +#particleCanvas { + position: absolute; + top: 0; + left: 0; + z-index: 0; +} + +@keyframes gradientShift { + 0% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } + 100% { background-position: 0% 50%; } +} \ No newline at end of file