sisyphus-progressbar
Version:
A animated progress bar inspired by the myth of Sisyphus, featuring physics-based animations and philosophical quotes
239 lines (227 loc) • 26.5 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var jsxRuntime = require('react/jsx-runtime');
var react = require('react');
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __spreadArray(to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
}
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
var SisyphusProgressBar = function (_a) {
var externalProgress = _a.progress, _b = _a.showPercentage, showPercentage = _b === void 0 ? true : _b;
var _c = react.useState(50), internalProgress = _c[0], setInternalProgress = _c[1];
var _d = react.useState({
boulderPosition: 50,
sisyphusPosition: 50,
boulderVelocity: 0,
targetPosition: 50,
phase: 'normal', // 'normal', 'chasing', 'pushing'
animationPhase: 0,
rollTarget: 0,
}), physicsState = _d[0], setPhysicsState = _d[1];
// State for the rotating quotes
var _e = react.useState(0), quoteIndex = _e[0], setQuoteIndex = _e[1];
var quoteRotationIntervalRef = react.useRef(null);
var animationRef = react.useRef();
var lastTimeRef = react.useRef(Date.now());
var progress = externalProgress !== undefined ? externalProgress : internalProgress;
// Authentic quotes from or inspired by "The Myth of Sisyphus"
var quotes = [
"The struggle itself toward the heights is enough to fill a man's heart.",
"There is no fate that cannot be surmounted by scorn.",
"The gods had thought with some reason that there is no more dreadful punishment than futile and hopeless labor.",
"He was superior to his fate. He was stronger than his rock.",
"His fate belongs to him. His rock is his thing.",
"I leave Sisyphus at the foot of the mountain! One always finds one's burden again.",
"The lucidity that was to constitute his torture at the same time crowns his victory."
];
// Physics constants
var PHYSICS = {
gravity: 120,
friction: 0.98,
chaseSpeed: 80,
pushSpeed: 25,
moveSpeed: 40,
initialVelocity: 20,
rollAmount: 35, // The amount the boulder rolls down when progress is decreased manually
};
var getDisplayProgress = react.useCallback(function (sisyphusPos) {
var maxProgress = 95 + (sisyphusPos / 100) * 4.9;
return Math.min(Math.max(0, sisyphusPos), maxProgress);
}, []);
var getPosition = react.useCallback(function (prog) {
var position = Math.max(0, Math.min(100, prog)) / 100;
return {
x: 10 + (position * 60),
y: 95 - (position * 30)
};
}, []);
// Update target when progress changes
react.useEffect(function () {
setPhysicsState(function (prev) { return (__assign(__assign({}, prev), { targetPosition: progress })); });
}, [progress]);
// Effect for rotating quotes when stagnant
react.useEffect(function () {
// Don't run this logic if the loader is controlled externally.
if (externalProgress !== undefined) {
if (quoteRotationIntervalRef.current)
clearInterval(quoteRotationIntervalRef.current);
return;
}
// Clear previous interval on each interaction to reset the timer
if (quoteRotationIntervalRef.current) {
clearInterval(quoteRotationIntervalRef.current);
}
// Set a new interval that rotates the quote every minute
quoteRotationIntervalRef.current = setInterval(function () {
setQuoteIndex(function (prevIndex) { return (prevIndex + 1) % quotes.length; });
}, 60000); // 1 minute
// Cleanup on unmount
return function () {
if (quoteRotationIntervalRef.current) {
clearInterval(quoteRotationIntervalRef.current);
}
};
}, [internalProgress, externalProgress, quotes.length]); // Re-runs on interaction, resetting the interval.
// Effect for random boulder drops
react.useEffect(function () {
if (externalProgress !== undefined)
return;
var randomDropInterval = setInterval(function () {
setPhysicsState(function (prev) {
// Only trigger a random drop if Sisyphus is in a stable state and not at the very bottom.
if (prev.phase === 'normal' && prev.boulderPosition > 20) {
var randomDropAmount = Math.floor(Math.random() * 16) + 5; // Drop between 5% and 20%
var newRollTarget = Math.max(0, prev.boulderPosition - randomDropAmount);
return __assign(__assign({}, prev), { phase: 'chasing', boulderVelocity: PHYSICS.initialVelocity, rollTarget: newRollTarget });
}
return prev;
});
}, 30000); // Approximately 2 times a minute
return function () { return clearInterval(randomDropInterval); };
}, [externalProgress, PHYSICS.initialVelocity]);
// Main physics animation loop
react.useEffect(function () {
var animate = function () {
var currentTime = Date.now();
var deltaTime = Math.min((currentTime - lastTimeRef.current) / 1000, 0.033); // Cap at ~30fps
lastTimeRef.current = currentTime;
setPhysicsState(function (prev) {
var boulderPosition = prev.boulderPosition, sisyphusPosition = prev.sisyphusPosition, boulderVelocity = prev.boulderVelocity, targetPosition = prev.targetPosition, phase = prev.phase, animationPhase = prev.animationPhase;
var newState = __assign(__assign({}, prev), { animationPhase: (animationPhase + 1) % 1000 });
switch (phase) {
case 'chasing': {
var rollTarget = prev.rollTarget;
if (boulderPosition > rollTarget) {
var newVelocity = boulderVelocity + PHYSICS.gravity * deltaTime;
var dampedVelocity = newVelocity * PHYSICS.friction;
var newBoulderPos = Math.max(rollTarget, boulderPosition - dampedVelocity * deltaTime);
var newSisyphusPos = sisyphusPosition;
if (sisyphusPosition > newBoulderPos + 5) {
newSisyphusPos = Math.max(newBoulderPos + 5, sisyphusPosition - PHYSICS.chaseSpeed * deltaTime);
}
return __assign(__assign({}, newState), { boulderPosition: newBoulderPos, sisyphusPosition: newSisyphusPos, boulderVelocity: dampedVelocity });
}
else {
return __assign(__assign({}, newState), { phase: 'pushing', boulderPosition: rollTarget, sisyphusPosition: rollTarget, boulderVelocity: 0 });
}
}
case 'pushing': {
if (boulderPosition < targetPosition) {
var moveAmount = PHYSICS.pushSpeed * deltaTime;
var newPos = Math.min(targetPosition, boulderPosition + moveAmount);
return __assign(__assign({}, newState), { boulderPosition: newPos, sisyphusPosition: newPos });
}
else {
return __assign(__assign({}, newState), { phase: 'normal', boulderPosition: targetPosition, sisyphusPosition: targetPosition, boulderVelocity: 0 });
}
}
default: { // 'normal'
var distanceToTarget = Math.abs(boulderPosition - targetPosition);
if (distanceToTarget > 0.1) {
var direction = targetPosition > boulderPosition ? 1 : -1;
if (direction < 0) {
var newRollTarget = Math.max(0, boulderPosition - PHYSICS.rollAmount);
return __assign(__assign({}, newState), { phase: 'chasing', boulderVelocity: PHYSICS.initialVelocity, rollTarget: newRollTarget });
}
var moveAmount = PHYSICS.moveSpeed * deltaTime;
var newPos = boulderPosition + direction * moveAmount;
return __assign(__assign({}, newState), { boulderPosition: newPos, sisyphusPosition: newPos });
}
return __assign(__assign({}, newState), { boulderPosition: targetPosition, sisyphusPosition: targetPosition });
}
}
});
animationRef.current = requestAnimationFrame(animate);
};
animationRef.current = requestAnimationFrame(animate);
return function () {
if (animationRef.current) {
cancelAnimationFrame(animationRef.current);
}
};
}, []);
var displayProgress = getDisplayProgress(physicsState.sisyphusPosition);
var sisyphusPos = getPosition(physicsState.sisyphusPosition);
var boulderPos = getPosition(physicsState.boulderPosition);
var isChasing = physicsState.phase === 'chasing';
var isPushing = physicsState.phase === 'pushing';
var struggleOffset = isPushing ? Math.sin(physicsState.animationPhase / 8) * 0.8 : Math.sin(physicsState.animationPhase / 10) * 0.5;
var sisyphusX = sisyphusPos.x + struggleOffset;
var sisyphusY = sisyphusPos.y - Math.abs(Math.sin(physicsState.animationPhase / 10)) * 0.3;
var boulderRotation = physicsState.boulderPosition * 7.2 + (isChasing ? physicsState.animationPhase * 5 : physicsState.animationPhase * 0.5);
var legSpeed = isChasing ? 15 : isPushing ? 30 : 40;
var isLeftLegForward = (physicsState.animationPhase % legSpeed) < legSpeed / 2;
var currentQuote = quotes[quoteIndex];
return (jsxRuntime.jsxs("div", { className: "w-full max-w-md mx-auto p-4 space-y-4 font-sans", role: "progressbar", "aria-valuenow": displayProgress, "aria-valuemin": 0, "aria-valuemax": 100, children: [jsxRuntime.jsxs("div", { className: "relative h-40 bg-amber-50 rounded-lg overflow-hidden shadow-2xl", children: [jsxRuntime.jsx("div", { className: "absolute inset-0 border-4 border-amber-700 rounded-lg pointer-events-none", children: jsxRuntime.jsxs("svg", { className: "absolute inset-0 w-full h-full", viewBox: "0 0 100 100", preserveAspectRatio: "none", children: [jsxRuntime.jsx("defs", { children: jsxRuntime.jsxs("pattern", { id: "greekKey", x: "0", y: "0", width: "10", height: "10", patternUnits: "userSpaceOnUse", children: [jsxRuntime.jsx("path", { d: "M 0 0 L 0 5 L 2 5 L 2 2 L 5 2 L 5 0 Z", fill: "none", stroke: "#92400E", strokeWidth: "0.5" }), jsxRuntime.jsx("path", { d: "M 5 0 L 8 0 L 8 3 L 10 3 L 10 0", fill: "none", stroke: "#92400E", strokeWidth: "0.5" }), jsxRuntime.jsx("path", { d: "M 10 5 L 8 5 L 8 8 L 5 8 L 5 10 L 10 10", fill: "none", stroke: "#92400E", strokeWidth: "0.5" }), jsxRuntime.jsx("path", { d: "M 0 10 L 0 7 L 2 7 L 2 10", fill: "none", stroke: "#92400E", strokeWidth: "0.5" })] }) }), jsxRuntime.jsx("rect", { x: "2", y: "2", width: "96", height: "8", fill: "url(#greekKey)", opacity: "0.3" }), jsxRuntime.jsx("rect", { x: "2", y: "90", width: "96", height: "8", fill: "url(#greekKey)", opacity: "0.3" })] }) }), jsxRuntime.jsxs("div", { className: "absolute inset-0 bg-gradient-to-b from-amber-100 via-orange-50 to-amber-50", children: [jsxRuntime.jsxs("svg", { className: "absolute top-4 right-4 w-12 h-12", children: [jsxRuntime.jsx("circle", { cx: "24", cy: "24", r: "10", fill: "#FFA500", opacity: "0.8" }), __spreadArray([], Array(8), true).map(function (_, i) { return (jsxRuntime.jsx("line", { x1: "24", y1: "24", x2: 24 + 20 * Math.cos((i * Math.PI) / 4), y2: 24 + 20 * Math.sin((i * Math.PI) / 4), stroke: "#FFA500", strokeWidth: "1", opacity: "0.4" }, i)); })] }), jsxRuntime.jsx("svg", { className: "absolute inset-0 w-full h-full", viewBox: "0 0 100 100", children: __spreadArray([], Array(3), true).map(function (_, i) {
var orbitRadiusX = 20 + i * 7;
var orbitRadiusY = 6 + i * 2;
var speed = 0.5 + i * 0.15;
var centerX = 50;
var centerY = 22;
var phaseOffset = i * 150;
var angle = (physicsState.animationPhase * speed + phaseOffset) * (Math.PI / 180);
var x = centerX + Math.cos(angle) * orbitRadiusX;
var y = centerY + Math.sin(angle) * orbitRadiusY;
var perspectiveFactor = (Math.sin(angle) + 1) / 2;
var scale = 0.6 + perspectiveFactor * 0.4;
var opacity = 0.7 + perspectiveFactor * 0.3;
return (jsxRuntime.jsxs("g", { transform: "translate(".concat(x, ", ").concat(y, ") scale(").concat(scale, ")"), opacity: opacity, children: [jsxRuntime.jsx("ellipse", { cx: "0", cy: "0", rx: "2", ry: "1.2", fill: "#2F4F4F" }), jsxRuntime.jsx("path", { d: "M -2 0 Q -3.5 -0.8 -4 0 Q -3.5 0.8 -2 0", fill: "#2F4F4F", opacity: "0.8", children: jsxRuntime.jsx("animate", { attributeName: "d", values: "M -2 0 Q -3.5 -0.8 -4 0 Q -3.5 0.8 -2 0;M -2 0 Q -3.5 -1.5 -4 0 Q -3.5 0.2 -2 0;M -2 0 Q -3.5 -0.8 -4 0 Q -3.5 0.8 -2 0", dur: "1s", repeatCount: "indefinite" }) }), jsxRuntime.jsx("path", { d: "M 2 0 Q 3.5 -0.8 4 0 Q 3.5 0.8 2 0", fill: "#2F4F4F", opacity: "0.8", children: jsxRuntime.jsx("animate", { attributeName: "d", values: "M 2 0 Q 3.5 -0.8 4 0 Q 3.5 0.8 2 0;M 2 0 Q 3.5 -1.5 4 0 Q 3.5 0.2 2 0;M 2 0 Q 3.5 -0.8 4 0 Q 3.5 0.8 2 0", dur: "1s", repeatCount: "indefinite" }) }), jsxRuntime.jsx("circle", { cx: "-1.5", cy: "0", r: "0.4", fill: "#8B4513" })] }, i));
}) })] }), jsxRuntime.jsxs("svg", { className: "absolute inset-0 w-full h-full", viewBox: "0 0 100 100", preserveAspectRatio: "none", children: [jsxRuntime.jsx("defs", { children: jsxRuntime.jsxs("pattern", { id: "marble", x: "0", y: "0", width: "20", height: "20", patternUnits: "userSpaceOnUse", children: [jsxRuntime.jsx("rect", { width: "20", height: "20", fill: "#D4A373" }), jsxRuntime.jsx("path", { d: "M 0 5 Q 10 3 20 5", stroke: "#C19660", strokeWidth: "0.5", fill: "none", opacity: "0.5" }), jsxRuntime.jsx("path", { d: "M 0 15 Q 10 13 20 15", stroke: "#C19660", strokeWidth: "0.5", fill: "none", opacity: "0.5" }), jsxRuntime.jsx("circle", { cx: "5", cy: "10", r: "1", fill: "#B8956A", opacity: "0.3" }), jsxRuntime.jsx("circle", { cx: "15", cy: "7", r: "0.5", fill: "#B8956A", opacity: "0.3" })] }) }), jsxRuntime.jsx("path", { d: "M 0 100 L 85 50 L 100 48 L 100 100 Z", fill: "url(#marble)", stroke: "#8B6914", strokeWidth: "1" }), jsxRuntime.jsx("path", { d: "M 10 95 Q 30 85 50 70 T 85 53", stroke: "#F5DEB3", strokeWidth: "3", fill: "none", opacity: "0.6" })] }), jsxRuntime.jsxs("svg", { className: "absolute left-2 bottom-0 w-8 h-16", viewBox: "0 0 20 40", children: [jsxRuntime.jsx("rect", { x: "4", y: "5", width: "12", height: "30", fill: "#DDD", stroke: "#AAA", strokeWidth: "0.5" }), jsxRuntime.jsx("rect", { x: "2", y: "0", width: "16", height: "5", fill: "#DDD", stroke: "#AAA", strokeWidth: "0.5" }), jsxRuntime.jsx("rect", { x: "2", y: "35", width: "16", height: "5", fill: "#DDD", stroke: "#AAA", strokeWidth: "0.5" }), __spreadArray([], Array(4), true).map(function (_, i) { return (jsxRuntime.jsx("line", { x1: 6 + i * 3, y1: "5", x2: 6 + i * 3, y2: "35", stroke: "#AAA", strokeWidth: "0.3" }, i)); })] }), jsxRuntime.jsx("svg", { className: "absolute inset-0 w-full h-full", viewBox: "0 0 100 100", children: jsxRuntime.jsx("g", { transform: "translate(".concat(boulderPos.x, ", ").concat(boulderPos.y - 7, ")"), children: jsxRuntime.jsxs("g", { transform: "rotate(".concat(boulderRotation, " 0 0)"), children: [jsxRuntime.jsx("circle", { cx: "0", cy: "0", r: "7", fill: "#8B7D6B", stroke: "#5D4E37", strokeWidth: "0.8" }), jsxRuntime.jsx("path", { d: "M -3 -3 L -1 0 L -3 3", stroke: "#5D4E37", strokeWidth: "0.3", fill: "none" }), jsxRuntime.jsx("path", { d: "M 2 -4 L 3 -1 L 1 2", stroke: "#5D4E37", strokeWidth: "0.3", fill: "none" }), jsxRuntime.jsx("circle", { cx: "-2", cy: "-2", r: "1.5", fill: "#6B5D54", opacity: "0.4" }), jsxRuntime.jsx("circle", { cx: "2", cy: "1", r: "1", fill: "#6B5D54", opacity: "0.4" })] }) }) }), jsxRuntime.jsxs("svg", { className: "absolute inset-0 w-full h-full", viewBox: "0 0 100 100", children: [jsxRuntime.jsx("g", { transform: "translate(".concat(sisyphusX, ", ").concat(sisyphusY, ")"), children: jsxRuntime.jsxs("g", { transform: "translate(-10, -3) scale(1) rotate(".concat(isChasing ? 5 : isPushing ? -10 : -struggleOffset * 2, " 0 0)"), children: [jsxRuntime.jsx("ellipse", { cx: "0", cy: "8", rx: "4", ry: "1", fill: "#000", opacity: "0.2" }), jsxRuntime.jsxs("g", { transform: "rotate(".concat(isLeftLegForward ? -15 : 15, " -1 3)"), children: [jsxRuntime.jsx("path", { d: "M -1 3 L -3 6 L -3 8", stroke: "#D4A373", strokeWidth: "1.8", strokeLinecap: "round", fill: "none" }), jsxRuntime.jsx("circle", { cx: "-3", cy: "8", r: "1", fill: "#8B4513" })] }), jsxRuntime.jsx("ellipse", { cx: "0", cy: "0", rx: 3 + Math.sin(physicsState.animationPhase / (isPushing ? 8 : 20)) * 0.2, ry: "4", fill: "#D4A373" }), jsxRuntime.jsx("path", { d: "M -3 -2 L 3 -2 L 2.5 4 L -2.5 4 Z", fill: "#FFF", opacity: "0.9" }), jsxRuntime.jsx("path", { d: "M -3 -2 L -2.5 4", stroke: "#DDD", strokeWidth: "0.3" }), jsxRuntime.jsx("path", { d: "M 3 -2 L 2.5 4", stroke: "#DDD", strokeWidth: "0.3" }), jsxRuntime.jsx("path", { d: "M -2 0 L 2 0", stroke: "#E6E6E6", strokeWidth: "0.2" }), jsxRuntime.jsx("path", { d: "M -2 2 L 2 2", stroke: "#E6E6E6", strokeWidth: "0.2" }), isChasing ? (jsxRuntime.jsxs("g", { children: [jsxRuntime.jsx("path", { d: "M 2 -1 Q 0 ".concat(isLeftLegForward ? -2 : 0, " -2 ").concat(isLeftLegForward ? -1 : 1), stroke: "#D4A373", strokeWidth: "1.8", strokeLinecap: "round", fill: "none" }), jsxRuntime.jsx("path", { d: "M 2 1 Q 4 ".concat(isLeftLegForward ? 0 : 2, " 5 ").concat(isLeftLegForward ? 1 : -1), stroke: "#D4A373", strokeWidth: "1.8", strokeLinecap: "round", fill: "none" })] })) : (jsxRuntime.jsxs("g", { transform: "rotate(".concat(isPushing ? -5 : Math.sin(physicsState.animationPhase / 15) * 3, " 2 0)"), children: [jsxRuntime.jsx("path", { d: "M 2 -1 Q 5 -1.5 8 -2", stroke: "#D4A373", strokeWidth: "1.8", strokeLinecap: "round", fill: "none" }), jsxRuntime.jsx("path", { d: "M 2 1 Q 5 0.5 8 0", stroke: "#D4A373", strokeWidth: "1.8", strokeLinecap: "round", fill: "none" }), jsxRuntime.jsx("circle", { cx: "4", cy: "-1", r: "0.5", fill: "#C19660", opacity: "0.3" }), jsxRuntime.jsx("circle", { cx: "4", cy: "0.5", r: "0.5", fill: "#C19660", opacity: "0.3" })] })), jsxRuntime.jsxs("g", { transform: "rotate(".concat(!isLeftLegForward ? -15 : 15, " 1 3)"), children: [jsxRuntime.jsx("path", { d: "M 1 3 L 2 6 L 2 8", stroke: "#D4A373", strokeWidth: "1.8", strokeLinecap: "round", fill: "none" }), jsxRuntime.jsx("circle", { cx: "2", cy: "8", r: "1", fill: "#8B4513" })] }), jsxRuntime.jsxs("g", { transform: "translate(0, ".concat(Math.sin(physicsState.animationPhase / 10) * 0.2, ")"), children: [jsxRuntime.jsx("circle", { cx: "0", cy: "-5", r: "2.5", fill: "#D4A373" }), jsxRuntime.jsx("path", { d: "M -2.5 -6.5 Q 0 -7.5 2.5 -6.5", fill: "#2F4F4F" }), jsxRuntime.jsx("path", { d: "M -2 -5 Q -2.5 -3 -2 -3", fill: "#2F4F4F" }), jsxRuntime.jsx("path", { d: "M 2 -5 Q 2.5 -3 2 -3", fill: "#2F4F4F" }), jsxRuntime.jsx("path", { d: "M -1.5 -3.5 Q 0 -2.5 1.5 -3.5", fill: "#2F4F4F", opacity: "0.7" }), jsxRuntime.jsx("path", { d: "M -2.5 -6 Q -2 -7 0 -7.2 Q 2 -7 2.5 -6", stroke: "#228B22", strokeWidth: "0.5", fill: "none" }), jsxRuntime.jsx("ellipse", { cx: "-2", cy: "-6.5", rx: "0.3", ry: "0.5", fill: "#228B22", transform: "rotate(-30 -2 -6.5)" }), jsxRuntime.jsx("ellipse", { cx: "2", cy: "-6.5", rx: "0.3", ry: "0.5", fill: "#228B22", transform: "rotate(30 2 -6.5)" }), jsxRuntime.jsx("circle", { cx: "-0.7", cy: "-5", r: "0.2", fill: "#000" }), jsxRuntime.jsx("circle", { cx: "0.7", cy: "-5", r: "0.2", fill: "#000" }), jsxRuntime.jsx("path", { d: "M -0.5 -4.3 Q 0 ".concat(-4 + (isChasing ? -0.3 : isPushing ? 0.2 : Math.sin(physicsState.animationPhase / 8) * 0.1), " 0.5 -4.3"), stroke: "#000", strokeWidth: "0.1", fill: "none" })] }), (isPushing || physicsState.phase === 'normal') && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: "M 3 -6 L 4 -7", stroke: "#FFD700", strokeWidth: "0.3", opacity: 0.6 + Math.sin(physicsState.animationPhase / 5) * 0.3 }), jsxRuntime.jsx("path", { d: "M 3.5 -4 L 4.5 -4", stroke: "#FFD700", strokeWidth: "0.3", opacity: 0.6 + Math.sin(physicsState.animationPhase / 7) * 0.3 }), isPushing && (jsxRuntime.jsx("path", { d: "M 3 -2 L 4 -1", stroke: "#FFD700", strokeWidth: "0.3", opacity: 0.6 + Math.sin(physicsState.animationPhase / 6) * 0.3 }))] }))] }) }), (displayProgress > 30 || isPushing) && !isChasing && (jsxRuntime.jsxs("circle", { cx: sisyphusX - 10, cy: sisyphusY - 8, r: "0.8", fill: "#4682B4", opacity: "0.6", children: [jsxRuntime.jsx("animate", { attributeName: "cy", from: sisyphusY - 8, to: sisyphusY + 10, dur: "1.5s", repeatCount: "indefinite" }), jsxRuntime.jsx("animate", { attributeName: "opacity", from: "0.6", to: "0", dur: "1.5s", repeatCount: "indefinite" })] })), (displayProgress > 60 || isPushing) && !isChasing && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("circle", { cx: sisyphusX - 8, cy: sisyphusY - 10, r: "0.6", fill: "#4682B4", opacity: "0.6", children: [jsxRuntime.jsx("animate", { attributeName: "cy", from: sisyphusY - 10, to: sisyphusY + 8, dur: "1.8s", repeatCount: "indefinite" }), jsxRuntime.jsx("animate", { attributeName: "opacity", from: "0.6", to: "0", dur: "1.8s", repeatCount: "indefinite" })] }), jsxRuntime.jsxs("circle", { cx: sisyphusX - 12, cy: sisyphusY - 6, r: "0.7", fill: "#4682B4", opacity: "0.6", children: [jsxRuntime.jsx("animate", { attributeName: "cy", from: sisyphusY - 6, to: sisyphusY + 12, dur: "2s", repeatCount: "indefinite" }), jsxRuntime.jsx("animate", { attributeName: "opacity", from: "0.6", to: "0", dur: "2s", repeatCount: "indefinite" })] })] })), __spreadArray([], Array(3), true).map(function (_, i) { return (jsxRuntime.jsx("circle", { cx: sisyphusX - 5 + i * 2, cy: sisyphusY + 7, r: "0.3", fill: "#D4A373", opacity: Math.sin(physicsState.animationPhase / (isChasing ? 3 : 10) + i) * 0.3 + 0.2 }, i)); }), isChasing && (jsxRuntime.jsx("text", { x: sisyphusX - 15, y: sisyphusY - 15, fontSize: "4", fill: "#8B4513", fontWeight: "bold", children: "!!!" }))] }), showPercentage && (jsxRuntime.jsxs("div", { className: "absolute bottom-3 right-3 text-sm font-bold text-amber-800 bg-amber-100 px-2 py-1 rounded border border-amber-600", children: [displayProgress.toFixed(1), "%"] })), currentQuote && displayProgress < 95 && (jsxRuntime.jsx("div", { className: "absolute top-2 left-4 right-4 text-center", children: jsxRuntime.jsxs("div", { className: "text-xs text-amber-900 italic bg-amber-50 bg-opacity-80 p-2 rounded-md shadow", children: ["\"", currentQuote, "\""] }) })), displayProgress >= 95 && (jsxRuntime.jsx("div", { className: "absolute top-4 left-4 right-4 text-center", children: jsxRuntime.jsx("div", { className: "text-sm text-amber-900 font-serif italic", children: "\"One must imagine Sisyphus happy.\"" }) }))] }), externalProgress === undefined && (jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsxs("label", { className: "text-sm font-medium text-gray-700", children: ["Progress Control: ", internalProgress, "%"] }), jsxRuntime.jsx("input", { type: "range", min: "0", max: "100", value: internalProgress, onChange: function (e) { return setInternalProgress(Number(e.target.value)); }, className: "w-full h-2 bg-amber-200 rounded-lg appearance-none cursor-pointer", style: {
background: "linear-gradient(to right, #D97706 0%, #D97706 ".concat(internalProgress, "%, #FED7AA ").concat(internalProgress, "%, #FED7AA 100%)")
} }), jsxRuntime.jsxs("div", { className: "flex justify-between text-xs text-gray-600", children: [jsxRuntime.jsx("span", { children: "0%" }), jsxRuntime.jsx("span", { children: "25%" }), jsxRuntime.jsx("span", { children: "50%" }), jsxRuntime.jsx("span", { children: "75%" }), jsxRuntime.jsx("span", { children: "100%" })] })] }))] }));
};
exports.SisyphusProgressBar = SisyphusProgressBar;
exports.default = SisyphusProgressBar;
//# sourceMappingURL=index.js.map