Spaces:
Paused
Paused
Commit ·
f03da5c
1
Parent(s): 3625de9
feat: Add full 4-hero Avengers V-Formation animation engine and sprite endpoints
Browse files- main.py +9 -0
- web_ui/index.html +44 -17
main.py
CHANGED
|
@@ -128,6 +128,15 @@ async def serve_cap() -> FileResponse:
|
|
| 128 |
raise HTTPException(status_code=404, detail="Captain America image missing")
|
| 129 |
|
| 130 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 131 |
@app.get("/health", response_class=JSONResponse)
|
| 132 |
async def health_check() -> Dict[str, Any]:
|
| 133 |
"""Health check reporting system and index readiness."""
|
|
|
|
| 128 |
raise HTTPException(status_code=404, detail="Captain America image missing")
|
| 129 |
|
| 130 |
|
| 131 |
+
@app.get("/spider_gwen.png")
|
| 132 |
+
async def serve_spider_gwen() -> FileResponse:
|
| 133 |
+
"""Serve Spider-Gwen sprite image."""
|
| 134 |
+
img_path = config.BASE_DIR / "web_ui" / "spider_gwen.png"
|
| 135 |
+
if img_path.exists():
|
| 136 |
+
return FileResponse(img_path)
|
| 137 |
+
raise HTTPException(status_code=404, detail="Spider-Gwen image missing")
|
| 138 |
+
|
| 139 |
+
|
| 140 |
@app.get("/health", response_class=JSONResponse)
|
| 141 |
async def health_check() -> Dict[str, Any]:
|
| 142 |
"""Health check reporting system and index readiness."""
|
web_ui/index.html
CHANGED
|
@@ -1429,8 +1429,26 @@
|
|
| 1429 |
let mainIronmanLoaded = false;
|
| 1430 |
mainIronmanImg.onload = () => { mainIronmanLoaded = true; };
|
| 1431 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1432 |
let mainImX = -220;
|
| 1433 |
const mainThrusterParticles = [];
|
|
|
|
|
|
|
|
|
|
| 1434 |
|
| 1435 |
function drawMainPageIronMan() {
|
| 1436 |
if (!mainCanvas || !mainCtx) return;
|
|
@@ -1755,26 +1773,35 @@
|
|
| 1755 |
mainCtx.restore();
|
| 1756 |
}
|
| 1757 |
|
| 1758 |
-
|
| 1759 |
-
|
| 1760 |
-
|
| 1761 |
-
|
| 1762 |
-
|
| 1763 |
-
|
| 1764 |
-
|
| 1765 |
-
capImg.onload = () => { capLoaded = true; };
|
| 1766 |
|
| 1767 |
-
|
| 1768 |
-
|
|
|
|
|
|
|
|
|
|
| 1769 |
|
| 1770 |
-
|
| 1771 |
-
|
| 1772 |
-
|
| 1773 |
-
|
| 1774 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1775 |
|
| 1776 |
-
|
| 1777 |
-
|
| 1778 |
|
| 1779 |
function drawLightningArc(c, x1, y1, x2, y2, roughness = 14) {
|
| 1780 |
const dx = x2 - x1;
|
|
|
|
| 1429 |
let mainIronmanLoaded = false;
|
| 1430 |
mainIronmanImg.onload = () => { mainIronmanLoaded = true; };
|
| 1431 |
|
| 1432 |
+
const thorImg = new Image();
|
| 1433 |
+
thorImg.src = "/thor.png";
|
| 1434 |
+
let thorLoaded = false;
|
| 1435 |
+
thorImg.onload = () => { thorLoaded = true; };
|
| 1436 |
+
|
| 1437 |
+
const capImg = new Image();
|
| 1438 |
+
capImg.src = "/cap.png";
|
| 1439 |
+
let capLoaded = false;
|
| 1440 |
+
capImg.onload = () => { capLoaded = true; };
|
| 1441 |
+
|
| 1442 |
+
const gwenImg = new Image();
|
| 1443 |
+
gwenImg.src = "/spider_gwen.png";
|
| 1444 |
+
let gwenLoaded = false;
|
| 1445 |
+
gwenImg.onload = () => { gwenLoaded = true; };
|
| 1446 |
+
|
| 1447 |
let mainImX = -220;
|
| 1448 |
const mainThrusterParticles = [];
|
| 1449 |
+
const thorSparks = [];
|
| 1450 |
+
const capSparks = [];
|
| 1451 |
+
const gwenParticles = [];
|
| 1452 |
|
| 1453 |
function drawMainPageIronMan() {
|
| 1454 |
if (!mainCanvas || !mainCtx) return;
|
|
|
|
| 1773 |
mainCtx.restore();
|
| 1774 |
}
|
| 1775 |
|
| 1776 |
+
// ==========================================
|
| 1777 |
+
// DRAW SPIDER-GWEN FLYING (Center Tail Wing of Avengers V-Formation)
|
| 1778 |
+
// ==========================================
|
| 1779 |
+
const gwenX = mainImX - 410;
|
| 1780 |
+
const gwenY = baseLeaderY;
|
| 1781 |
+
const gwenW = 150;
|
| 1782 |
+
const gwenH = 220;
|
|
|
|
| 1783 |
|
| 1784 |
+
if (gwenLoaded) {
|
| 1785 |
+
mainCtx.save();
|
| 1786 |
+
mainCtx.filter = "brightness(1.4) contrast(1.25) saturate(1.3) drop-shadow(0 0 20px rgba(255, 0, 150, 0.95))";
|
| 1787 |
+
mainCtx.drawImage(gwenImg, gwenX, gwenY, gwenW, gwenH);
|
| 1788 |
+
mainCtx.restore();
|
| 1789 |
|
| 1790 |
+
// Luminous Neon Web Aura Flare
|
| 1791 |
+
mainCtx.save();
|
| 1792 |
+
const webGrad = mainCtx.createRadialGradient(gwenX + gwenW * 0.5, gwenY + gwenH * 0.4, 0, gwenX + gwenW * 0.5, gwenY + gwenH * 0.4, 24);
|
| 1793 |
+
webGrad.addColorStop(0, "rgba(255, 255, 255, 0.95)");
|
| 1794 |
+
webGrad.addColorStop(0.4, "rgba(255, 0, 150, 0.85)");
|
| 1795 |
+
webGrad.addColorStop(1, "rgba(255, 0, 150, 0)");
|
| 1796 |
+
mainCtx.fillStyle = webGrad;
|
| 1797 |
+
mainCtx.beginPath();
|
| 1798 |
+
mainCtx.arc(gwenX + gwenW * 0.5, gwenY + gwenH * 0.4, 24, 0, Math.PI * 2);
|
| 1799 |
+
mainCtx.fill();
|
| 1800 |
+
mainCtx.restore();
|
| 1801 |
+
}
|
| 1802 |
|
| 1803 |
+
requestAnimationFrame(drawMainPageIronMan);
|
| 1804 |
+
}
|
| 1805 |
|
| 1806 |
function drawLightningArc(c, x1, y1, x2, y2, roughness = 14) {
|
| 1807 |
const dx = x2 - x1;
|