Fade in and fade out

This commit is contained in:
2026-05-03 20:24:24 -04:00
parent 24fed2fa7a
commit fbe46b8215
11 changed files with 178 additions and 22 deletions

BIN
www/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -1,14 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<link rel="icon" type="image/png" href="favicon.png">
<link rel="stylesheet" href="style/styles.css">
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
</head>
<body>
<canvas id="waveCanvas"></canvas>
<canvas id="particleCanvas"></canvas>
<div id="problem">Loading...</div>
<div id="steps"></div>
<div id="problem"></div>
<div id="equation"></div>
<div id="explanation"></div>
<script src="scripts/background.js"></script>
<script src="scripts/problem.js"></script>

View File

@@ -1,15 +1,55 @@
let state = "problem"; // problem | steps | done
function showProblem() {
const problemEl = document.getElementById("problem");
const stepsEl = document.getElementById("steps");
const stepsEl = document.getElementById("equation");
problemEl.innerHTML = `\\(${problemData.problem}\\)`;
const formatted = formatMath(problemData.problem);
problemEl.innerHTML = `\\(${formatted}\\)`;
stepsEl.innerHTML = "";
MathJax.typesetPromise();
}
function showStep() {
if (stepIndex >= problemData.steps.length) {
setTimeout(requestNextProblem, 3000);
return;
}
const eqEl = document.getElementById("equation");
const expEl = document.getElementById("explanation");
const step = problemData.steps[stepIndex];
expEl.innerHTML = step.step;
// STEP 1: fade out
eqEl.classList.remove("fade-in");
eqEl.classList.add("fade-out");
setTimeout(() => {
// STEP 2: update content
eqEl.innerHTML = `\\(${formatMath(step.after)}\\)`;
MathJax.typesetPromise();
// STEP 3: force reflow (CRUCIAL)
void eqEl.offsetWidth;
// STEP 4: fade back in
eqEl.classList.remove("fade-out");
eqEl.classList.add("fade-in");
stepIndex++;
setTimeout(showStep, 2000);
}, 500);
}
function startSteps() {
stepIndex = 0;
showStep();
}
function startSequence() {
setTimeout(() => {
showNextStep();
@@ -29,17 +69,19 @@ function showNextStep() {
}
const s = problemData.steps[stepIndex];
const formatted_step_before = formatMath(s.before);
const formatted_step_after = formatMath(s.after);
const html = `
<div class="step">
<div>\\(${s.before}\\)</div>
<div>${s.step}</div>
<div>\\(${s.after}\\)</div>
</div>
<hr/>
<div class="step">
<div>\\(${formatted_step_before}\\)</div>
<div>${s.step}</div>
<div>\\(${formatted_step_after}\\)</div>
</div>
`;
stepsEl.innerHTML += html;
stepsEl.innerHTML = html;
MathJax.typesetPromise();
@@ -48,3 +90,19 @@ function showNextStep() {
setTimeout(showNextStep, 2000); // time between steps
}
function formatMath(str) {
return str
.replace(/\*\*/g, "^") // Exponent Fix
.replace(/(\d+)\s*\*\s*x/g, "$1x") // 4*x -> 4x
.replace(/x\s*\*\s*(\d+)/g, "$1x") // x*4 -> 4x
.replace(/\b1x\b/g, "x") // 1x -> x
.replace(/(\d+)\s*\*\s*\(/g, "$1(") // 4*( -> 4(
.replace(/\)\s*\*\s*\(/g, ")(") // )*( -> )(
.replace(/x\s*\*\s*\(/g, "x(") // x*( -> x(
// FRACTIONS (order matters!)
.replace(/\(([^()]+)\)\s*\/\s*\(([^()]+)\)/g, "\\frac{$1}{$2}")
.replace(/\(([^()]+)\)\s*\/\s*([a-zA-Z0-9]+)/g, "\\frac{$1}{$2}")
.replace(/([a-zA-Z0-9]+)\s*\/\s*\(([^()]+)\)/g, "\\frac{$1}{$2}")
.replace(/([a-zA-Z0-9]+)\s*\/\s*([a-zA-Z0-9]+)/g, "\\frac{$1}{$2}");
}

View File

@@ -21,7 +21,7 @@ socket.onmessage = (event) => {
showProblem();
// start animation sequence
startSequence();
startSteps();
}
};

View File

@@ -1,4 +1,4 @@
body {
html, body {
margin: 0;
height: 100vh;
overflow: hidden;
@@ -11,20 +11,91 @@ body {
font-family: Arial;
}
#waveCanvas {
#problem {
position: absolute;
top: 10%;
left: 50%;
transform: translateX(-50%);
font-size: 76px;
text-align: center;
}
#equation {
position: absolute;
top: 30%;
left: 50%;
transform: translateX(-50%);
font-size: 32px;
font-family: "Comic Sans MS", cursive; /* surprisingly effective */
text-shadow:
0 0 2px rgba(255,255,255,0.8),
0 0 6px rgba(255,255,255,0.4);
transition: opacity 0.5s ease, transform 0.5s ease;
}
#explanation {
position: absolute;
top: 45%;
left: 50%;
transform: translateX(-50%);
font-size: 24px;
opacity: 0.8;
} 28px;
#steps {
position: absolute;
top: 27%; /* below the problem */
left: 50%;
transform: translateX(-50%);
width: 800px;
text-align: center;
font-size: 28px;
}
#waveCanvas {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 0;
}
#particleCanvas {
position: absolute;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 0;
}
.fade-out {
opacity: 0;
transform: translateX(-50%) scale(0.95);
}
.fade-in {
opacity: 1;
transform: translateX(-50%) scale(1);
}
.chalk-in {
opacity: 0;
transform: scale(1.05);
filter: blur(6px);
}
.chalk-in-active {
opacity: 1;
transform: scale(1);
filter: blur(0px);
transition: all 0.4s ease;
}
@keyframes gradientShift {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }