Update firecrackers, sparks, and sad faces to adapt dynamically to light/dark themes
This commit is contained in:
@@ -206,6 +206,17 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
(function(){
|
||||||
|
let isLight = false;
|
||||||
|
try {
|
||||||
|
isLight = !window.parent.document.documentElement.classList.contains('dark');
|
||||||
|
} catch (e) {
|
||||||
|
const p = new URLSearchParams(window.location.search);
|
||||||
|
isLight = p.get('theme') === 'light';
|
||||||
|
}
|
||||||
|
window.isLightTheme = isLight;
|
||||||
|
})();
|
||||||
|
|
||||||
const stage=document.getElementById('stage');
|
const stage=document.getElementById('stage');
|
||||||
const body=document.body;
|
const body=document.body;
|
||||||
const numEl=document.getElementById('number');
|
const numEl=document.getElementById('number');
|
||||||
@@ -225,9 +236,9 @@
|
|||||||
}
|
}
|
||||||
resize(); addEventListener('resize',resize);
|
resize(); addEventListener('resize',resize);
|
||||||
|
|
||||||
const SPARK=['#f6dd93','#e8c463','#d4af37','#fff4cf','#ffffff','#8fb4ff'];
|
const SPARK=window.isLightTheme?['#e28a22','#c2410c','#b45309','#78350f','#ea580c','#3b82f6']:['#f6dd93','#e8c463','#d4af37','#fff4cf','#ffffff','#8fb4ff'];
|
||||||
const CONF =['#f6dd93','#e8c463','#d4af37','#ffffff','#ffd34d'];
|
const CONF=window.isLightTheme?['#e28a22','#c2410c','#b45309','#ea580c','#ef4444','#3b82f6','#10b981']:['#f6dd93','#e8c463','#d4af37','#ffffff','#ffd34d'];
|
||||||
let parts=[], running=false, mode='fireworks', rafFW=null, fwTimers=[], fadeCol='rgba(0,0,0,0.22)';
|
let parts=[], running=false, mode='fireworks', rafFW=null, fwTimers=[], fadeCol=(window.isLightTheme ? 'rgba(255,255,255,0.22)' : 'rgba(0,0,0,0.22)');
|
||||||
|
|
||||||
function burst(xr,yr,count){
|
function burst(xr,yr,count){
|
||||||
const x=xr*W, y=yr*H, n=count|0;
|
const x=xr*W, y=yr*H, n=count|0;
|
||||||
@@ -250,11 +261,11 @@
|
|||||||
const r=p.r, s=p.s, alpha=Math.min(1,p.fi);
|
const r=p.r, s=p.s, alpha=Math.min(1,p.fi);
|
||||||
const yb=Math.sin(p.phase)*3*DPR + s*3*DPR; // gentle bob + slight downward droop
|
const yb=Math.sin(p.phase)*3*DPR + s*3*DPR; // gentle bob + slight downward droop
|
||||||
ctx.save(); ctx.translate(p.x, p.y+yb); ctx.globalAlpha=alpha;
|
ctx.save(); ctx.translate(p.x, p.y+yb); ctx.globalAlpha=alpha;
|
||||||
const line=Math.max(1.6,r*0.075), stroke='rgba(182,200,228,0.92)';
|
const line=Math.max(1.6,r*0.075), stroke=(window.isLightTheme ? 'rgba(40,60,90,0.92)' : 'rgba(182,200,228,0.92)');
|
||||||
|
|
||||||
// face
|
// face
|
||||||
ctx.beginPath(); ctx.arc(0,0,r,0,7);
|
ctx.beginPath(); ctx.arc(0,0,r,0,7);
|
||||||
ctx.fillStyle='rgba(150,175,210,0.13)'; ctx.fill();
|
ctx.fillStyle=(window.isLightTheme ? 'rgba(40,60,90,0.15)' : 'rgba(150,175,210,0.13)'); ctx.fill();
|
||||||
ctx.lineWidth=line; ctx.strokeStyle=stroke; ctx.stroke();
|
ctx.lineWidth=line; ctx.strokeStyle=stroke; ctx.stroke();
|
||||||
|
|
||||||
const ex=r*0.42, ey=-r*0.12, er=r*0.10;
|
const ex=r*0.42, ey=-r*0.12, er=r*0.10;
|
||||||
@@ -265,7 +276,7 @@
|
|||||||
ctx.beginPath(); ctx.moveTo( ex-bl*0.5, ey-r*0.30 - bl*tilt*0.6); ctx.lineTo( ex+bl*0.5, ey-r*0.30 + bl*tilt); ctx.stroke();
|
ctx.beginPath(); ctx.moveTo( ex-bl*0.5, ey-r*0.30 - bl*tilt*0.6); ctx.lineTo( ex+bl*0.5, ey-r*0.30 + bl*tilt); ctx.stroke();
|
||||||
|
|
||||||
// eyes (droopier when sadder: a lid line cuts the top)
|
// eyes (droopier when sadder: a lid line cuts the top)
|
||||||
ctx.fillStyle='rgba(205,218,238,0.95)';
|
ctx.fillStyle=(window.isLightTheme ? 'rgba(40,60,90,0.95)' : 'rgba(205,218,238,0.95)');
|
||||||
ctx.beginPath(); ctx.arc(-ex,ey,er,0,7); ctx.fill();
|
ctx.beginPath(); ctx.arc(-ex,ey,er,0,7); ctx.fill();
|
||||||
ctx.beginPath(); ctx.arc( ex,ey,er,0,7); ctx.fill();
|
ctx.beginPath(); ctx.arc( ex,ey,er,0,7); ctx.fill();
|
||||||
|
|
||||||
@@ -278,7 +289,7 @@
|
|||||||
const tears = s>0.66 ? 2 : s>0.3 ? 1 : 0;
|
const tears = s>0.66 ? 2 : s>0.3 ? 1 : 0;
|
||||||
if(tears){
|
if(tears){
|
||||||
const drop=(p.tp % 1);
|
const drop=(p.tp % 1);
|
||||||
ctx.fillStyle='rgba(150,205,244,0.92)';
|
ctx.fillStyle=(window.isLightTheme ? 'rgba(30,144,255,0.92)' : 'rgba(150,205,244,0.92)');
|
||||||
const cheeks = tears===2 ? [-ex, ex] : [-ex];
|
const cheeks = tears===2 ? [-ex, ex] : [-ex];
|
||||||
for(const cx of cheeks){
|
for(const cx of cheeks){
|
||||||
const ty=ey+er + drop*r*0.9, tr=r*0.085*(1-drop*0.35);
|
const ty=ey+er + drop*r*0.9, tr=r*0.085*(1-drop*0.35);
|
||||||
@@ -318,7 +329,7 @@
|
|||||||
function stopFw(){ fwTimers.forEach(clearTimeout); fwTimers=[]; running=false; parts=[]; if(W&&H) ctx.clearRect(0,0,W,H); }
|
function stopFw(){ fwTimers.forEach(clearTimeout); fwTimers=[]; running=false; parts=[]; if(W&&H) ctx.clearRect(0,0,W,H); }
|
||||||
|
|
||||||
function celebrate(t){ // t: 0..1 intensity
|
function celebrate(t){ // t: 0..1 intensity
|
||||||
stopFw(); parts=[]; mode='fireworks'; fadeCol='rgba(0,0,0,0.22)'; running=true;
|
stopFw(); parts=[]; mode='fireworks'; fadeCol=(window.isLightTheme ? 'rgba(255,255,255,0.22)' : 'rgba(0,0,0,0.22)'); running=true;
|
||||||
if(!rafFW) rafFW=requestAnimationFrame(tick);
|
if(!rafFW) rafFW=requestAnimationFrame(tick);
|
||||||
const rounds=Math.round(5+t*10); // 5..15
|
const rounds=Math.round(5+t*10); // 5..15
|
||||||
const gap=Math.round(345-t*155); // 345..190 ms
|
const gap=Math.round(345-t*155); // 345..190 ms
|
||||||
@@ -400,13 +411,14 @@
|
|||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
let isLight = false;
|
let isLight = false;
|
||||||
try {
|
try {
|
||||||
// In Tailwind next-themes class strategy, light mode is defined by the absence of the 'dark' class.
|
|
||||||
isLight = !window.parent.document.documentElement.classList.contains('dark');
|
isLight = !window.parent.document.documentElement.classList.contains('dark');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const p = new URLSearchParams(window.location.search);
|
const p = new URLSearchParams(window.location.search);
|
||||||
isLight = p.get('theme') === 'light';
|
isLight = p.get('theme') === 'light';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.isLightTheme = isLight;
|
||||||
|
|
||||||
if (isLight) {
|
if (isLight) {
|
||||||
document.body.style.setProperty('background', '#ffffff', 'important');
|
document.body.style.setProperty('background', '#ffffff', 'important');
|
||||||
document.documentElement.style.setProperty('background', '#ffffff', 'important');
|
document.documentElement.style.setProperty('background', '#ffffff', 'important');
|
||||||
@@ -415,6 +427,10 @@
|
|||||||
if (typeof fadeCol !== 'undefined') {
|
if (typeof fadeCol !== 'undefined') {
|
||||||
fadeCol = 'rgba(255,255,255,0.22)';
|
fadeCol = 'rgba(255,255,255,0.22)';
|
||||||
}
|
}
|
||||||
|
window.sadFaceStroke = 'rgba(40,60,90,0.92)';
|
||||||
|
window.sadFaceFill = 'rgba(40,60,90,0.15)';
|
||||||
|
window.sadFaceEyes = 'rgba(40,60,90,0.95)';
|
||||||
|
window.sadFaceTears = 'rgba(30,144,255,0.92)';
|
||||||
} else {
|
} else {
|
||||||
document.body.style.setProperty('background', '#000000', 'important');
|
document.body.style.setProperty('background', '#000000', 'important');
|
||||||
document.documentElement.style.setProperty('background', '#000000', 'important');
|
document.documentElement.style.setProperty('background', '#000000', 'important');
|
||||||
@@ -423,6 +439,10 @@
|
|||||||
if (typeof fadeCol !== 'undefined') {
|
if (typeof fadeCol !== 'undefined') {
|
||||||
fadeCol = 'rgba(0,0,0,0.22)';
|
fadeCol = 'rgba(0,0,0,0.22)';
|
||||||
}
|
}
|
||||||
|
window.sadFaceStroke = 'rgba(182,200,228,0.92)';
|
||||||
|
window.sadFaceFill = 'rgba(150,175,210,0.13)';
|
||||||
|
window.sadFaceEyes = 'rgba(205,218,238,0.95)';
|
||||||
|
window.sadFaceTears = 'rgba(150,205,244,0.92)';
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -61,11 +61,38 @@ def port_html():
|
|||||||
html = html.replace("Math.max(target,5)/5", "Math.max(target,3)/3")
|
html = html.replace("Math.max(target,5)/5", "Math.max(target,3)/3")
|
||||||
html = html.replace("(4 - target) / 3", "(3 - target) / 3")
|
html = html.replace("(4 - target) / 3", "(3 - target) / 3")
|
||||||
|
|
||||||
# Replace blue canvas trailing colors
|
# Inject theme initialization at start of script block
|
||||||
html = html.replace("'rgba(8,18,38,0.22)'", "'rgba(0,0,0,0.22)'")
|
init_theme_script = """<script>
|
||||||
html = html.replace("'rgba(10,16,23,0.3)'", "'rgba(0,0,0,0.3)'")
|
(function(){
|
||||||
html = html.replace("rgba(8,18,38,0.22)", "rgba(0,0,0,0.22)")
|
let isLight = false;
|
||||||
html = html.replace("rgba(10,16,23,0.3)", "rgba(0,0,0,0.3)")
|
try {
|
||||||
|
isLight = !window.parent.document.documentElement.classList.contains('dark');
|
||||||
|
} catch (e) {
|
||||||
|
const p = new URLSearchParams(window.location.search);
|
||||||
|
isLight = p.get('theme') === 'light';
|
||||||
|
}
|
||||||
|
window.isLightTheme = isLight;
|
||||||
|
})();
|
||||||
|
"""
|
||||||
|
html = html.replace("<script>", init_theme_script, 1)
|
||||||
|
|
||||||
|
# Make firecracker spark/confetti arrays dynamic based on theme
|
||||||
|
spark_replacement = "const SPARK=window.isLightTheme?['#e28a22','#c2410c','#b45309','#78350f','#ea580c','#3b82f6']:['#f6dd93','#e8c463','#d4af37','#fff4cf','#ffffff','#8fb4ff'];"
|
||||||
|
conf_replacement = "const CONF=window.isLightTheme?['#e28a22','#c2410c','#b45309','#ea580c','#ef4444','#3b82f6','#10b981']:['#f6dd93','#e8c463','#d4af37','#ffffff','#ffd34d'];"
|
||||||
|
html = re.sub(r"const SPARK\s*=\s*\[[^\]]*\];", spark_replacement, html)
|
||||||
|
html = re.sub(r"const CONF\s*=\s*\[[^\]]*\];", conf_replacement, html)
|
||||||
|
|
||||||
|
# Make canvas particle trail fade colors dynamic
|
||||||
|
html = html.replace("'rgba(8,18,38,0.22)'", "(window.isLightTheme ? 'rgba(255,255,255,0.22)' : 'rgba(0,0,0,0.22)')")
|
||||||
|
html = html.replace("'rgba(10,16,23,0.3)'", "(window.isLightTheme ? 'rgba(255,255,255,0.3)' : 'rgba(0,0,0,0.3)')")
|
||||||
|
html = html.replace("rgba(8,18,38,0.22)", "(window.isLightTheme ? 'rgba(255,255,255,0.22)' : 'rgba(0,0,0,0.22)')")
|
||||||
|
html = html.replace("rgba(10,16,23,0.3)", "(window.isLightTheme ? 'rgba(255,255,255,0.3)' : 'rgba(0,0,0,0.3)')")
|
||||||
|
|
||||||
|
# Make sad face outline and eye colors dynamic
|
||||||
|
html = html.replace("stroke='rgba(182,200,228,0.92)'", "stroke=(window.isLightTheme ? 'rgba(40,60,90,0.92)' : 'rgba(182,200,228,0.92)')")
|
||||||
|
html = html.replace("ctx.fillStyle='rgba(150,175,210,0.13)'", "ctx.fillStyle=(window.isLightTheme ? 'rgba(40,60,90,0.15)' : 'rgba(150,175,210,0.13)')")
|
||||||
|
html = html.replace("ctx.fillStyle='rgba(205,218,238,0.95)'", "ctx.fillStyle=(window.isLightTheme ? 'rgba(40,60,90,0.95)' : 'rgba(205,218,238,0.95)')")
|
||||||
|
html = html.replace("ctx.fillStyle='rgba(150,205,244,0.92)'", "ctx.fillStyle=(window.isLightTheme ? 'rgba(30,144,255,0.92)' : 'rgba(150,205,244,0.92)')")
|
||||||
|
|
||||||
# Replace blue root CSS variables
|
# Replace blue root CSS variables
|
||||||
html = html.replace("#081226", "#000000")
|
html = html.replace("#081226", "#000000")
|
||||||
@@ -87,13 +114,14 @@ def port_html():
|
|||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
let isLight = false;
|
let isLight = false;
|
||||||
try {
|
try {
|
||||||
// In Tailwind next-themes class strategy, light mode is defined by the absence of the 'dark' class.
|
|
||||||
isLight = !window.parent.document.documentElement.classList.contains('dark');
|
isLight = !window.parent.document.documentElement.classList.contains('dark');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const p = new URLSearchParams(window.location.search);
|
const p = new URLSearchParams(window.location.search);
|
||||||
isLight = p.get('theme') === 'light';
|
isLight = p.get('theme') === 'light';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.isLightTheme = isLight;
|
||||||
|
|
||||||
if (isLight) {
|
if (isLight) {
|
||||||
document.body.style.setProperty('background', '#ffffff', 'important');
|
document.body.style.setProperty('background', '#ffffff', 'important');
|
||||||
document.documentElement.style.setProperty('background', '#ffffff', 'important');
|
document.documentElement.style.setProperty('background', '#ffffff', 'important');
|
||||||
@@ -102,6 +130,10 @@ def port_html():
|
|||||||
if (typeof fadeCol !== 'undefined') {
|
if (typeof fadeCol !== 'undefined') {
|
||||||
fadeCol = 'rgba(255,255,255,0.22)';
|
fadeCol = 'rgba(255,255,255,0.22)';
|
||||||
}
|
}
|
||||||
|
window.sadFaceStroke = 'rgba(40,60,90,0.92)';
|
||||||
|
window.sadFaceFill = 'rgba(40,60,90,0.15)';
|
||||||
|
window.sadFaceEyes = 'rgba(40,60,90,0.95)';
|
||||||
|
window.sadFaceTears = 'rgba(30,144,255,0.92)';
|
||||||
} else {
|
} else {
|
||||||
document.body.style.setProperty('background', '#000000', 'important');
|
document.body.style.setProperty('background', '#000000', 'important');
|
||||||
document.documentElement.style.setProperty('background', '#000000', 'important');
|
document.documentElement.style.setProperty('background', '#000000', 'important');
|
||||||
@@ -110,6 +142,10 @@ def port_html():
|
|||||||
if (typeof fadeCol !== 'undefined') {
|
if (typeof fadeCol !== 'undefined') {
|
||||||
fadeCol = 'rgba(0,0,0,0.22)';
|
fadeCol = 'rgba(0,0,0,0.22)';
|
||||||
}
|
}
|
||||||
|
window.sadFaceStroke = 'rgba(182,200,228,0.92)';
|
||||||
|
window.sadFaceFill = 'rgba(150,175,210,0.13)';
|
||||||
|
window.sadFaceEyes = 'rgba(205,218,238,0.95)';
|
||||||
|
window.sadFaceTears = 'rgba(150,205,244,0.92)';
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
})();
|
})();
|
||||||
|
|||||||
Reference in New Issue
Block a user