Skip to content

Commit f63a207

Browse files
Implement Modular Bridge Effects for LCARS theme
- Add 'lcars-effect-zone' to top-left bracket in lcars-frame.html - Create library of CSS-only diagnostics: starmap, histogram, waveform, orbital - Implement slide-specific effect switching in slidedown.js via metadata - Add '.effect' slide modifier to compiler for easy diagnostic selection - Sync all Starfleet bridge animations
1 parent b9f0512 commit f63a207

4 files changed

Lines changed: 159 additions & 1 deletion

File tree

assets/js/slidedown.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,28 @@ Page.prototype = {
778778
DOMID_currentSlide.style.display = "none";
779779
DOMID_followingSlide.style.display = "block";
780780

781+
// --- Bridge Effect Update ---
782+
let effectZone = document.getElementById('lcars-bridge-effect');
783+
if (effectZone) {
784+
// Clear current effect
785+
effectZone.innerHTML = '';
786+
787+
// Look for slide-specific effect metadata
788+
let effectMeta = document.getElementById(this.str_slideIDprefix + index_followingSlide + '-effect');
789+
let effectName = effectMeta ? effectMeta.innerHTML.trim() : 'starmap';
790+
791+
if (effectName === 'starmap') {
792+
effectZone.innerHTML = '<div class="effect-starmap"></div>';
793+
} else if (effectName === 'histogram') {
794+
effectZone.innerHTML = '<div class="effect-histogram"><div></div><div></div><div></div><div></div><div></div></div>';
795+
} else if (effectName === 'waveform') {
796+
effectZone.innerHTML = '<div class="effect-waveform"></div>';
797+
} else if (effectName === 'orbital') {
798+
effectZone.innerHTML = '<div class="effect-orbital"></div>';
799+
}
800+
}
801+
// ----------------------------
802+
781803
// Reset ALL typewriters on the slide we're entering
782804
this.resetAllTypewritersOnSlide(index_followingSlide);
783805

src/lib/directives.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,16 @@ def slide_handler(node: Any, compiler: Any) -> str:
121121
# Generate watermarks from theme config
122122
watermarks_html = compiler.watermarks_generate()
123123

124+
# Extract effect from slide modifiers (e.g., .slide{.effect{histogram}})
125+
slide_effect = node.modifiers.get('effect', 'starmap')
126+
124127
return f"""
125128
<div id="slide-{slide_num}-title" style="display: none;">
126129
{title_content}
127130
</div>
131+
<div id="slide-{slide_num}-effect" style="display: none;">
132+
{slide_effect}
133+
</div>
128134
<div class="{css_classes}" id="slide-{slide_num}" name="slide-{slide_num}" {style_attr}>
129135
{watermarks_html}
130136
{content}
@@ -574,6 +580,14 @@ def syntax_handler(node: Any, compiler: Any) -> str:
574580
"""Should never be called - .syntax{} extracted by parser"""
575581
return ""
576582

583+
self.register(DirectiveSpec(
584+
name='effect',
585+
category=DirectiveCategory.MODIFIER,
586+
description='Bridge animation for LCARS theme',
587+
handler=style_handler,
588+
examples=['.slide{.effect{histogram}}']
589+
))
590+
577591
self.register(DirectiveSpec(
578592
name='syntax',
579593
category=DirectiveCategory.MODIFIER,

themes/lcars-lower-decks/templates/lcars-frame.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<div class="wrap">
44
<div class="scroll-top"><a id="scroll-top" href="#" onclick="scrollToTop(); return false;"><span class="hop">screen</span> top</a></div>
55
<div class="left-frame-top" id="top-frame">
6-
<div class="panel-1"><span id="lcars-date"></span> <span class="hop" id="lcars-time"></span></div>
6+
<div class="panel-1" id="lcars-effect-zone"><div class="lcars-diagnostic-header"><span id="lcars-date"></span></div><div id="lcars-bridge-effect"></div></div>
77
<div class="panel-2">SLIDE <span class="hop navbar-counter" data-template="{{current}} / {{total}}">1 / {slide_count}</span></div>
88
</div>
99
<div class="right-frame-top">
@@ -48,6 +48,7 @@
4848
</div>
4949
<main>
5050
{content}
51+
<div id="slide-{slide_num}-effect" style="display:none;">{slide_effect}</div>
5152
</main>
5253
</div>
5354
</div>

themes/lcars-lower-decks/theme.css

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2234,3 +2234,124 @@ body {
22342234
.lcars-pulse div:nth-child(4) { animation-delay: 0.6s; }
22352235

22362236
/* ---------------------------- */
2237+
2238+
/* --- Modular Bridge Effects Library --- */
2239+
2240+
#lcars-effect-zone {
2241+
display: flex;
2242+
flex-direction: column;
2243+
justify-content: center;
2244+
align-items: center;
2245+
padding: 5px !important;
2246+
overflow: hidden;
2247+
}
2248+
2249+
.lcars-diagnostic-header {
2250+
font-size: 0.8rem;
2251+
color: #f91;
2252+
margin-bottom: 4px;
2253+
letter-spacing: 1px;
2254+
}
2255+
2256+
#lcars-bridge-effect {
2257+
width: 100%;
2258+
height: 100%;
2259+
display: flex;
2260+
justify-content: center;
2261+
align-items: center;
2262+
}
2263+
2264+
/* 1. Star Map Effect */
2265+
.effect-starmap {
2266+
width: 80px;
2267+
height: 40px;
2268+
position: relative;
2269+
background: radial-gradient(circle, #fff 1px, transparent 1px);
2270+
background-size: 20px 20px;
2271+
animation: stars-drift 20s linear infinite;
2272+
}
2273+
2274+
.effect-starmap::before {
2275+
content: '';
2276+
position: absolute;
2277+
width: 100%;
2278+
height: 100%;
2279+
background: radial-gradient(circle, #f91 1px, transparent 1px);
2280+
background-size: 15px 15px;
2281+
animation: stars-drift 15s linear reverse infinite;
2282+
}
2283+
2284+
@keyframes stars-drift {
2285+
from { background-position: 0 0; }
2286+
to { background-position: 100% 100%; }
2287+
}
2288+
2289+
/* 2. Histogram Effect */
2290+
.effect-histogram {
2291+
display: flex;
2292+
gap: 2px;
2293+
align-items: flex-end;
2294+
height: 30px;
2295+
}
2296+
2297+
.effect-histogram div {
2298+
width: 4px;
2299+
background: #fc9;
2300+
animation: hist-pulse 1.2s infinite ease-in-out;
2301+
}
2302+
2303+
@keyframes hist-pulse {
2304+
0%, 100% { height: 30%; }
2305+
50% { height: 90%; }
2306+
}
2307+
2308+
/* 3. Waveform Effect */
2309+
.effect-waveform {
2310+
width: 60px;
2311+
height: 20px;
2312+
border-bottom: 2px solid #f91;
2313+
position: relative;
2314+
overflow: hidden;
2315+
}
2316+
2317+
.effect-waveform::after {
2318+
content: '';
2319+
position: absolute;
2320+
width: 200%;
2321+
height: 100%;
2322+
background: repeating-linear-gradient(90deg, transparent, transparent 10px, #f91 10px, #f91 12px);
2323+
animation: wave-slide 2s linear infinite;
2324+
}
2325+
2326+
@keyframes wave-slide {
2327+
from { left: 0; }
2328+
to { left: -50%; }
2329+
}
2330+
2331+
/* 4. Molecule/Orbital Effect */
2332+
.effect-orbital {
2333+
width: 30px;
2334+
height: 30px;
2335+
border: 2px solid #fc9;
2336+
border-radius: 50%;
2337+
position: relative;
2338+
animation: rotate 4s linear infinite;
2339+
}
2340+
2341+
.effect-orbital::after {
2342+
content: '';
2343+
position: absolute;
2344+
width: 6px;
2345+
height: 6px;
2346+
background: #f91;
2347+
border-radius: 50%;
2348+
top: -4px;
2349+
left: 12px;
2350+
}
2351+
2352+
@keyframes rotate {
2353+
from { transform: rotate(0deg); }
2354+
to { transform: rotate(360deg); }
2355+
}
2356+
2357+
/* -------------------------------------- */

0 commit comments

Comments
 (0)