trama-ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CATALOG.md +1237 -0
- package/LICENSE +21 -0
- package/README.md +78 -0
- package/THIRD-PARTY.md +4 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/brown.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/brown_inlay.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/brown_pressed.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/grey.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/grey_inlay.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/grey_pressed.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/tan.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/tan_inlay.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/tan_pressed.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/white.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/white_inlay.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/white_pressed.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Colored/blue.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Colored/blue_pressed.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Colored/green.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Colored/green_pressed.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Colored/grey.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Colored/grey_pressed.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Colored/red.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Colored/red_pressed.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Colored/yellow.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Colored/yellow_pressed.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Outline/blue.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Outline/blue_pressed.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Outline/green.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Outline/green_pressed.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Outline/red.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Outline/red_pressed.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Outline/yellow.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/Outline/yellow_pressed.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/list.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/space.png +0 -0
- package/assets/pixel/kenney-pixel-ui/9-slice/space_inlay.png +0 -0
- package/assets/pixel/kenney-pixel-ui/License.txt +23 -0
- package/assets/pixel/kenney-pixel-ui/spritesheet/sheet.png +0 -0
- package/bin/trama-ui.mjs +27 -0
- package/dist/components/ui/Accordion.d.ts +12 -0
- package/dist/components/ui/Accordion.js +12 -0
- package/dist/components/ui/Alert.d.ts +15 -0
- package/dist/components/ui/Alert.js +15 -0
- package/dist/components/ui/ArticlesSection.d.ts +30 -0
- package/dist/components/ui/ArticlesSection.js +18 -0
- package/dist/components/ui/AsciiBackground.d.ts +58 -0
- package/dist/components/ui/AsciiBackground.js +173 -0
- package/dist/components/ui/AsciiCard.d.ts +78 -0
- package/dist/components/ui/AsciiCard.js +253 -0
- package/dist/components/ui/AsciiChart.d.ts +18 -0
- package/dist/components/ui/AsciiChart.js +47 -0
- package/dist/components/ui/Badge.d.ts +15 -0
- package/dist/components/ui/Badge.js +8 -0
- package/dist/components/ui/BitmapText.d.ts +25 -0
- package/dist/components/ui/BitmapText.js +21 -0
- package/dist/components/ui/BlogCard.d.ts +33 -0
- package/dist/components/ui/BlogCard.js +13 -0
- package/dist/components/ui/Breadcrumbs.d.ts +9 -0
- package/dist/components/ui/Breadcrumbs.js +7 -0
- package/dist/components/ui/Button.d.ts +74 -0
- package/dist/components/ui/Button.js +48 -0
- package/dist/components/ui/CTASection.d.ts +13 -0
- package/dist/components/ui/CTASection.js +7 -0
- package/dist/components/ui/Carousel.d.ts +30 -0
- package/dist/components/ui/Carousel.js +80 -0
- package/dist/components/ui/CheckboxGroup.d.ts +11 -0
- package/dist/components/ui/CheckboxGroup.js +20 -0
- package/dist/components/ui/CodeBlock.d.ts +11 -0
- package/dist/components/ui/CodeBlock.js +20 -0
- package/dist/components/ui/ContactForm.d.ts +25 -0
- package/dist/components/ui/ContactForm.js +26 -0
- package/dist/components/ui/CrtOverlay.d.ts +10 -0
- package/dist/components/ui/CrtOverlay.js +5 -0
- package/dist/components/ui/Divider.d.ts +12 -0
- package/dist/components/ui/Divider.js +7 -0
- package/dist/components/ui/Drawer.d.ts +16 -0
- package/dist/components/ui/Drawer.js +25 -0
- package/dist/components/ui/Dropdown.d.ts +10 -0
- package/dist/components/ui/Dropdown.js +21 -0
- package/dist/components/ui/FAQSection.d.ts +14 -0
- package/dist/components/ui/FAQSection.js +7 -0
- package/dist/components/ui/FeatureGrid.d.ts +18 -0
- package/dist/components/ui/FeatureGrid.js +14 -0
- package/dist/components/ui/Footer.d.ts +14 -0
- package/dist/components/ui/Footer.js +16 -0
- package/dist/components/ui/GlyphCursor.d.ts +22 -0
- package/dist/components/ui/GlyphCursor.js +50 -0
- package/dist/components/ui/GridBackground.d.ts +15 -0
- package/dist/components/ui/GridBackground.js +6 -0
- package/dist/components/ui/Hero.d.ts +21 -0
- package/dist/components/ui/Hero.js +12 -0
- package/dist/components/ui/HoverFX.d.ts +29 -0
- package/dist/components/ui/HoverFX.js +75 -0
- package/dist/components/ui/Icon.d.ts +33 -0
- package/dist/components/ui/Icon.js +29 -0
- package/dist/components/ui/ImageGallery.d.ts +31 -0
- package/dist/components/ui/ImageGallery.js +79 -0
- package/dist/components/ui/LogoCloud.d.ts +12 -0
- package/dist/components/ui/LogoCloud.js +9 -0
- package/dist/components/ui/MagneticButton.d.ts +12 -0
- package/dist/components/ui/MagneticButton.js +49 -0
- package/dist/components/ui/Marquee.d.ts +29 -0
- package/dist/components/ui/Marquee.js +15 -0
- package/dist/components/ui/Modal.d.ts +40 -0
- package/dist/components/ui/Modal.js +51 -0
- package/dist/components/ui/NavBar.d.ts +14 -0
- package/dist/components/ui/NavBar.js +12 -0
- package/dist/components/ui/NeonSign.d.ts +14 -0
- package/dist/components/ui/NeonSign.js +7 -0
- package/dist/components/ui/OtpInput.d.ts +9 -0
- package/dist/components/ui/OtpInput.js +27 -0
- package/dist/components/ui/Pagination.d.ts +10 -0
- package/dist/components/ui/Pagination.js +24 -0
- package/dist/components/ui/Panel.d.ts +21 -0
- package/dist/components/ui/Panel.js +8 -0
- package/dist/components/ui/PixelFrame.d.ts +61 -0
- package/dist/components/ui/PixelFrame.js +29 -0
- package/dist/components/ui/Presence.d.ts +51 -0
- package/dist/components/ui/Presence.js +343 -0
- package/dist/components/ui/PricingCard.d.ts +30 -0
- package/dist/components/ui/PricingCard.js +21 -0
- package/dist/components/ui/PricingSection.d.ts +35 -0
- package/dist/components/ui/PricingSection.js +21 -0
- package/dist/components/ui/Progress.d.ts +17 -0
- package/dist/components/ui/Progress.js +9 -0
- package/dist/components/ui/RadioGroup.d.ts +10 -0
- package/dist/components/ui/RadioGroup.js +11 -0
- package/dist/components/ui/RangeSlider.d.ts +14 -0
- package/dist/components/ui/RangeSlider.js +11 -0
- package/dist/components/ui/Reveal.d.ts +48 -0
- package/dist/components/ui/Reveal.js +181 -0
- package/dist/components/ui/SceneFlash.d.ts +14 -0
- package/dist/components/ui/SceneFlash.js +51 -0
- package/dist/components/ui/ScrambleText.d.ts +31 -0
- package/dist/components/ui/ScrambleText.js +51 -0
- package/dist/components/ui/ScrollArea.d.ts +15 -0
- package/dist/components/ui/ScrollArea.js +18 -0
- package/dist/components/ui/SectionHeader.d.ts +12 -0
- package/dist/components/ui/SectionHeader.js +6 -0
- package/dist/components/ui/Select.d.ts +17 -0
- package/dist/components/ui/Select.js +31 -0
- package/dist/components/ui/Skeleton.d.ts +12 -0
- package/dist/components/ui/Skeleton.js +18 -0
- package/dist/components/ui/Spinner.d.ts +15 -0
- package/dist/components/ui/Spinner.js +24 -0
- package/dist/components/ui/Spotlight.d.ts +16 -0
- package/dist/components/ui/Spotlight.js +16 -0
- package/dist/components/ui/Sprite.d.ts +27 -0
- package/dist/components/ui/Sprite.js +19 -0
- package/dist/components/ui/StatCounter.d.ts +24 -0
- package/dist/components/ui/StatCounter.js +70 -0
- package/dist/components/ui/StatsSection.d.ts +14 -0
- package/dist/components/ui/StatsSection.js +13 -0
- package/dist/components/ui/Stepper.d.ts +10 -0
- package/dist/components/ui/Stepper.js +7 -0
- package/dist/components/ui/Table.d.ts +10 -0
- package/dist/components/ui/Table.js +8 -0
- package/dist/components/ui/Tabs.d.ts +12 -0
- package/dist/components/ui/Tabs.js +18 -0
- package/dist/components/ui/TeamSection.d.ts +18 -0
- package/dist/components/ui/TeamSection.js +19 -0
- package/dist/components/ui/TerminalTyper.d.ts +20 -0
- package/dist/components/ui/TerminalTyper.js +45 -0
- package/dist/components/ui/Testimonial.d.ts +19 -0
- package/dist/components/ui/Testimonial.js +9 -0
- package/dist/components/ui/TestimonialSection.d.ts +20 -0
- package/dist/components/ui/TestimonialSection.js +15 -0
- package/dist/components/ui/TextField.d.ts +26 -0
- package/dist/components/ui/TextField.js +13 -0
- package/dist/components/ui/TextmodeBackground.d.ts +52 -0
- package/dist/components/ui/TextmodeBackground.js +83 -0
- package/dist/components/ui/Timeline.d.ts +13 -0
- package/dist/components/ui/Timeline.js +8 -0
- package/dist/components/ui/Toast.d.ts +30 -0
- package/dist/components/ui/Toast.js +47 -0
- package/dist/components/ui/Toggle.d.ts +13 -0
- package/dist/components/ui/Toggle.js +10 -0
- package/dist/components/ui/Tooltip.d.ts +20 -0
- package/dist/components/ui/Tooltip.js +20 -0
- package/dist/components/ui/Typewriter.d.ts +20 -0
- package/dist/components/ui/Typewriter.js +46 -0
- package/dist/components/ui/VideoPlayer.d.ts +81 -0
- package/dist/components/ui/VideoPlayer.js +379 -0
- package/dist/components/ui/fill.d.ts +32 -0
- package/dist/components/ui/fill.js +27 -0
- package/dist/components/ui/intent.d.ts +20 -0
- package/dist/components/ui/intent.js +23 -0
- package/dist/components/ui/styles/kit.css +31 -0
- package/dist/components/ui/styles/ui-carousel.css +113 -0
- package/dist/components/ui/styles/ui-kit.css +1135 -0
- package/dist/components/ui/styles/ui-video.css +75 -0
- package/dist/components/ui/swiperCss.d.ts +15 -0
- package/dist/components/ui/swiperCss.js +15 -0
- package/dist/components/ui/variants.d.ts +12 -0
- package/dist/components/ui/variants.js +10 -0
- package/dist/index.d.ts +77 -0
- package/dist/index.js +77 -0
- package/dist/lib/asciify/painters.d.ts +25 -0
- package/dist/lib/asciify/painters.js +604 -0
- package/dist/lib/asciify/pointer.d.ts +12 -0
- package/dist/lib/asciify/pointer.js +54 -0
- package/dist/lib/asciify/shape-painters.d.ts +44 -0
- package/dist/lib/asciify/shape-painters.js +335 -0
- package/dist/lib/asciify/theme-painters.d.ts +8 -0
- package/dist/lib/asciify/theme-painters.js +437 -0
- package/dist/lib/cells.d.ts +46 -0
- package/dist/lib/cells.js +114 -0
- package/dist/lib/scroll/store.d.ts +21 -0
- package/dist/lib/scroll/store.js +25 -0
- package/dist/lib/sketches/aurora.d.ts +3 -0
- package/dist/lib/sketches/aurora.js +42 -0
- package/dist/lib/sketches/fire.d.ts +3 -0
- package/dist/lib/sketches/fire.js +80 -0
- package/dist/lib/sketches/flow.d.ts +3 -0
- package/dist/lib/sketches/flow.js +70 -0
- package/dist/lib/sketches/life.d.ts +3 -0
- package/dist/lib/sketches/life.js +107 -0
- package/dist/lib/sketches/matrix.d.ts +3 -0
- package/dist/lib/sketches/matrix.js +64 -0
- package/dist/lib/sketches/ocean.d.ts +3 -0
- package/dist/lib/sketches/ocean.js +56 -0
- package/dist/lib/sketches/plasma.d.ts +3 -0
- package/dist/lib/sketches/plasma.js +29 -0
- package/dist/lib/sketches/registry.d.ts +6 -0
- package/dist/lib/sketches/registry.js +60 -0
- package/dist/lib/sketches/ripples.d.ts +3 -0
- package/dist/lib/sketches/ripples.js +84 -0
- package/dist/lib/sketches/scroll-assemble.d.ts +8 -0
- package/dist/lib/sketches/scroll-assemble.js +90 -0
- package/dist/lib/sketches/scroll-parallax.d.ts +6 -0
- package/dist/lib/sketches/scroll-parallax.js +76 -0
- package/dist/lib/sketches/scroll-rain.d.ts +6 -0
- package/dist/lib/sketches/scroll-rain.js +82 -0
- package/dist/lib/sketches/scroll-stats.d.ts +7 -0
- package/dist/lib/sketches/scroll-stats.js +81 -0
- package/dist/lib/sketches/scroll-terminal.d.ts +6 -0
- package/dist/lib/sketches/scroll-terminal.js +87 -0
- package/dist/lib/sketches/scroll-zoom.d.ts +7 -0
- package/dist/lib/sketches/scroll-zoom.js +49 -0
- package/dist/lib/sketches/starfield.d.ts +3 -0
- package/dist/lib/sketches/starfield.js +54 -0
- package/dist/lib/sketches/text-3d.d.ts +6 -0
- package/dist/lib/sketches/text-3d.js +62 -0
- package/dist/lib/sketches/text-combo-figlet.d.ts +6 -0
- package/dist/lib/sketches/text-combo-figlet.js +91 -0
- package/dist/lib/sketches/text-glitch.d.ts +3 -0
- package/dist/lib/sketches/text-glitch.js +57 -0
- package/dist/lib/sketches/text-marquee.d.ts +3 -0
- package/dist/lib/sketches/text-marquee.js +35 -0
- package/dist/lib/sketches/text-particles.d.ts +9 -0
- package/dist/lib/sketches/text-particles.js +91 -0
- package/dist/lib/sketches/text-rain.d.ts +3 -0
- package/dist/lib/sketches/text-rain.js +73 -0
- package/dist/lib/sketches/text-scramble.d.ts +6 -0
- package/dist/lib/sketches/text-scramble.js +49 -0
- package/dist/lib/sketches/text-wave.d.ts +3 -0
- package/dist/lib/sketches/text-wave.js +43 -0
- package/dist/lib/sketches/theme-orbit.d.ts +6 -0
- package/dist/lib/sketches/theme-orbit.js +119 -0
- package/dist/lib/sketches/theme-pulse.d.ts +7 -0
- package/dist/lib/sketches/theme-pulse.js +84 -0
- package/dist/lib/sketches/tunnel.d.ts +3 -0
- package/dist/lib/sketches/tunnel.js +28 -0
- package/dist/lib/text/banner.d.ts +5 -0
- package/dist/lib/text/banner.js +35 -0
- package/dist/lib/text/mask.d.ts +40 -0
- package/dist/lib/text/mask.js +143 -0
- package/dist/lib/text/store.d.ts +23 -0
- package/dist/lib/text/store.js +86 -0
- package/dist/lib/ui/card-fields.d.ts +52 -0
- package/dist/lib/ui/card-fields.js +193 -0
- package/dist/lib/ui/fonts.d.ts +56 -0
- package/dist/lib/ui/fonts.js +94 -0
- package/dist/lib/ui/fx.d.ts +42 -0
- package/dist/lib/ui/fx.js +162 -0
- package/dist/lib/ui/icons.d.ts +437 -0
- package/dist/lib/ui/icons.js +314 -0
- package/dist/lib/ui/placeholder.d.ts +11 -0
- package/dist/lib/ui/placeholder.js +65 -0
- package/dist/lib/ui/tokens.d.ts +49 -0
- package/dist/lib/ui/tokens.js +129 -0
- package/dist/lib/ui/useTokens.d.ts +10 -0
- package/dist/lib/ui/useTokens.js +32 -0
- package/package.json +80 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { clamp01, eachCell, hash2, hsv } from "../cells.js";
|
|
2
|
+
/** Aurora boreal: cortinas de ruido sobre un cielo estrellado y montañas. */
|
|
3
|
+
export function aurora(t) {
|
|
4
|
+
const ramp = t.createGlyphRamp(" .:;+*#%");
|
|
5
|
+
t.draw(() => {
|
|
6
|
+
const s = t.secs;
|
|
7
|
+
const rows = t.grid.rows;
|
|
8
|
+
const top = -Math.floor(rows / 2);
|
|
9
|
+
t.background(0);
|
|
10
|
+
eachCell(t, (x, y) => {
|
|
11
|
+
const yy = (y - top) / rows; // 0 arriba, 1 abajo
|
|
12
|
+
const ridge = 0.8 + 0.1 * t.noise(x * 0.03, 9) + 0.06 * t.noise(x * 0.11, 3);
|
|
13
|
+
if (yy > ridge) {
|
|
14
|
+
t.char(" ");
|
|
15
|
+
t.cellColor(3, 4, 8 + (yy - ridge) * 20);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
t.cellColor(2, 5, 14 + yy * 26);
|
|
19
|
+
// El pliegue de la cortina ondula en horizontal y se desplaza con el tiempo
|
|
20
|
+
const center = 0.2 + 0.3 * t.noise(x * 0.022, s * 0.06) + 0.07 * Math.sin(x * 0.035 + s * 0.45);
|
|
21
|
+
const fall = Math.exp(-(((yy - center) / 0.17) ** 2));
|
|
22
|
+
const rays = 0.45 + 0.75 * t.noise(x * 0.35, s * 0.3);
|
|
23
|
+
const body = 0.6 + 0.6 * t.noise(x * 0.05, yy * 2.2, s * 0.15);
|
|
24
|
+
const power = clamp01(fall * rays * body);
|
|
25
|
+
if (power > 0.05) {
|
|
26
|
+
const above = clamp01((center - yy) / 0.3);
|
|
27
|
+
const hue = 0.34 + 0.44 * above;
|
|
28
|
+
t.char(ramp.at(power));
|
|
29
|
+
t.charColor(...hsv(hue, 0.6, 0.35 + 0.65 * power));
|
|
30
|
+
t.cellColor(...hsv(hue, 0.9, 0.05 + 0.25 * power));
|
|
31
|
+
}
|
|
32
|
+
else if (hash2(x, y) > 0.988) {
|
|
33
|
+
const tw = Math.sin(s * 2.2 + hash2(y, x) * 60) * 0.5 + 0.5;
|
|
34
|
+
t.char(tw > 0.6 ? "*" : ".");
|
|
35
|
+
t.charColor(255, 255, 255, 90 + 165 * tw);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
t.char(" ");
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { aspect, createPointer, gridOrigin, mix, plot } from "../cells.js";
|
|
2
|
+
/** Paleta negro → rojo → naranja → amarillo → blanco */
|
|
3
|
+
function fireColor(h) {
|
|
4
|
+
if (h < 0.35) {
|
|
5
|
+
const k = h / 0.35;
|
|
6
|
+
return [mix(10, 200, k), mix(0, 30, k), mix(0, 10, k)];
|
|
7
|
+
}
|
|
8
|
+
if (h < 0.7) {
|
|
9
|
+
const k = (h - 0.35) / 0.35;
|
|
10
|
+
return [mix(200, 255, k), mix(30, 170, k), mix(10, 20, k)];
|
|
11
|
+
}
|
|
12
|
+
const k = (h - 0.7) / 0.3;
|
|
13
|
+
return [255, mix(170, 255, k), mix(20, 210, k)];
|
|
14
|
+
}
|
|
15
|
+
/** Fuego estilo Doom. El puntero es una antorcha; pulsar la convierte en un soplete. */
|
|
16
|
+
export function fire(t) {
|
|
17
|
+
const ramp = t.createGlyphRamp(" .:-=+*#%@");
|
|
18
|
+
const ptr = createPointer(t);
|
|
19
|
+
let W = 0;
|
|
20
|
+
let H = 0;
|
|
21
|
+
let heat = new Float32Array(0);
|
|
22
|
+
const rebuild = () => {
|
|
23
|
+
W = t.grid.cols;
|
|
24
|
+
H = t.grid.rows;
|
|
25
|
+
heat = new Float32Array(W * H);
|
|
26
|
+
};
|
|
27
|
+
t.draw(() => {
|
|
28
|
+
if (W !== t.grid.cols || H !== t.grid.rows)
|
|
29
|
+
rebuild();
|
|
30
|
+
ptr.update();
|
|
31
|
+
const { x0, y0 } = gridOrigin(t);
|
|
32
|
+
if (t.frameCount % 2 === 0) {
|
|
33
|
+
// Combustible con lenguas de distinta altura, moduladas por ruido
|
|
34
|
+
for (let x = 0; x < W; x++) {
|
|
35
|
+
const fuel = t.noise(x * 0.09, t.secs * 0.5);
|
|
36
|
+
heat[(H - 1) * W + x] = Math.min(1, 0.35 + fuel * 1.1 + Math.random() * 0.1);
|
|
37
|
+
}
|
|
38
|
+
const r = ptr.pressed ? 9 : 4;
|
|
39
|
+
const asp = aspect(t);
|
|
40
|
+
const rx = Math.ceil(r * asp);
|
|
41
|
+
const gx = Math.round(ptr.x - x0);
|
|
42
|
+
const gy = Math.round(ptr.y - y0);
|
|
43
|
+
if (ptr.hovering) {
|
|
44
|
+
for (let dy = -r; dy <= r; dy++) {
|
|
45
|
+
for (let dx = -rx; dx <= rx; dx++) {
|
|
46
|
+
const x = gx + dx;
|
|
47
|
+
const y = gy + dy;
|
|
48
|
+
if (x < 0 || y < 0 || x >= W || y >= H)
|
|
49
|
+
continue;
|
|
50
|
+
if (Math.hypot(dx / asp, dy) <= r)
|
|
51
|
+
heat[y * W + x] = 1;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const decay = 1.9 / H;
|
|
56
|
+
const wind = Math.sin(t.secs * 0.4) * 0.6;
|
|
57
|
+
for (let y = 0; y < H - 1; y++) {
|
|
58
|
+
for (let x = 0; x < W; x++) {
|
|
59
|
+
// Cada celda toma calor de la de abajo, ladeada al azar y por el viento
|
|
60
|
+
const sx = Math.min(W - 1, Math.max(0, x + Math.round(Math.random() * 2 - 1 + wind)));
|
|
61
|
+
const src = (heat[(y + 1) * W + sx] * 2 + heat[(y + 1) * W + x]) / 3;
|
|
62
|
+
heat[y * W + x] = Math.max(0, src - decay * (0.5 + Math.random()));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
t.background(8, 4, 8);
|
|
67
|
+
for (let y = 0; y < H; y++) {
|
|
68
|
+
for (let x = 0; x < W; x++) {
|
|
69
|
+
const h = heat[y * W + x];
|
|
70
|
+
if (h < 0.03)
|
|
71
|
+
continue;
|
|
72
|
+
const [r, g, b] = fireColor(h);
|
|
73
|
+
t.char(ramp.at(h));
|
|
74
|
+
t.charColor(Math.min(255, r * 1.25), Math.min(255, g * 1.2 + 20), b);
|
|
75
|
+
t.cellColor(r * 0.45, g * 0.4, b * 0.4);
|
|
76
|
+
plot(t, x0 + x, y0 + y);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { aspect, createPointer, gridOrigin, hsv, plot } from "../cells.js";
|
|
2
|
+
const TRAIL = 9;
|
|
3
|
+
/** Partículas sobre un campo de flujo de ruido. El puntero las atrae; pulsar las repele. */
|
|
4
|
+
export function flow(t) {
|
|
5
|
+
const ptr = createPointer(t);
|
|
6
|
+
const ramp = t.createGlyphRamp(" .:-=+*#");
|
|
7
|
+
const particles = [];
|
|
8
|
+
const respawn = (p) => {
|
|
9
|
+
const { cols, rows, x0, y0 } = gridOrigin(t);
|
|
10
|
+
p.x = x0 + Math.random() * cols;
|
|
11
|
+
p.y = y0 + Math.random() * rows;
|
|
12
|
+
p.age = 0;
|
|
13
|
+
p.life = 120 + Math.random() * 260;
|
|
14
|
+
p.trail = [];
|
|
15
|
+
};
|
|
16
|
+
// La rejilla no existe hasta el primer fotograma, así que las partículas se crean allí
|
|
17
|
+
const init = () => {
|
|
18
|
+
for (let i = 0; i < 800; i++) {
|
|
19
|
+
const p = { x: 0, y: 0, age: 0, life: 0, trail: [] };
|
|
20
|
+
respawn(p);
|
|
21
|
+
p.age = Math.random() * p.life;
|
|
22
|
+
particles.push(p);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
t.draw(() => {
|
|
26
|
+
if (particles.length === 0)
|
|
27
|
+
init();
|
|
28
|
+
ptr.update();
|
|
29
|
+
const s = t.secs;
|
|
30
|
+
const asp = aspect(t);
|
|
31
|
+
const { cols, rows, x0, y0 } = gridOrigin(t);
|
|
32
|
+
const sign = ptr.pressed ? -1 : 1;
|
|
33
|
+
t.background(5, 6, 14);
|
|
34
|
+
for (const p of particles) {
|
|
35
|
+
const n = t.noise(p.x * 0.025, p.y * 0.025 * asp, s * 0.07);
|
|
36
|
+
const ang = n * Math.PI * 4;
|
|
37
|
+
let vx = Math.cos(ang) * 0.5;
|
|
38
|
+
let vy = (Math.sin(ang) * 0.5) / asp;
|
|
39
|
+
const dx = ptr.x - p.x;
|
|
40
|
+
const dy = (ptr.y - p.y) * asp;
|
|
41
|
+
const d = Math.hypot(dx, dy) + 0.001;
|
|
42
|
+
if (d < 34) {
|
|
43
|
+
const pull = ((34 - d) / 34) * 0.9 * sign;
|
|
44
|
+
vx += (dx / d) * pull;
|
|
45
|
+
vy += ((dy / d) * pull) / asp;
|
|
46
|
+
}
|
|
47
|
+
p.x += vx;
|
|
48
|
+
p.y += vy;
|
|
49
|
+
p.age++;
|
|
50
|
+
if (p.age % 2 === 0) {
|
|
51
|
+
p.trail.push(p.x, p.y);
|
|
52
|
+
if (p.trail.length > TRAIL * 2)
|
|
53
|
+
p.trail.splice(0, 2);
|
|
54
|
+
}
|
|
55
|
+
if (p.age > p.life || p.x < x0 - 2 || p.x > x0 + cols + 2 || p.y < y0 - 2 || p.y > y0 + rows + 2) {
|
|
56
|
+
respawn(p);
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
const hue = 0.52 + (ang / (Math.PI * 4)) * 0.4;
|
|
60
|
+
const len = p.trail.length / 2;
|
|
61
|
+
for (let k = 0; k < len; k++) {
|
|
62
|
+
const f = (k + 1) / len;
|
|
63
|
+
t.char(ramp.at(f));
|
|
64
|
+
t.charColor(...hsv(hue, 0.65, 0.25 + 0.75 * f));
|
|
65
|
+
t.cellColor(...hsv(hue, 0.8, 0.06 * f));
|
|
66
|
+
plot(t, Math.round(p.trail[k * 2]), Math.round(p.trail[k * 2 + 1]));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { aspect, createPointer, gridOrigin, hsv, plot } from "../cells.js";
|
|
2
|
+
/** Juego de la vida toroidal. Mover el puntero siembra células; pulsar siembra en grande. */
|
|
3
|
+
export function life(t) {
|
|
4
|
+
const ptr = createPointer(t);
|
|
5
|
+
let W = 0;
|
|
6
|
+
let H = 0;
|
|
7
|
+
let alive = new Uint8Array(0);
|
|
8
|
+
let scratch = new Uint8Array(0);
|
|
9
|
+
let age = new Uint16Array(0);
|
|
10
|
+
let ghost = new Float32Array(0);
|
|
11
|
+
let steps = 0;
|
|
12
|
+
const seed = (density, keep = false) => {
|
|
13
|
+
for (let i = 0; i < W * H; i++) {
|
|
14
|
+
if (keep && alive[i])
|
|
15
|
+
continue;
|
|
16
|
+
if (Math.random() < density)
|
|
17
|
+
alive[i] = 1;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
const rebuild = () => {
|
|
21
|
+
W = t.grid.cols;
|
|
22
|
+
H = t.grid.rows;
|
|
23
|
+
alive = new Uint8Array(W * H);
|
|
24
|
+
scratch = new Uint8Array(W * H);
|
|
25
|
+
age = new Uint16Array(W * H);
|
|
26
|
+
ghost = new Float32Array(W * H);
|
|
27
|
+
seed(0.2);
|
|
28
|
+
};
|
|
29
|
+
const step = () => {
|
|
30
|
+
let pop = 0;
|
|
31
|
+
for (let y = 0; y < H; y++) {
|
|
32
|
+
const ym = ((y + H - 1) % H) * W;
|
|
33
|
+
const yp = ((y + 1) % H) * W;
|
|
34
|
+
for (let x = 0; x < W; x++) {
|
|
35
|
+
const xm = (x + W - 1) % W;
|
|
36
|
+
const xp = (x + 1) % W;
|
|
37
|
+
const n = alive[ym + xm] + alive[ym + x] + alive[ym + xp] +
|
|
38
|
+
alive[y * W + xm] + alive[y * W + xp] +
|
|
39
|
+
alive[yp + xm] + alive[yp + x] + alive[yp + xp];
|
|
40
|
+
const i = y * W + x;
|
|
41
|
+
const live = alive[i] ? n === 2 || n === 3 : n === 3;
|
|
42
|
+
scratch[i] = live ? 1 : 0;
|
|
43
|
+
if (live) {
|
|
44
|
+
age[i] = alive[i] ? Math.min(age[i] + 1, 60) : 0;
|
|
45
|
+
pop++;
|
|
46
|
+
}
|
|
47
|
+
else if (alive[i]) {
|
|
48
|
+
ghost[i] = 1;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
[alive, scratch] = [scratch, alive];
|
|
53
|
+
steps++;
|
|
54
|
+
if (pop < W * H * 0.012)
|
|
55
|
+
seed(0.2);
|
|
56
|
+
else if (steps % 500 === 0)
|
|
57
|
+
seed(0.03, true);
|
|
58
|
+
};
|
|
59
|
+
t.draw(() => {
|
|
60
|
+
if (W !== t.grid.cols || H !== t.grid.rows)
|
|
61
|
+
rebuild();
|
|
62
|
+
ptr.update();
|
|
63
|
+
const { x0, y0 } = gridOrigin(t);
|
|
64
|
+
if (ptr.raw) {
|
|
65
|
+
const r = ptr.pressed ? 6 : 2;
|
|
66
|
+
const p = ptr.pressed ? 0.6 : 0.3;
|
|
67
|
+
const asp = aspect(t);
|
|
68
|
+
const rx = Math.ceil(r * asp);
|
|
69
|
+
const gx = Math.round(ptr.raw.x - x0);
|
|
70
|
+
const gy = Math.round(ptr.raw.y - y0);
|
|
71
|
+
for (let dy = -r; dy <= r; dy++) {
|
|
72
|
+
for (let dx = -rx; dx <= rx; dx++) {
|
|
73
|
+
if (Math.hypot(dx / asp, dy) > r)
|
|
74
|
+
continue;
|
|
75
|
+
const x = gx + dx;
|
|
76
|
+
const y = gy + dy;
|
|
77
|
+
if (x < 0 || y < 0 || x >= W || y >= H)
|
|
78
|
+
continue;
|
|
79
|
+
if (Math.random() < p)
|
|
80
|
+
alive[y * W + x] = 1;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (t.frameCount % 4 === 0)
|
|
85
|
+
step();
|
|
86
|
+
t.background(4, 5, 12);
|
|
87
|
+
for (let y = 0; y < H; y++) {
|
|
88
|
+
for (let x = 0; x < W; x++) {
|
|
89
|
+
const i = y * W + x;
|
|
90
|
+
if (alive[i]) {
|
|
91
|
+
const a = age[i];
|
|
92
|
+
t.char(a < 2 ? "@" : a < 8 ? "O" : a < 24 ? "o" : "+");
|
|
93
|
+
t.charColor(...hsv(0.5 + Math.min(a, 40) * 0.006, 0.55, a < 2 ? 1 : 0.85));
|
|
94
|
+
t.cellColor(...hsv(0.55, 0.7, 0.14 + (a < 2 ? 0.14 : 0)));
|
|
95
|
+
plot(t, x0 + x, y0 + y);
|
|
96
|
+
}
|
|
97
|
+
else if (ghost[i] > 0.05) {
|
|
98
|
+
ghost[i] *= 0.9;
|
|
99
|
+
t.char(".");
|
|
100
|
+
t.charColor(...hsv(0.85, 0.6, ghost[i] * 0.9));
|
|
101
|
+
t.cellColor(4, 5, 12);
|
|
102
|
+
plot(t, x0 + x, y0 + y);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { aspect, createPointer, gridOrigin, plot } from "../cells.js";
|
|
2
|
+
const GLYPHS = "01ABCDEFGHIJKLMNOPQRSTUVWXYZ<>{}[]/\\|+=*:;#$%&@";
|
|
3
|
+
/** Lluvia digital. Las columnas cercanas al puntero se vuelven cian, aceleran y se descomponen. */
|
|
4
|
+
export function matrix(t) {
|
|
5
|
+
const ptr = createPointer(t);
|
|
6
|
+
let columns = [];
|
|
7
|
+
let W = 0;
|
|
8
|
+
let H = 0;
|
|
9
|
+
const glyph = () => GLYPHS[Math.floor(Math.random() * GLYPHS.length)];
|
|
10
|
+
const spawn = (initial) => {
|
|
11
|
+
const len = 8 + Math.random() * 22;
|
|
12
|
+
return {
|
|
13
|
+
head: initial ? Math.random() * H * 1.4 - H * 0.2 : -len - Math.random() * H * 0.5,
|
|
14
|
+
speed: 0.12 + Math.random() * 0.5,
|
|
15
|
+
len,
|
|
16
|
+
chars: Array.from({ length: H + 48 }, glyph),
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
const rebuild = () => {
|
|
20
|
+
W = t.grid.cols;
|
|
21
|
+
H = t.grid.rows;
|
|
22
|
+
columns = Array.from({ length: W }, () => spawn(true));
|
|
23
|
+
};
|
|
24
|
+
t.draw(() => {
|
|
25
|
+
if (W !== t.grid.cols || H !== t.grid.rows)
|
|
26
|
+
rebuild();
|
|
27
|
+
ptr.update();
|
|
28
|
+
const asp = aspect(t);
|
|
29
|
+
const { x0, y0 } = gridOrigin(t);
|
|
30
|
+
const R = 11 + (ptr.pressed ? 10 : 0);
|
|
31
|
+
t.background(0, 6, 2);
|
|
32
|
+
for (let i = 0; i < W; i++) {
|
|
33
|
+
const c = columns[i];
|
|
34
|
+
const x = x0 + i;
|
|
35
|
+
const headY = y0 + c.head;
|
|
36
|
+
const near = Math.hypot(x - ptr.x, (headY - ptr.y) * asp) < R;
|
|
37
|
+
c.head += c.speed * (near ? 2.4 : 1);
|
|
38
|
+
if (Math.random() < 0.06)
|
|
39
|
+
c.chars[Math.floor(Math.random() * c.chars.length)] = glyph();
|
|
40
|
+
if (c.head - c.len > H)
|
|
41
|
+
columns[i] = spawn(false);
|
|
42
|
+
for (let k = 0; k < c.len; k++) {
|
|
43
|
+
const row = Math.floor(c.head) - k;
|
|
44
|
+
if (row < 0 || row >= H)
|
|
45
|
+
continue;
|
|
46
|
+
const fade = 1 - k / c.len;
|
|
47
|
+
const y = y0 + row;
|
|
48
|
+
const hot = Math.hypot(x - ptr.x, (y - ptr.y) * asp) < R;
|
|
49
|
+
t.char(hot && Math.random() < 0.4 ? glyph() : c.chars[row % c.chars.length]);
|
|
50
|
+
if (k === 0) {
|
|
51
|
+
t.charColor(hot ? 210 : 200, 255, hot ? 255 : 220);
|
|
52
|
+
}
|
|
53
|
+
else if (hot) {
|
|
54
|
+
t.charColor(40 * fade, 220 * fade + 30, 255 * fade + 20);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
t.charColor(0, 60 + 195 * fade * fade, 40 * fade);
|
|
58
|
+
}
|
|
59
|
+
t.cellColor(0, 8 + 14 * fade, 4);
|
|
60
|
+
plot(t, x, y);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { aspect, clamp01, eachCell, hash2, mix, smoothstep } from "../cells.js";
|
|
2
|
+
/** Atardecer sobre el mar: cielo degradado, sol y reflejo que centellea entre las olas. */
|
|
3
|
+
export function ocean(t) {
|
|
4
|
+
t.draw(() => {
|
|
5
|
+
const s = t.secs;
|
|
6
|
+
const asp = aspect(t);
|
|
7
|
+
const rows = t.grid.rows;
|
|
8
|
+
const horizon = Math.round(rows * 0.08); // fila (coordenada Y) del horizonte
|
|
9
|
+
const top = -Math.floor(rows / 2);
|
|
10
|
+
const bottom = top + rows;
|
|
11
|
+
const sunR = Math.max(6, rows * 0.16);
|
|
12
|
+
t.background(0);
|
|
13
|
+
eachCell(t, (x, y) => {
|
|
14
|
+
if (y < horizon) {
|
|
15
|
+
// Cielo
|
|
16
|
+
const k = (y - top) / (horizon - top);
|
|
17
|
+
const dx = x;
|
|
18
|
+
const dy = (y - (horizon - sunR * 0.55)) * asp;
|
|
19
|
+
const d = Math.hypot(dx, dy);
|
|
20
|
+
const glow = Math.exp(-d / (sunR * 2.2)) * 0.9;
|
|
21
|
+
let r = mix(24, 255, k * k) + glow * 90;
|
|
22
|
+
let g = mix(14, 120, k * k * k) + glow * 70;
|
|
23
|
+
let b = mix(60, 110, k) + glow * 10;
|
|
24
|
+
t.cellColor(r, g, b);
|
|
25
|
+
if (d < sunR) {
|
|
26
|
+
t.char(" ");
|
|
27
|
+
t.cellColor(255, 220 - d * 4, 130 - d * 5);
|
|
28
|
+
t.charColor(255, 240, 190);
|
|
29
|
+
}
|
|
30
|
+
else if (k < 0.5 && hash2(x, y) > 0.985) {
|
|
31
|
+
t.char(Math.sin(s * 2 + hash2(y, x) * 40) > 0 ? "*" : ".");
|
|
32
|
+
t.charColor(255, 255, 255, (1 - k * 2) * 255);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
t.char(" ");
|
|
36
|
+
}
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
// Agua
|
|
40
|
+
const depth = clamp01((y - horizon) / (bottom - horizon));
|
|
41
|
+
const k = 0.12 + 0.55 * (1 - depth);
|
|
42
|
+
const wave = Math.sin(x * k + s * (1 + depth * 2.5) + Math.sin(y * 0.7 + s * 0.6) * 0.8) * 0.5 + 0.5;
|
|
43
|
+
const sunSpread = 3 + depth * 26;
|
|
44
|
+
const glitter = Math.exp(-(x * x) / (sunSpread * sunSpread)) * smoothstep(0.35, 0.9, wave);
|
|
45
|
+
t.cellColor(mix(70, 6, depth) + glitter * 190, mix(30, 14, depth) + glitter * 130, mix(90, 40, depth) + glitter * 20);
|
|
46
|
+
if (glitter > 0.25) {
|
|
47
|
+
t.char("=");
|
|
48
|
+
t.charColor(255, 235, 180);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
t.char(wave > 0.8 ? "~" : wave > 0.5 ? "-" : " ");
|
|
52
|
+
t.charColor(mix(190, 90, depth), mix(90, 110, depth), mix(150, 190, depth));
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { aspect, clamp01, createPointer, eachCell, hsv } from "../cells.js";
|
|
2
|
+
/** Plasma con rampa de glifos. El puntero deforma el campo; al pulsar la onda crece. */
|
|
3
|
+
export function plasma(t) {
|
|
4
|
+
const ramp = t.createGlyphRamp(" .:-=+*#%@");
|
|
5
|
+
const ptr = createPointer(t);
|
|
6
|
+
t.draw(() => {
|
|
7
|
+
ptr.update();
|
|
8
|
+
const s = t.secs;
|
|
9
|
+
const asp = aspect(t);
|
|
10
|
+
const radius = ptr.pressed ? 900 : 260;
|
|
11
|
+
t.background(0);
|
|
12
|
+
eachCell(t, (x, y) => {
|
|
13
|
+
const yy = y * asp;
|
|
14
|
+
let v = Math.sin(x * 0.09 + s) +
|
|
15
|
+
Math.sin(yy * 0.13 - s * 1.3) +
|
|
16
|
+
Math.sin((x + yy) * 0.06 + s * 0.7) +
|
|
17
|
+
Math.sin(Math.hypot(x * 0.8, yy) * 0.08 - s * 1.1);
|
|
18
|
+
const dx = x - ptr.x;
|
|
19
|
+
const dy = (y - ptr.y) * asp;
|
|
20
|
+
const d2 = dx * dx + dy * dy;
|
|
21
|
+
v += 3 * Math.exp(-d2 / radius) * Math.sin(s * 4 - Math.sqrt(d2) * 0.5);
|
|
22
|
+
const n = clamp01((v + 4) / 8);
|
|
23
|
+
const hue = n * 0.55 + s * 0.02 + 0.55;
|
|
24
|
+
t.char(ramp.at(n));
|
|
25
|
+
t.charColor(...hsv(hue, 0.75, 0.3 + 0.7 * n));
|
|
26
|
+
t.cellColor(...hsv(hue, 0.85, 0.05 + 0.13 * n));
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { aurora } from "./aurora.js";
|
|
2
|
+
import { fire } from "./fire.js";
|
|
3
|
+
import { flow } from "./flow.js";
|
|
4
|
+
import { life } from "./life.js";
|
|
5
|
+
import { matrix } from "./matrix.js";
|
|
6
|
+
import { ocean } from "./ocean.js";
|
|
7
|
+
import { plasma } from "./plasma.js";
|
|
8
|
+
import { ripples } from "./ripples.js";
|
|
9
|
+
import { starfield } from "./starfield.js";
|
|
10
|
+
import { tunnel } from "./tunnel.js";
|
|
11
|
+
import { scAssemble } from "./scroll-assemble.js";
|
|
12
|
+
import { scParallax } from "./scroll-parallax.js";
|
|
13
|
+
import { scRain } from "./scroll-rain.js";
|
|
14
|
+
import { scStats } from "./scroll-stats.js";
|
|
15
|
+
import { scTerminal } from "./scroll-terminal.js";
|
|
16
|
+
import { scZoom } from "./scroll-zoom.js";
|
|
17
|
+
import { tx3d } from "./text-3d.js";
|
|
18
|
+
import { txScramble } from "./text-scramble.js";
|
|
19
|
+
import { thOrbit } from "./theme-orbit.js";
|
|
20
|
+
import { thPulse } from "./theme-pulse.js";
|
|
21
|
+
import { txComboFiglet } from "./text-combo-figlet.js";
|
|
22
|
+
import { txGlitch } from "./text-glitch.js";
|
|
23
|
+
import { txMarquee } from "./text-marquee.js";
|
|
24
|
+
import { txParticles } from "./text-particles.js";
|
|
25
|
+
import { txRain } from "./text-rain.js";
|
|
26
|
+
import { txWave } from "./text-wave.js";
|
|
27
|
+
export const sketches = {
|
|
28
|
+
plasma: { fontSize: 16, setup: plasma },
|
|
29
|
+
matrix: { fontSize: 16, setup: matrix },
|
|
30
|
+
starfield: { fontSize: 14, setup: starfield },
|
|
31
|
+
ripples: { fontSize: 14, setup: ripples },
|
|
32
|
+
life: { fontSize: 14, setup: life },
|
|
33
|
+
flow: { fontSize: 14, setup: flow },
|
|
34
|
+
fire: { fontSize: 14, setup: fire },
|
|
35
|
+
ocean: { fontSize: 16, setup: ocean },
|
|
36
|
+
tunnel: { fontSize: 16, setup: tunnel },
|
|
37
|
+
aurora: { fontSize: 16, setup: aurora },
|
|
38
|
+
// Demos de texto (leen lo que se escribe en el cajón de la interfaz)
|
|
39
|
+
"tx-wave": { fontSize: 12, setup: txWave },
|
|
40
|
+
"tx-particles": { fontSize: 12, setup: txParticles },
|
|
41
|
+
"tx-glitch": { fontSize: 12, setup: txGlitch },
|
|
42
|
+
"tx-rain": { fontSize: 14, setup: txRain },
|
|
43
|
+
"tx-marquee": { fontSize: 16, setup: txMarquee },
|
|
44
|
+
"tx-combo-figlet": { fontSize: 14, setup: txComboFiglet },
|
|
45
|
+
"tx-scramble": { fontSize: 12, setup: txScramble },
|
|
46
|
+
"tx-3d": { fontSize: 12, setup: tx3d },
|
|
47
|
+
// Demos con scroll (300vh): leen scrollState
|
|
48
|
+
"sc-zoom": { fontSize: 12, setup: scZoom },
|
|
49
|
+
"sc-assemble": { fontSize: 12, setup: (t) => scAssemble(t) },
|
|
50
|
+
"sc-rain": { fontSize: 14, setup: scRain },
|
|
51
|
+
"sc-parallax": { fontSize: 14, setup: scParallax },
|
|
52
|
+
"sc-terminal": { fontSize: 20, setup: scTerminal },
|
|
53
|
+
"sc-stats": { fontSize: 10, setup: scStats },
|
|
54
|
+
"sc-combo": { fontSize: 12, setup: (t) => scAssemble(t, { transparent: true }) },
|
|
55
|
+
// Fondos de las landings temáticas
|
|
56
|
+
"th-orbit": { fontSize: 14, setup: thOrbit },
|
|
57
|
+
"th-pulse": { fontSize: 14, setup: thPulse },
|
|
58
|
+
// Capa superior del combo: partículas de texto sin fondo, fusionadas con la capa de asciify
|
|
59
|
+
"tx-combo-layers": { fontSize: 12, setup: (t) => txParticles(t, { transparent: true }) },
|
|
60
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { aspect, clamp01, createPointer, gridOrigin, plot } from "../cells.js";
|
|
2
|
+
/** Agua. Cada movimiento del puntero lanza ondas; pulsar deja caer una gota grande. */
|
|
3
|
+
export function ripples(t) {
|
|
4
|
+
const ramp = t.createGlyphRamp(" .,:;+*#@");
|
|
5
|
+
const ptr = createPointer(t);
|
|
6
|
+
let W = 0;
|
|
7
|
+
let H = 0;
|
|
8
|
+
let cur = new Float32Array(0);
|
|
9
|
+
let prev = new Float32Array(0);
|
|
10
|
+
let next = new Float32Array(0);
|
|
11
|
+
const rebuild = () => {
|
|
12
|
+
W = t.grid.cols;
|
|
13
|
+
H = t.grid.rows;
|
|
14
|
+
cur = new Float32Array(W * H);
|
|
15
|
+
prev = new Float32Array(W * H);
|
|
16
|
+
next = new Float32Array(W * H);
|
|
17
|
+
};
|
|
18
|
+
const drop = (cx, cy, r, amp) => {
|
|
19
|
+
const asp = aspect(t);
|
|
20
|
+
const ry = Math.ceil(r);
|
|
21
|
+
const rx = Math.ceil(r * asp);
|
|
22
|
+
for (let dy = -ry; dy <= ry; dy++) {
|
|
23
|
+
for (let dx = -rx; dx <= rx; dx++) {
|
|
24
|
+
const x = cx + dx;
|
|
25
|
+
const y = cy + dy;
|
|
26
|
+
if (x < 1 || y < 1 || x >= W - 1 || y >= H - 1)
|
|
27
|
+
continue;
|
|
28
|
+
const f = Math.max(0, 1 - Math.hypot(dx, dy * asp) / (r * asp + 0.5));
|
|
29
|
+
cur[y * W + x] += amp * f;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
let wasPressed = false;
|
|
34
|
+
t.draw(() => {
|
|
35
|
+
if (W !== t.grid.cols || H !== t.grid.rows)
|
|
36
|
+
rebuild();
|
|
37
|
+
ptr.update();
|
|
38
|
+
const { x0, y0 } = gridOrigin(t);
|
|
39
|
+
// Entradas: puntero y lluvia ocasional
|
|
40
|
+
if (ptr.raw) {
|
|
41
|
+
const gx = ptr.raw.x - x0;
|
|
42
|
+
const gy = ptr.raw.y - y0;
|
|
43
|
+
if (ptr.pressed && !wasPressed)
|
|
44
|
+
drop(gx, gy, 4, 6);
|
|
45
|
+
else if (Math.abs(ptr.vx) + Math.abs(ptr.vy) > 0.15)
|
|
46
|
+
drop(gx, gy, 1, 1.4);
|
|
47
|
+
}
|
|
48
|
+
wasPressed = ptr.pressed;
|
|
49
|
+
if (t.frameCount % 45 === 0) {
|
|
50
|
+
drop(2 + Math.floor(Math.random() * (W - 4)), 2 + Math.floor(Math.random() * (H - 4)), 2, 3);
|
|
51
|
+
}
|
|
52
|
+
// Ecuación de ondas anisótropa: las celdas son ~2 veces más altas que anchas
|
|
53
|
+
const asp = aspect(t);
|
|
54
|
+
const kx = 1;
|
|
55
|
+
const ky = 1 / (asp * asp);
|
|
56
|
+
const a = 0.92 / (kx + ky); // condición de estabilidad: a·(kx+ky) < 1
|
|
57
|
+
for (let y = 1; y < H - 1; y++) {
|
|
58
|
+
for (let x = 1; x < W - 1; x++) {
|
|
59
|
+
const i = y * W + x;
|
|
60
|
+
const u = cur[i];
|
|
61
|
+
const lap = kx * (cur[i - 1] + cur[i + 1] - 2 * u) + ky * (cur[i - W] + cur[i + W] - 2 * u);
|
|
62
|
+
next[i] = (2 * u - prev[i] + a * lap) * 0.99;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
[prev, cur, next] = [cur, next, prev];
|
|
66
|
+
t.background(3, 10, 24);
|
|
67
|
+
for (let y = 0; y < H; y++) {
|
|
68
|
+
for (let x = 0; x < W; x++) {
|
|
69
|
+
const v = cur[y * W + x];
|
|
70
|
+
const m = Math.abs(v);
|
|
71
|
+
if (m < 0.04)
|
|
72
|
+
continue;
|
|
73
|
+
const n = clamp01(m * 0.9);
|
|
74
|
+
t.char(ramp.at(n));
|
|
75
|
+
if (v > 0)
|
|
76
|
+
t.charColor(120 + 135 * n, 210 + 45 * n, 255);
|
|
77
|
+
else
|
|
78
|
+
t.charColor(20 + 40 * n, 90 + 90 * n, 200 + 50 * n);
|
|
79
|
+
t.cellColor(4 + 20 * n, 16 + 60 * n, 40 + 90 * n);
|
|
80
|
+
plot(t, x0 + x, y0 + y);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Textmodifier } from "textmode.js";
|
|
2
|
+
/**
|
|
3
|
+
* Ensamblaje: las partículas empiezan dispersas, se agrupan formando tu texto a medida
|
|
4
|
+
* que bajas y estallan hacia fuera al final del recorrido.
|
|
5
|
+
*/
|
|
6
|
+
export declare function scAssemble(t: Textmodifier, opts?: {
|
|
7
|
+
transparent?: boolean;
|
|
8
|
+
}): void;
|