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.
Files changed (285) hide show
  1. package/CATALOG.md +1237 -0
  2. package/LICENSE +21 -0
  3. package/README.md +78 -0
  4. package/THIRD-PARTY.md +4 -0
  5. package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/brown.png +0 -0
  6. package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/brown_inlay.png +0 -0
  7. package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/brown_pressed.png +0 -0
  8. package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/grey.png +0 -0
  9. package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/grey_inlay.png +0 -0
  10. package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/grey_pressed.png +0 -0
  11. package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/tan.png +0 -0
  12. package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/tan_inlay.png +0 -0
  13. package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/tan_pressed.png +0 -0
  14. package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/white.png +0 -0
  15. package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/white_inlay.png +0 -0
  16. package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/white_pressed.png +0 -0
  17. package/assets/pixel/kenney-pixel-ui/9-slice/Colored/blue.png +0 -0
  18. package/assets/pixel/kenney-pixel-ui/9-slice/Colored/blue_pressed.png +0 -0
  19. package/assets/pixel/kenney-pixel-ui/9-slice/Colored/green.png +0 -0
  20. package/assets/pixel/kenney-pixel-ui/9-slice/Colored/green_pressed.png +0 -0
  21. package/assets/pixel/kenney-pixel-ui/9-slice/Colored/grey.png +0 -0
  22. package/assets/pixel/kenney-pixel-ui/9-slice/Colored/grey_pressed.png +0 -0
  23. package/assets/pixel/kenney-pixel-ui/9-slice/Colored/red.png +0 -0
  24. package/assets/pixel/kenney-pixel-ui/9-slice/Colored/red_pressed.png +0 -0
  25. package/assets/pixel/kenney-pixel-ui/9-slice/Colored/yellow.png +0 -0
  26. package/assets/pixel/kenney-pixel-ui/9-slice/Colored/yellow_pressed.png +0 -0
  27. package/assets/pixel/kenney-pixel-ui/9-slice/Outline/blue.png +0 -0
  28. package/assets/pixel/kenney-pixel-ui/9-slice/Outline/blue_pressed.png +0 -0
  29. package/assets/pixel/kenney-pixel-ui/9-slice/Outline/green.png +0 -0
  30. package/assets/pixel/kenney-pixel-ui/9-slice/Outline/green_pressed.png +0 -0
  31. package/assets/pixel/kenney-pixel-ui/9-slice/Outline/red.png +0 -0
  32. package/assets/pixel/kenney-pixel-ui/9-slice/Outline/red_pressed.png +0 -0
  33. package/assets/pixel/kenney-pixel-ui/9-slice/Outline/yellow.png +0 -0
  34. package/assets/pixel/kenney-pixel-ui/9-slice/Outline/yellow_pressed.png +0 -0
  35. package/assets/pixel/kenney-pixel-ui/9-slice/list.png +0 -0
  36. package/assets/pixel/kenney-pixel-ui/9-slice/space.png +0 -0
  37. package/assets/pixel/kenney-pixel-ui/9-slice/space_inlay.png +0 -0
  38. package/assets/pixel/kenney-pixel-ui/License.txt +23 -0
  39. package/assets/pixel/kenney-pixel-ui/spritesheet/sheet.png +0 -0
  40. package/bin/trama-ui.mjs +27 -0
  41. package/dist/components/ui/Accordion.d.ts +12 -0
  42. package/dist/components/ui/Accordion.js +12 -0
  43. package/dist/components/ui/Alert.d.ts +15 -0
  44. package/dist/components/ui/Alert.js +15 -0
  45. package/dist/components/ui/ArticlesSection.d.ts +30 -0
  46. package/dist/components/ui/ArticlesSection.js +18 -0
  47. package/dist/components/ui/AsciiBackground.d.ts +58 -0
  48. package/dist/components/ui/AsciiBackground.js +173 -0
  49. package/dist/components/ui/AsciiCard.d.ts +78 -0
  50. package/dist/components/ui/AsciiCard.js +253 -0
  51. package/dist/components/ui/AsciiChart.d.ts +18 -0
  52. package/dist/components/ui/AsciiChart.js +47 -0
  53. package/dist/components/ui/Badge.d.ts +15 -0
  54. package/dist/components/ui/Badge.js +8 -0
  55. package/dist/components/ui/BitmapText.d.ts +25 -0
  56. package/dist/components/ui/BitmapText.js +21 -0
  57. package/dist/components/ui/BlogCard.d.ts +33 -0
  58. package/dist/components/ui/BlogCard.js +13 -0
  59. package/dist/components/ui/Breadcrumbs.d.ts +9 -0
  60. package/dist/components/ui/Breadcrumbs.js +7 -0
  61. package/dist/components/ui/Button.d.ts +74 -0
  62. package/dist/components/ui/Button.js +48 -0
  63. package/dist/components/ui/CTASection.d.ts +13 -0
  64. package/dist/components/ui/CTASection.js +7 -0
  65. package/dist/components/ui/Carousel.d.ts +30 -0
  66. package/dist/components/ui/Carousel.js +80 -0
  67. package/dist/components/ui/CheckboxGroup.d.ts +11 -0
  68. package/dist/components/ui/CheckboxGroup.js +20 -0
  69. package/dist/components/ui/CodeBlock.d.ts +11 -0
  70. package/dist/components/ui/CodeBlock.js +20 -0
  71. package/dist/components/ui/ContactForm.d.ts +25 -0
  72. package/dist/components/ui/ContactForm.js +26 -0
  73. package/dist/components/ui/CrtOverlay.d.ts +10 -0
  74. package/dist/components/ui/CrtOverlay.js +5 -0
  75. package/dist/components/ui/Divider.d.ts +12 -0
  76. package/dist/components/ui/Divider.js +7 -0
  77. package/dist/components/ui/Drawer.d.ts +16 -0
  78. package/dist/components/ui/Drawer.js +25 -0
  79. package/dist/components/ui/Dropdown.d.ts +10 -0
  80. package/dist/components/ui/Dropdown.js +21 -0
  81. package/dist/components/ui/FAQSection.d.ts +14 -0
  82. package/dist/components/ui/FAQSection.js +7 -0
  83. package/dist/components/ui/FeatureGrid.d.ts +18 -0
  84. package/dist/components/ui/FeatureGrid.js +14 -0
  85. package/dist/components/ui/Footer.d.ts +14 -0
  86. package/dist/components/ui/Footer.js +16 -0
  87. package/dist/components/ui/GlyphCursor.d.ts +22 -0
  88. package/dist/components/ui/GlyphCursor.js +50 -0
  89. package/dist/components/ui/GridBackground.d.ts +15 -0
  90. package/dist/components/ui/GridBackground.js +6 -0
  91. package/dist/components/ui/Hero.d.ts +21 -0
  92. package/dist/components/ui/Hero.js +12 -0
  93. package/dist/components/ui/HoverFX.d.ts +29 -0
  94. package/dist/components/ui/HoverFX.js +75 -0
  95. package/dist/components/ui/Icon.d.ts +33 -0
  96. package/dist/components/ui/Icon.js +29 -0
  97. package/dist/components/ui/ImageGallery.d.ts +31 -0
  98. package/dist/components/ui/ImageGallery.js +79 -0
  99. package/dist/components/ui/LogoCloud.d.ts +12 -0
  100. package/dist/components/ui/LogoCloud.js +9 -0
  101. package/dist/components/ui/MagneticButton.d.ts +12 -0
  102. package/dist/components/ui/MagneticButton.js +49 -0
  103. package/dist/components/ui/Marquee.d.ts +29 -0
  104. package/dist/components/ui/Marquee.js +15 -0
  105. package/dist/components/ui/Modal.d.ts +40 -0
  106. package/dist/components/ui/Modal.js +51 -0
  107. package/dist/components/ui/NavBar.d.ts +14 -0
  108. package/dist/components/ui/NavBar.js +12 -0
  109. package/dist/components/ui/NeonSign.d.ts +14 -0
  110. package/dist/components/ui/NeonSign.js +7 -0
  111. package/dist/components/ui/OtpInput.d.ts +9 -0
  112. package/dist/components/ui/OtpInput.js +27 -0
  113. package/dist/components/ui/Pagination.d.ts +10 -0
  114. package/dist/components/ui/Pagination.js +24 -0
  115. package/dist/components/ui/Panel.d.ts +21 -0
  116. package/dist/components/ui/Panel.js +8 -0
  117. package/dist/components/ui/PixelFrame.d.ts +61 -0
  118. package/dist/components/ui/PixelFrame.js +29 -0
  119. package/dist/components/ui/Presence.d.ts +51 -0
  120. package/dist/components/ui/Presence.js +343 -0
  121. package/dist/components/ui/PricingCard.d.ts +30 -0
  122. package/dist/components/ui/PricingCard.js +21 -0
  123. package/dist/components/ui/PricingSection.d.ts +35 -0
  124. package/dist/components/ui/PricingSection.js +21 -0
  125. package/dist/components/ui/Progress.d.ts +17 -0
  126. package/dist/components/ui/Progress.js +9 -0
  127. package/dist/components/ui/RadioGroup.d.ts +10 -0
  128. package/dist/components/ui/RadioGroup.js +11 -0
  129. package/dist/components/ui/RangeSlider.d.ts +14 -0
  130. package/dist/components/ui/RangeSlider.js +11 -0
  131. package/dist/components/ui/Reveal.d.ts +48 -0
  132. package/dist/components/ui/Reveal.js +181 -0
  133. package/dist/components/ui/SceneFlash.d.ts +14 -0
  134. package/dist/components/ui/SceneFlash.js +51 -0
  135. package/dist/components/ui/ScrambleText.d.ts +31 -0
  136. package/dist/components/ui/ScrambleText.js +51 -0
  137. package/dist/components/ui/ScrollArea.d.ts +15 -0
  138. package/dist/components/ui/ScrollArea.js +18 -0
  139. package/dist/components/ui/SectionHeader.d.ts +12 -0
  140. package/dist/components/ui/SectionHeader.js +6 -0
  141. package/dist/components/ui/Select.d.ts +17 -0
  142. package/dist/components/ui/Select.js +31 -0
  143. package/dist/components/ui/Skeleton.d.ts +12 -0
  144. package/dist/components/ui/Skeleton.js +18 -0
  145. package/dist/components/ui/Spinner.d.ts +15 -0
  146. package/dist/components/ui/Spinner.js +24 -0
  147. package/dist/components/ui/Spotlight.d.ts +16 -0
  148. package/dist/components/ui/Spotlight.js +16 -0
  149. package/dist/components/ui/Sprite.d.ts +27 -0
  150. package/dist/components/ui/Sprite.js +19 -0
  151. package/dist/components/ui/StatCounter.d.ts +24 -0
  152. package/dist/components/ui/StatCounter.js +70 -0
  153. package/dist/components/ui/StatsSection.d.ts +14 -0
  154. package/dist/components/ui/StatsSection.js +13 -0
  155. package/dist/components/ui/Stepper.d.ts +10 -0
  156. package/dist/components/ui/Stepper.js +7 -0
  157. package/dist/components/ui/Table.d.ts +10 -0
  158. package/dist/components/ui/Table.js +8 -0
  159. package/dist/components/ui/Tabs.d.ts +12 -0
  160. package/dist/components/ui/Tabs.js +18 -0
  161. package/dist/components/ui/TeamSection.d.ts +18 -0
  162. package/dist/components/ui/TeamSection.js +19 -0
  163. package/dist/components/ui/TerminalTyper.d.ts +20 -0
  164. package/dist/components/ui/TerminalTyper.js +45 -0
  165. package/dist/components/ui/Testimonial.d.ts +19 -0
  166. package/dist/components/ui/Testimonial.js +9 -0
  167. package/dist/components/ui/TestimonialSection.d.ts +20 -0
  168. package/dist/components/ui/TestimonialSection.js +15 -0
  169. package/dist/components/ui/TextField.d.ts +26 -0
  170. package/dist/components/ui/TextField.js +13 -0
  171. package/dist/components/ui/TextmodeBackground.d.ts +52 -0
  172. package/dist/components/ui/TextmodeBackground.js +83 -0
  173. package/dist/components/ui/Timeline.d.ts +13 -0
  174. package/dist/components/ui/Timeline.js +8 -0
  175. package/dist/components/ui/Toast.d.ts +30 -0
  176. package/dist/components/ui/Toast.js +47 -0
  177. package/dist/components/ui/Toggle.d.ts +13 -0
  178. package/dist/components/ui/Toggle.js +10 -0
  179. package/dist/components/ui/Tooltip.d.ts +20 -0
  180. package/dist/components/ui/Tooltip.js +20 -0
  181. package/dist/components/ui/Typewriter.d.ts +20 -0
  182. package/dist/components/ui/Typewriter.js +46 -0
  183. package/dist/components/ui/VideoPlayer.d.ts +81 -0
  184. package/dist/components/ui/VideoPlayer.js +379 -0
  185. package/dist/components/ui/fill.d.ts +32 -0
  186. package/dist/components/ui/fill.js +27 -0
  187. package/dist/components/ui/intent.d.ts +20 -0
  188. package/dist/components/ui/intent.js +23 -0
  189. package/dist/components/ui/styles/kit.css +31 -0
  190. package/dist/components/ui/styles/ui-carousel.css +113 -0
  191. package/dist/components/ui/styles/ui-kit.css +1135 -0
  192. package/dist/components/ui/styles/ui-video.css +75 -0
  193. package/dist/components/ui/swiperCss.d.ts +15 -0
  194. package/dist/components/ui/swiperCss.js +15 -0
  195. package/dist/components/ui/variants.d.ts +12 -0
  196. package/dist/components/ui/variants.js +10 -0
  197. package/dist/index.d.ts +77 -0
  198. package/dist/index.js +77 -0
  199. package/dist/lib/asciify/painters.d.ts +25 -0
  200. package/dist/lib/asciify/painters.js +604 -0
  201. package/dist/lib/asciify/pointer.d.ts +12 -0
  202. package/dist/lib/asciify/pointer.js +54 -0
  203. package/dist/lib/asciify/shape-painters.d.ts +44 -0
  204. package/dist/lib/asciify/shape-painters.js +335 -0
  205. package/dist/lib/asciify/theme-painters.d.ts +8 -0
  206. package/dist/lib/asciify/theme-painters.js +437 -0
  207. package/dist/lib/cells.d.ts +46 -0
  208. package/dist/lib/cells.js +114 -0
  209. package/dist/lib/scroll/store.d.ts +21 -0
  210. package/dist/lib/scroll/store.js +25 -0
  211. package/dist/lib/sketches/aurora.d.ts +3 -0
  212. package/dist/lib/sketches/aurora.js +42 -0
  213. package/dist/lib/sketches/fire.d.ts +3 -0
  214. package/dist/lib/sketches/fire.js +80 -0
  215. package/dist/lib/sketches/flow.d.ts +3 -0
  216. package/dist/lib/sketches/flow.js +70 -0
  217. package/dist/lib/sketches/life.d.ts +3 -0
  218. package/dist/lib/sketches/life.js +107 -0
  219. package/dist/lib/sketches/matrix.d.ts +3 -0
  220. package/dist/lib/sketches/matrix.js +64 -0
  221. package/dist/lib/sketches/ocean.d.ts +3 -0
  222. package/dist/lib/sketches/ocean.js +56 -0
  223. package/dist/lib/sketches/plasma.d.ts +3 -0
  224. package/dist/lib/sketches/plasma.js +29 -0
  225. package/dist/lib/sketches/registry.d.ts +6 -0
  226. package/dist/lib/sketches/registry.js +60 -0
  227. package/dist/lib/sketches/ripples.d.ts +3 -0
  228. package/dist/lib/sketches/ripples.js +84 -0
  229. package/dist/lib/sketches/scroll-assemble.d.ts +8 -0
  230. package/dist/lib/sketches/scroll-assemble.js +90 -0
  231. package/dist/lib/sketches/scroll-parallax.d.ts +6 -0
  232. package/dist/lib/sketches/scroll-parallax.js +76 -0
  233. package/dist/lib/sketches/scroll-rain.d.ts +6 -0
  234. package/dist/lib/sketches/scroll-rain.js +82 -0
  235. package/dist/lib/sketches/scroll-stats.d.ts +7 -0
  236. package/dist/lib/sketches/scroll-stats.js +81 -0
  237. package/dist/lib/sketches/scroll-terminal.d.ts +6 -0
  238. package/dist/lib/sketches/scroll-terminal.js +87 -0
  239. package/dist/lib/sketches/scroll-zoom.d.ts +7 -0
  240. package/dist/lib/sketches/scroll-zoom.js +49 -0
  241. package/dist/lib/sketches/starfield.d.ts +3 -0
  242. package/dist/lib/sketches/starfield.js +54 -0
  243. package/dist/lib/sketches/text-3d.d.ts +6 -0
  244. package/dist/lib/sketches/text-3d.js +62 -0
  245. package/dist/lib/sketches/text-combo-figlet.d.ts +6 -0
  246. package/dist/lib/sketches/text-combo-figlet.js +91 -0
  247. package/dist/lib/sketches/text-glitch.d.ts +3 -0
  248. package/dist/lib/sketches/text-glitch.js +57 -0
  249. package/dist/lib/sketches/text-marquee.d.ts +3 -0
  250. package/dist/lib/sketches/text-marquee.js +35 -0
  251. package/dist/lib/sketches/text-particles.d.ts +9 -0
  252. package/dist/lib/sketches/text-particles.js +91 -0
  253. package/dist/lib/sketches/text-rain.d.ts +3 -0
  254. package/dist/lib/sketches/text-rain.js +73 -0
  255. package/dist/lib/sketches/text-scramble.d.ts +6 -0
  256. package/dist/lib/sketches/text-scramble.js +49 -0
  257. package/dist/lib/sketches/text-wave.d.ts +3 -0
  258. package/dist/lib/sketches/text-wave.js +43 -0
  259. package/dist/lib/sketches/theme-orbit.d.ts +6 -0
  260. package/dist/lib/sketches/theme-orbit.js +119 -0
  261. package/dist/lib/sketches/theme-pulse.d.ts +7 -0
  262. package/dist/lib/sketches/theme-pulse.js +84 -0
  263. package/dist/lib/sketches/tunnel.d.ts +3 -0
  264. package/dist/lib/sketches/tunnel.js +28 -0
  265. package/dist/lib/text/banner.d.ts +5 -0
  266. package/dist/lib/text/banner.js +35 -0
  267. package/dist/lib/text/mask.d.ts +40 -0
  268. package/dist/lib/text/mask.js +143 -0
  269. package/dist/lib/text/store.d.ts +23 -0
  270. package/dist/lib/text/store.js +86 -0
  271. package/dist/lib/ui/card-fields.d.ts +52 -0
  272. package/dist/lib/ui/card-fields.js +193 -0
  273. package/dist/lib/ui/fonts.d.ts +56 -0
  274. package/dist/lib/ui/fonts.js +94 -0
  275. package/dist/lib/ui/fx.d.ts +42 -0
  276. package/dist/lib/ui/fx.js +162 -0
  277. package/dist/lib/ui/icons.d.ts +437 -0
  278. package/dist/lib/ui/icons.js +314 -0
  279. package/dist/lib/ui/placeholder.d.ts +11 -0
  280. package/dist/lib/ui/placeholder.js +65 -0
  281. package/dist/lib/ui/tokens.d.ts +49 -0
  282. package/dist/lib/ui/tokens.js +129 -0
  283. package/dist/lib/ui/useTokens.d.ts +10 -0
  284. package/dist/lib/ui/useTokens.js +32 -0
  285. package/package.json +80 -0
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Sólidos geométricos básicos como nube de "píxeles" cuadrados que gira, con el mismo lenguaje
3
+ * visual que el toro: fondo oscuro, color por posición sobre la superficie y rotación guiada por el
4
+ * puntero. A diferencia del toro, cada punto lleva su normal: se descartan las caras traseras y se
5
+ * sombrea con una luz fija, de modo que la forma se lee como un bloque duro y no como una nube.
6
+ */
7
+ import type { Painter } from "./painters.js";
8
+ /** Efectos de hover propios de cada forma (se aplican a los puntos proyectados, alrededor del puntero). */
9
+ export type ShapeFx = "none" | "repel" | "magnify" | "twist" | "explode" | "wave" | "magnet" | "snap" | "stretch";
10
+ /**
11
+ * Puesta en escena compartida por todos los sólidos: posición (fracción del lienzo, puede estar fuera de
12
+ * 0..1 para recortar la forma contra el borde), escala y efecto de hover. Un consumidor (p. ej. una landing)
13
+ * la modifica cada fotograma; el valor por defecto es "centrada, sin efecto", así que el resto de usos no cambian.
14
+ */
15
+ export declare const shapeView: {
16
+ x: number;
17
+ y: number;
18
+ s: number;
19
+ fx: ShapeFx;
20
+ };
21
+ export declare const resetShapeView: () => {
22
+ x: number;
23
+ y: number;
24
+ s: number;
25
+ fx: ShapeFx;
26
+ } & {
27
+ x: number;
28
+ y: number;
29
+ s: number;
30
+ fx: ShapeFx;
31
+ };
32
+ export declare const shapePainters: {
33
+ cube: () => Painter;
34
+ pyramid: () => Painter;
35
+ sphere: () => Painter;
36
+ cylinder: () => Painter;
37
+ cone: () => Painter;
38
+ octahedron: () => Painter;
39
+ tetrahedron: () => Painter;
40
+ icosahedron: () => Painter;
41
+ hexprism: () => Painter;
42
+ diamond: () => Painter;
43
+ torusknot: () => Painter;
44
+ };
@@ -0,0 +1,335 @@
1
+ const TAU = Math.PI * 2;
2
+ const sub = (a, b) => [a[0] - b[0], a[1] - b[1], a[2] - b[2]];
3
+ const cross = (a, b) => [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
4
+ const norm = (a) => {
5
+ const l = Math.hypot(a[0], a[1], a[2]) || 1;
6
+ return [a[0] / l, a[1] / l, a[2] / l];
7
+ };
8
+ /** Añade un punto; `u` (matiz) sale del ángulo alrededor del eje vertical. */
9
+ function push(out, p, n) {
10
+ const h = Math.sin(out.length * 127.1 + 311.7) * 43758.5453;
11
+ out.push({ x: p[0], y: p[1], z: p[2], nx: n[0], ny: n[1], nz: n[2], u: Math.atan2(p[2], p[0]) + Math.PI, r: h - Math.floor(h) });
12
+ }
13
+ /** Normal de una cara, orientada hacia fuera (el origen queda dentro de todos los sólidos). */
14
+ function faceNormal(a, b, c) {
15
+ let n = norm(cross(sub(b, a), sub(c, a)));
16
+ const cx = (a[0] + b[0] + c[0]) / 3, cy = (a[1] + b[1] + c[1]) / 3, cz = (a[2] + b[2] + c[2]) / 3;
17
+ if (n[0] * cx + n[1] * cy + n[2] * cz < 0)
18
+ n = [-n[0], -n[1], -n[2]];
19
+ return n;
20
+ }
21
+ function tri(out, A, B, C, n) {
22
+ const nm = faceNormal(A, B, C);
23
+ for (let i = 0; i <= n; i++) {
24
+ for (let j = 0; j <= n - i; j++) {
25
+ const a = i / n, b = j / n, c = 1 - a - b;
26
+ push(out, [A[0] * c + B[0] * a + C[0] * b, A[1] * c + B[1] * a + C[1] * b, A[2] * c + B[2] * a + C[2] * b], nm);
27
+ }
28
+ }
29
+ }
30
+ function quad(out, A, B, D, n, m = n) {
31
+ const nm = faceNormal(A, B, D);
32
+ for (let i = 0; i <= n; i++) {
33
+ for (let j = 0; j <= m; j++) {
34
+ const s = i / n, t = j / m;
35
+ push(out, [A[0] + (B[0] - A[0]) * s + (D[0] - A[0]) * t, A[1] + (B[1] - A[1]) * s + (D[1] - A[1]) * t, A[2] + (B[2] - A[2]) * s + (D[2] - A[2]) * t], nm);
36
+ }
37
+ }
38
+ }
39
+ /** Disco relleno en el plano y = `y`, con anillos concéntricos de densidad constante. */
40
+ function disc(out, y, r, ny, step) {
41
+ push(out, [0, y, 0], [0, ny, 0]);
42
+ for (let r0 = step; r0 <= r + 1e-6; r0 += step) {
43
+ const m = Math.max(6, Math.round((TAU * r0) / step));
44
+ for (let k = 0; k < m; k++)
45
+ push(out, [Math.cos((k / m) * TAU) * r0, y, Math.sin((k / m) * TAU) * r0], [0, ny, 0]);
46
+ }
47
+ }
48
+ const cube = () => {
49
+ const s = 0.8, n = 22;
50
+ const c = (x, y, z) => [x * s, y * s, z * s];
51
+ const pts = [];
52
+ quad(pts, c(-1, -1, 1), c(1, -1, 1), c(-1, 1, 1), n); // frente
53
+ quad(pts, c(-1, -1, -1), c(1, -1, -1), c(-1, 1, -1), n); // fondo
54
+ quad(pts, c(-1, -1, -1), c(-1, -1, 1), c(-1, 1, -1), n); // izquierda
55
+ quad(pts, c(1, -1, -1), c(1, -1, 1), c(1, 1, -1), n); // derecha
56
+ quad(pts, c(-1, -1, -1), c(1, -1, -1), c(-1, -1, 1), n); // arriba
57
+ quad(pts, c(-1, 1, -1), c(1, 1, -1), c(-1, 1, 1), n); // abajo
58
+ return { pts, step: (2 * s) / n };
59
+ };
60
+ const pyramid = () => {
61
+ const h = 0.9, b = 0.95, n = 26;
62
+ const apex = [0, -h, 0];
63
+ const c = [[-b, h * 0.9, -b], [b, h * 0.9, -b], [b, h * 0.9, b], [-b, h * 0.9, b]];
64
+ const pts = [];
65
+ for (let i = 0; i < 4; i++)
66
+ tri(pts, apex, c[i], c[(i + 1) % 4], n);
67
+ quad(pts, c[0], c[1], c[3], n);
68
+ return { pts, step: (2 * b) / n * 1.05 };
69
+ };
70
+ const octahedron = () => {
71
+ const r = 1.15, n = 24;
72
+ const v = [[r, 0, 0], [-r, 0, 0], [0, r, 0], [0, -r, 0], [0, 0, r], [0, 0, -r]];
73
+ const pts = [];
74
+ for (const sx of [0, 1])
75
+ for (const sy of [2, 3])
76
+ for (const sz of [4, 5])
77
+ tri(pts, v[sx], v[sy], v[sz], n);
78
+ return { pts, step: (r * Math.SQRT2) / n };
79
+ };
80
+ const tetrahedron = () => {
81
+ const k = 0.85, n = 32;
82
+ const v = [[k, k, k], [k, -k, -k], [-k, k, -k], [-k, -k, k]];
83
+ const pts = [];
84
+ tri(pts, v[0], v[1], v[2], n);
85
+ tri(pts, v[0], v[1], v[3], n);
86
+ tri(pts, v[0], v[2], v[3], n);
87
+ tri(pts, v[1], v[2], v[3], n);
88
+ return { pts, step: (k * 2 * Math.SQRT2) / n };
89
+ };
90
+ const sphere = () => {
91
+ const N = 1700, R = 1.05, ga = Math.PI * (3 - Math.sqrt(5));
92
+ const pts = [];
93
+ for (let i = 0; i < N; i++) {
94
+ const y = 1 - (2 * (i + 0.5)) / N;
95
+ const rr = Math.sqrt(1 - y * y);
96
+ const nrm = [Math.cos(ga * i) * rr, y, Math.sin(ga * i) * rr];
97
+ push(pts, [nrm[0] * R, nrm[1] * R, nrm[2] * R], nrm);
98
+ }
99
+ return { pts, step: Math.sqrt((4 * Math.PI * R * R) / N) * 1.05 };
100
+ };
101
+ const cylinder = () => {
102
+ const r = 0.75, half = 0.9, step = 0.075;
103
+ const pts = [];
104
+ const m = Math.round((TAU * r) / step);
105
+ const rows = Math.round((2 * half) / step);
106
+ for (let j = 0; j <= rows; j++) {
107
+ for (let k = 0; k < m; k++) {
108
+ const a = (k / m) * TAU;
109
+ push(pts, [Math.cos(a) * r, -half + (j / rows) * 2 * half, Math.sin(a) * r], [Math.cos(a), 0, Math.sin(a)]);
110
+ }
111
+ }
112
+ disc(pts, -half, r, -1, step);
113
+ disc(pts, half, r, 1, step);
114
+ return { pts, step };
115
+ };
116
+ const cone = () => {
117
+ const R = 0.95, H = 1.9, step = 0.075;
118
+ const pts = [];
119
+ const slant = Math.hypot(R, H);
120
+ const rows = Math.round(slant / step);
121
+ for (let j = 0; j <= rows; j++) {
122
+ const f = j / rows; // 0 = ápice, 1 = base
123
+ const rr = R * f;
124
+ const m = Math.max(1, Math.round((TAU * rr) / step));
125
+ for (let k = 0; k < m; k++) {
126
+ const a = (k / m) * TAU;
127
+ push(pts, [Math.cos(a) * rr, -H / 2 + H * f, Math.sin(a) * rr], norm([Math.cos(a) * H, -R, Math.sin(a) * H]));
128
+ }
129
+ }
130
+ disc(pts, H / 2, R, 1, step);
131
+ return { pts, step };
132
+ };
133
+ const icosahedron = () => {
134
+ const phi = (1 + Math.sqrt(5)) / 2, R = 1.1, n = 22;
135
+ const raw = [];
136
+ for (const a of [-1, 1])
137
+ for (const b of [-phi, phi])
138
+ raw.push([0, a, b], [a, b, 0], [b, 0, a]);
139
+ const len = Math.hypot(...raw[0]);
140
+ const v = raw.map((p) => [(p[0] / len) * R, (p[1] / len) * R, (p[2] / len) * R]);
141
+ const dist = (a, b) => Math.hypot(a[0] - b[0], a[1] - b[1], a[2] - b[2]);
142
+ const edge = Math.min(...v.slice(1).map((p) => dist(v[0], p)));
143
+ const adj = (a, b) => Math.abs(dist(a, b) - edge) < 1e-6;
144
+ const pts = [];
145
+ for (let i = 0; i < v.length; i++)
146
+ for (let j = i + 1; j < v.length; j++)
147
+ for (let k = j + 1; k < v.length; k++) {
148
+ if (adj(v[i], v[j]) && adj(v[j], v[k]) && adj(v[i], v[k]))
149
+ tri(pts, v[i], v[j], v[k], n);
150
+ }
151
+ return { pts, step: (edge / n) * 1.05 };
152
+ };
153
+ const hexprism = () => {
154
+ const r = 0.9, half = 0.8, n = 22;
155
+ const top = (i) => [Math.cos((i / 6) * TAU) * r, -half, Math.sin((i / 6) * TAU) * r];
156
+ const bot = (i) => [Math.cos((i / 6) * TAU) * r, half, Math.sin((i / 6) * TAU) * r];
157
+ const pts = [];
158
+ for (let i = 0; i < 6; i++)
159
+ quad(pts, top(i), top(i + 1), bot(i), Math.round(n * 0.6), Math.round(n * 1.1));
160
+ for (let i = 0; i < 6; i++) {
161
+ tri(pts, [0, -half, 0], top(i), top(i + 1), 12);
162
+ tri(pts, [0, half, 0], bot(i), bot(i + 1), 12);
163
+ }
164
+ return { pts, step: r / 13 };
165
+ };
166
+ const diamond = () => {
167
+ const H = 1.25, r = 0.85, n = 22;
168
+ const e = (i) => [Math.cos((i / 6) * TAU) * r, 0, Math.sin((i / 6) * TAU) * r];
169
+ const pts = [];
170
+ for (let i = 0; i < 6; i++) {
171
+ tri(pts, [0, -H, 0], e(i), e(i + 1), n);
172
+ tri(pts, [0, H, 0], e(i), e(i + 1), n);
173
+ }
174
+ return { pts, step: (Math.hypot(r, H) / n) * 1.05 };
175
+ };
176
+ /** Nudo toroidal (2,3): tubo alrededor de una curva cerrada. Es cóncavo, así que se ordena por profundidad. */
177
+ const torusknot = () => {
178
+ const M = 380, K = 12, tube = 0.17, sc = 0.31;
179
+ const C = (t) => [(2 + Math.cos(3 * t)) * Math.cos(2 * t) * sc, (2 + Math.cos(3 * t)) * Math.sin(2 * t) * sc, Math.sin(3 * t) * sc * 1.15];
180
+ const pts = [];
181
+ const d = 1e-3;
182
+ for (let i = 0; i < M; i++) {
183
+ const t = (i / M) * TAU;
184
+ const p = C(t), a = C(t - d), b = C(t + d);
185
+ const T = norm(sub(b, a));
186
+ const acc = [b[0] + a[0] - 2 * p[0], b[1] + a[1] - 2 * p[1], b[2] + a[2] - 2 * p[2]];
187
+ const dot = acc[0] * T[0] + acc[1] * T[1] + acc[2] * T[2];
188
+ const N = norm([acc[0] - T[0] * dot, acc[1] - T[1] * dot, acc[2] - T[2] * dot]);
189
+ const B = cross(T, N);
190
+ for (let k = 0; k < K; k++) {
191
+ const a2 = (k / K) * TAU;
192
+ const nrm = [Math.cos(a2) * N[0] + Math.sin(a2) * B[0], Math.cos(a2) * N[1] + Math.sin(a2) * B[1], Math.cos(a2) * N[2] + Math.sin(a2) * B[2]];
193
+ push(pts, [p[0] + nrm[0] * tube, p[1] + nrm[1] * tube, p[2] + nrm[2] * tube], nrm);
194
+ }
195
+ }
196
+ return { pts, step: 0.1, sort: true };
197
+ };
198
+ const LIGHT = norm([-0.5, -0.7, 0.6]);
199
+ /**
200
+ * Puesta en escena compartida por todos los sólidos: posición (fracción del lienzo, puede estar fuera de
201
+ * 0..1 para recortar la forma contra el borde), escala y efecto de hover. Un consumidor (p. ej. una landing)
202
+ * la modifica cada fotograma; el valor por defecto es "centrada, sin efecto", así que el resto de usos no cambian.
203
+ */
204
+ export const shapeView = { x: 0.5, y: 0.5, s: 1, fx: "none" };
205
+ export const resetShapeView = () => Object.assign(shapeView, { x: 0.5, y: 0.5, s: 1, fx: "none" });
206
+ /** Convierte un constructor de sólido en un Painter con la misma puesta en escena que el toro. */
207
+ const make = (build) => () => {
208
+ const { pts, step, sort } = build();
209
+ let ax = 0.5;
210
+ let ay = 0;
211
+ let hv = 0; // intensidad del hover, con inercia
212
+ const vis = [];
213
+ return (ctx, w, h, t, p) => {
214
+ const bg = ctx.createRadialGradient(w / 2, h / 2, 0, w / 2, h / 2, Math.max(w, h) * 0.7);
215
+ bg.addColorStop(0, "#150a2e");
216
+ bg.addColorStop(1, "#03020a");
217
+ ctx.globalCompositeOperation = "source-over";
218
+ ctx.globalAlpha = 1;
219
+ ctx.fillStyle = bg;
220
+ ctx.fillRect(0, 0, w, h);
221
+ ax += 0.006 + (p.y - 0.5) * 0.03;
222
+ ay += 0.016 + (p.x - 0.5) * 0.04;
223
+ const ca = Math.cos(ax), sa = Math.sin(ax), cb = Math.cos(ay), sb = Math.sin(ay);
224
+ const S = Math.min(w, h) * 0.3 * shapeView.s * (p.down ? 1.25 : 1);
225
+ const cx = w * shapeView.x, cy = h * shapeView.y;
226
+ const hue0 = t * 30;
227
+ const fx = shapeView.fx;
228
+ hv += ((p.active && fx !== "none" ? 1 : 0) - hv) * 0.12;
229
+ const hx = p.x * w, hy = p.y * h;
230
+ const R = Math.min(w, h) * 0.36;
231
+ let n = 0;
232
+ for (const q of pts) {
233
+ // rotación X, luego Y (posición y normal)
234
+ const ny1 = q.ny * ca - q.nz * sa;
235
+ const nz1 = q.ny * sa + q.nz * ca;
236
+ const nz2 = -q.nx * sb + nz1 * cb;
237
+ if (nz2 < -0.02)
238
+ continue; // cara trasera
239
+ const nx2 = q.nx * cb + nz1 * sb;
240
+ const y1 = q.y * ca - q.z * sa;
241
+ const z1 = q.y * sa + q.z * ca;
242
+ const x2 = q.x * cb + z1 * sb;
243
+ const z2 = -q.x * sb + z1 * cb;
244
+ const persp = 3.2 / (3.2 - z2);
245
+ let px = cx + x2 * S * persp;
246
+ let py = cy + y1 * S * persp;
247
+ let s = step * S * persp * 1.25 + 1;
248
+ if (hv > 0.01) {
249
+ const dx = px - hx, dy = py - hy;
250
+ const d = Math.hypot(dx, dy) || 1;
251
+ let f = hv * Math.max(0, 1 - d / R);
252
+ f = f * f * (3 - 2 * f);
253
+ if (f > 0.002) {
254
+ const ux = dx / d, uy = dy / d;
255
+ if (fx === "repel") {
256
+ px += ux * f * R * 0.9;
257
+ py += uy * f * R * 0.9;
258
+ }
259
+ else if (fx === "magnify") {
260
+ const k = 1 + 1.8 * f;
261
+ px = hx + dx * k;
262
+ py = hy + dy * k;
263
+ s *= k;
264
+ }
265
+ else if (fx === "twist") {
266
+ const a = f * 3.4, c = Math.cos(a), sn = Math.sin(a);
267
+ px = hx + dx * c - dy * sn;
268
+ py = hy + dx * sn + dy * c;
269
+ }
270
+ else if (fx === "explode") {
271
+ px += ux * f * R * 1.5 + (q.r - 0.5) * f * R * 0.8;
272
+ py += uy * f * R * 1.5 + (((q.r * 7.13) % 1) - 0.5) * f * R * 0.8;
273
+ s *= 1 - f * 0.55;
274
+ }
275
+ else if (fx === "wave") {
276
+ const o = Math.sin(d * 0.11 - t * 11) * f * R * 0.3;
277
+ px += ux * o;
278
+ py += uy * o;
279
+ }
280
+ else if (fx === "magnet") {
281
+ px -= dx * f * 0.88;
282
+ py -= dy * f * 0.88;
283
+ s *= 1 + f;
284
+ }
285
+ else if (fx === "snap") {
286
+ const g = 3 + f * R * 0.24;
287
+ const m = Math.min(1, f * 2.5);
288
+ px += (Math.round(px / g) * g - px) * m;
289
+ py += (Math.round(py / g) * g - py) * m;
290
+ s = s * (1 - m) + g * 0.9 * m;
291
+ }
292
+ else if (fx === "stretch") {
293
+ px = hx + dx * (1 + 2.6 * f);
294
+ py = hy + dy * (1 - 0.35 * f);
295
+ }
296
+ }
297
+ }
298
+ const lam = Math.max(0, nx2 * LIGHT[0] + ny1 * LIGHT[1] + nz2 * LIGHT[2]);
299
+ const col = `hsl(${(q.u * 57.3 + hue0) % 360},85%,${22 + lam * 48}%)`;
300
+ if (sort) {
301
+ const v = (vis[n] ??= { px: 0, py: 0, z: 0, s: 0, col: "" });
302
+ v.px = px;
303
+ v.py = py;
304
+ v.z = z2;
305
+ v.s = s;
306
+ v.col = col;
307
+ n++;
308
+ }
309
+ else {
310
+ ctx.fillStyle = col;
311
+ ctx.fillRect(px - s / 2, py - s / 2, s, s);
312
+ }
313
+ }
314
+ if (sort) {
315
+ const list = vis.slice(0, n).sort((a, b) => a.z - b.z);
316
+ for (const v of list) {
317
+ ctx.fillStyle = v.col;
318
+ ctx.fillRect(v.px - v.s / 2, v.py - v.s / 2, v.s, v.s);
319
+ }
320
+ }
321
+ };
322
+ };
323
+ export const shapePainters = {
324
+ cube: make(cube),
325
+ pyramid: make(pyramid),
326
+ sphere: make(sphere),
327
+ cylinder: make(cylinder),
328
+ cone: make(cone),
329
+ octahedron: make(octahedron),
330
+ tetrahedron: make(tetrahedron),
331
+ icosahedron: make(icosahedron),
332
+ hexprism: make(hexprism),
333
+ diamond: make(diamond),
334
+ torusknot: make(torusknot),
335
+ };
@@ -0,0 +1,8 @@
1
+ import type { Painter } from "./painters.js";
2
+ export declare const themePainters: {
3
+ tide: () => Painter;
4
+ wave: () => Painter;
5
+ brew: () => Painter;
6
+ bloom: () => Painter;
7
+ arcade: () => Painter;
8
+ };