kmcom-nuxt-layers 1.0.1

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 (380) hide show
  1. package/.claude/rules/nuxt-layers.md +23 -0
  2. package/.claude/rules/typescript.md +16 -0
  3. package/.claude/rules/vue-components.md +34 -0
  4. package/.claude/settings.local.json +81 -0
  5. package/.editorconfig +27 -0
  6. package/.github/workflows/npm-publish.yml +33 -0
  7. package/.oxlintrc.json +10 -0
  8. package/.prettierignore +87 -0
  9. package/CLAUDE.md +71 -0
  10. package/apps/playground/README.md +75 -0
  11. package/apps/playground/app/app.config.ts +10 -0
  12. package/apps/playground/app/app.vue +12 -0
  13. package/apps/playground/app/components/AmbientBackground.client.vue +795 -0
  14. package/apps/playground/app/components/ShaderDemoCanvas.client.vue +636 -0
  15. package/apps/playground/app/components/ShaderImageDemo.client.vue +211 -0
  16. package/apps/playground/app/pages/ambient.vue +387 -0
  17. package/apps/playground/app/pages/content.vue +200 -0
  18. package/apps/playground/app/pages/core.vue +560 -0
  19. package/apps/playground/app/pages/forms.vue +645 -0
  20. package/apps/playground/app/pages/index.vue +257 -0
  21. package/apps/playground/app/pages/layout.vue +591 -0
  22. package/apps/playground/app/pages/locomotive-scroll.vue +738 -0
  23. package/apps/playground/app/pages/motion.vue +848 -0
  24. package/apps/playground/app/pages/shader.vue +1701 -0
  25. package/apps/playground/app/pages/theme.vue +115 -0
  26. package/apps/playground/app/pages/ui.vue +656 -0
  27. package/apps/playground/content/blog/hello-world.md +127 -0
  28. package/apps/playground/content/blog/second-post.md +99 -0
  29. package/apps/playground/content/blog/third-post.md +33 -0
  30. package/apps/playground/content/gallery/autumn-collection.md +57 -0
  31. package/apps/playground/content/gallery/summer-collection.md +52 -0
  32. package/apps/playground/content/pages/index.md +132 -0
  33. package/apps/playground/content/portfolio/project-one.md +90 -0
  34. package/apps/playground/content/portfolio/project-two.md +96 -0
  35. package/apps/playground/content.config.ts +93 -0
  36. package/apps/playground/nuxt.config.ts +99 -0
  37. package/apps/playground/package.json +17 -0
  38. package/apps/playground/public/favicon.ico +0 -0
  39. package/apps/playground/public/robots.txt +2 -0
  40. package/apps/playground/tsconfig.json +25 -0
  41. package/eslint.config.mjs +223 -0
  42. package/eslint.configCOPY.mjs +216 -0
  43. package/eslintconfigCURRENT.mjs +244 -0
  44. package/eslintconfigOLD.mjs +178 -0
  45. package/files for claude/Scroller.vue +31 -0
  46. package/files for claude/TextMarquee.vue +255 -0
  47. package/files for claude/gsap.client.ts +18 -0
  48. package/files for claude/gsap.ts +10 -0
  49. package/files for claude/scroll.ts +28 -0
  50. package/layers/content/app/assets/css/main.css +1 -0
  51. package/layers/content/app/components/Blog/Article.vue +29 -0
  52. package/layers/content/app/components/Blog/Card.vue +40 -0
  53. package/layers/content/app/components/Blog/List.vue +35 -0
  54. package/layers/content/app/components/Gallery/AmbientImage.vue +52 -0
  55. package/layers/content/app/components/Gallery/Card.vue +39 -0
  56. package/layers/content/app/components/Gallery/Detail.vue +76 -0
  57. package/layers/content/app/components/Gallery/Grid.vue +48 -0
  58. package/layers/content/app/components/Gallery/ImageDetail.vue +92 -0
  59. package/layers/content/app/components/Gallery/Lightbox.vue +102 -0
  60. package/layers/content/app/components/NuxtContent/Detail.vue +53 -0
  61. package/layers/content/app/components/NuxtContent/List.vue +21 -0
  62. package/layers/content/app/components/NuxtContent/Renderer.vue +14 -0
  63. package/layers/content/app/components/NuxtContent/Surround.vue +15 -0
  64. package/layers/content/app/components/NuxtContent/Toc.vue +18 -0
  65. package/layers/content/app/components/Portfolio/Card.vue +39 -0
  66. package/layers/content/app/components/Portfolio/ColorPalette.vue +39 -0
  67. package/layers/content/app/components/Portfolio/Detail.vue +49 -0
  68. package/layers/content/app/components/Portfolio/List.vue +44 -0
  69. package/layers/content/app/components/Portfolio/Typography.vue +37 -0
  70. package/layers/content/app/components/content/Figure.vue +31 -0
  71. package/layers/content/app/composables/useBlogPost.ts +3 -0
  72. package/layers/content/app/composables/useBlogPosts.ts +23 -0
  73. package/layers/content/app/composables/useCollectionItem.ts +5 -0
  74. package/layers/content/app/composables/useCollectionSurround.ts +9 -0
  75. package/layers/content/app/composables/useContentPage.ts +3 -0
  76. package/layers/content/app/composables/useGalleryItem.ts +3 -0
  77. package/layers/content/app/composables/useGalleryItems.ts +19 -0
  78. package/layers/content/app/composables/usePortfolioItem.ts +3 -0
  79. package/layers/content/app/composables/usePortfolioItems.ts +23 -0
  80. package/layers/content/app/pages/blog/[slug].vue +10 -0
  81. package/layers/content/app/pages/blog/index.vue +15 -0
  82. package/layers/content/app/pages/gallery/[slug]/[imageId].vue +11 -0
  83. package/layers/content/app/pages/gallery/[slug]/index.vue +10 -0
  84. package/layers/content/app/pages/gallery/index.vue +15 -0
  85. package/layers/content/app/pages/portfolio/[slug].vue +10 -0
  86. package/layers/content/app/pages/portfolio/index.vue +15 -0
  87. package/layers/content/app/types/content.ts +84 -0
  88. package/layers/content/app.config.ts +12 -0
  89. package/layers/content/content.config.ts +93 -0
  90. package/layers/content/nuxt.config.ts +31 -0
  91. package/layers/content/package.json +31 -0
  92. package/layers/content/tsconfig.json +6 -0
  93. package/layers/core/app/assets/css/base.css +88 -0
  94. package/layers/core/app/assets/css/layout.css +36 -0
  95. package/layers/core/app/assets/css/main.css +7 -0
  96. package/layers/core/app/assets/css-backup.zip +0 -0
  97. package/layers/core/app/components/ErrorBoundary.vue +102 -0
  98. package/layers/core/app/components/LoadingScreen.vue +137 -0
  99. package/layers/core/app/composables/useBrowser.ts +161 -0
  100. package/layers/core/app/composables/useCache.ts +138 -0
  101. package/layers/core/app/composables/useDevice.ts +36 -0
  102. package/layers/core/app/composables/useEnv.ts +23 -0
  103. package/layers/core/app/composables/useErrorLog.ts +158 -0
  104. package/layers/core/app/composables/useFeatures.ts +269 -0
  105. package/layers/core/app/composables/useLoading.ts +109 -0
  106. package/layers/core/app/composables/useNetworkInfo.ts +83 -0
  107. package/layers/core/app/composables/usePWAInfo.ts +104 -0
  108. package/layers/core/app/composables/useRendering.ts +97 -0
  109. package/layers/core/app/composables/useScreen.ts +95 -0
  110. package/layers/core/app/composables/useScrollGuard.ts +266 -0
  111. package/layers/core/app/error.vue +103 -0
  112. package/layers/core/app/layouts/default.vue +4 -0
  113. package/layers/core/app/pages/[...slug].vue +168 -0
  114. package/layers/core/app/pages/diagnostics.vue +228 -0
  115. package/layers/core/app/plugins/error-handler.ts +47 -0
  116. package/layers/core/app/plugins/feature-detection.client.ts +32 -0
  117. package/layers/core/app/plugins/init.ts +188 -0
  118. package/layers/core/app/plugins/loading.client.ts +54 -0
  119. package/layers/core/app/plugins/scroll-guard.client.ts +53 -0
  120. package/layers/core/app/types/detection.ts +117 -0
  121. package/layers/core/app/types/index.ts +10 -0
  122. package/layers/core/app/types/loading.ts +47 -0
  123. package/layers/core/app/types/runtime-config.ts +31 -0
  124. package/layers/core/app/types/scroll-guard.ts +25 -0
  125. package/layers/core/app/utils/helpers.ts +246 -0
  126. package/layers/core/app/utils/index.ts +8 -0
  127. package/layers/core/app/utils/regex.ts +6 -0
  128. package/layers/core/app.config.ts +193 -0
  129. package/layers/core/nuxt.config.ts +84 -0
  130. package/layers/core/package.json +25 -0
  131. package/layers/core/tailwind.config.js +28 -0
  132. package/layers/core/tsconfig.json +6 -0
  133. package/layers/forms/app/components/Form/Contact.vue +78 -0
  134. package/layers/forms/app/components/Form/Field.vue +85 -0
  135. package/layers/forms/app/composables/useFormSchema.ts +35 -0
  136. package/layers/forms/app/config/fields.ts +104 -0
  137. package/layers/forms/app/types/fields.ts +60 -0
  138. package/layers/forms/app.config.ts +12 -0
  139. package/layers/forms/nuxt.config.ts +17 -0
  140. package/layers/forms/package.json +17 -0
  141. package/layers/forms/tsconfig.json +6 -0
  142. package/layers/layout/.nuxtrc +1 -0
  143. package/layers/layout/CLAUDE.MD +186 -0
  144. package/layers/layout/GRID_SYSTEM.md +993 -0
  145. package/layers/layout/README.md +73 -0
  146. package/layers/layout/app/assets/css/layout/grids.css +180 -0
  147. package/layers/layout/app/assets/css/main.css +1 -0
  148. package/layers/layout/app/components/Layout/Grid/Debug.vue +79 -0
  149. package/layers/layout/app/components/Layout/Grid/Item.vue +180 -0
  150. package/layers/layout/app/components/Layout/Page/Container.vue +100 -0
  151. package/layers/layout/app/components/Layout/Page/Header.vue +33 -0
  152. package/layers/layout/app/components/Layout/Section/Gallery.vue +68 -0
  153. package/layers/layout/app/components/Layout/Section/Hero.vue +71 -0
  154. package/layers/layout/app/components/Layout/Section/Split.vue +56 -0
  155. package/layers/layout/app/components/Layout/Section/index.vue +39 -0
  156. package/layers/layout/app/composables/GridPlacement.ts +31 -0
  157. package/layers/layout/app/composables/useGridConfig.ts +27 -0
  158. package/layers/layout/app/types/layouts.ts +37 -0
  159. package/layers/layout/app.config.ts +97 -0
  160. package/layers/layout/nuxt.config.ts +14 -0
  161. package/layers/layout/package.json +14 -0
  162. package/layers/layout/tailwind.config.js +28 -0
  163. package/layers/layout/tsconfig.json +6 -0
  164. package/layers/motion/README.md +107 -0
  165. package/layers/motion/TASKS.MD +16 -0
  166. package/layers/motion/app/assets/css/main.css +111 -0
  167. package/layers/motion/app/components/Motion/Marquee.vue +171 -0
  168. package/layers/motion/app/components/Motion/Parallax.vue +75 -0
  169. package/layers/motion/app/components/Motion/ScrollLink.vue +49 -0
  170. package/layers/motion/app/components/Motion/ScrollProgress.vue +127 -0
  171. package/layers/motion/app/components/Motion/ScrollStats.vue +102 -0
  172. package/layers/motion/app/components/Motion/Staggered.vue +73 -0
  173. package/layers/motion/app/components/Motion/TextReveal.vue +101 -0
  174. package/layers/motion/app/components/Motion/Transition.vue +89 -0
  175. package/layers/motion/app/components/Motion/VelocityEffect.vue +139 -0
  176. package/layers/motion/app/components/Motion/index.vue +16 -0
  177. package/layers/motion/app/composables/useGsap.ts +21 -0
  178. package/layers/motion/app/composables/useMotion.ts +137 -0
  179. package/layers/motion/app/composables/useSmoothScroll.ts +154 -0
  180. package/layers/motion/app/plugins/gsap.client.ts +15 -0
  181. package/layers/motion/app/plugins/locomotive-scroll.client.ts +49 -0
  182. package/layers/motion/app/utils/gsapAnimations.ts +122 -0
  183. package/layers/motion/app.config.ts +30 -0
  184. package/layers/motion/nuxt.config.ts +19 -0
  185. package/layers/motion/package.json +17 -0
  186. package/layers/motion/tsconfig.json +6 -0
  187. package/layers/shader/AGENTS.MD +195 -0
  188. package/layers/shader/additional-modular-tsl-shaders-for-claude/.prettierignore +6 -0
  189. package/layers/shader/additional-modular-tsl-shaders-for-claude/.prettierrc +18 -0
  190. package/layers/shader/additional-modular-tsl-shaders-for-claude/LICENSE +21 -0
  191. package/layers/shader/additional-modular-tsl-shaders-for-claude/README.md +100 -0
  192. package/layers/shader/additional-modular-tsl-shaders-for-claude/index.html +13 -0
  193. package/layers/shader/additional-modular-tsl-shaders-for-claude/jsconfig.json +30 -0
  194. package/layers/shader/additional-modular-tsl-shaders-for-claude/package.json +18 -0
  195. package/layers/shader/additional-modular-tsl-shaders-for-claude/pnpm-lock.yaml +633 -0
  196. package/layers/shader/additional-modular-tsl-shaders-for-claude/public/vite.svg +1 -0
  197. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/components/sketch/webgpu_sketch.js +128 -0
  198. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/components/sketches_dropdown/index.css +87 -0
  199. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/components/sketches_dropdown/sketches_dropdown.js +169 -0
  200. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/index.css +25 -0
  201. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/main.js +93 -0
  202. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/router.js +43 -0
  203. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/sketches/flare-1.js +68 -0
  204. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/sketches/noise/dawn-1.js +56 -0
  205. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/distortion/bulge_distortion.js +35 -0
  206. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/distortion/swirl_distortion.js +35 -0
  207. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/distortion/wave_distortion.js +43 -0
  208. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/noise/common.js +145 -0
  209. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/noise/curl_noise_3d.js +53 -0
  210. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/noise/curl_noise_4d.js +55 -0
  211. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/noise/fbm.js +163 -0
  212. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/noise/perlin_noise_3d.js +70 -0
  213. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/noise/simplex_noise_3d.js +59 -0
  214. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/noise/simplex_noise_4d.js +72 -0
  215. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/noise/turbulence.js +41 -0
  216. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/patterns/canvas_weave_pattern.js +26 -0
  217. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/patterns/grain_texture_pattern.js +10 -0
  218. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/patterns/led_pattern.js +45 -0
  219. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/patterns/pixellation_pattern.js +15 -0
  220. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/patterns/speckled_noise_pattern.js +34 -0
  221. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/patterns/vignette_pattern.js +21 -0
  222. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/bulge_distortion_effect.js +27 -0
  223. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/chromatic_aberration_effect.js +45 -0
  224. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/crt_scanline_effect.js +45 -0
  225. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/dither_effect.js +126 -0
  226. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/grain_texture_effect.js +21 -0
  227. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/halftone_effect.js +44 -0
  228. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/led_effect.js +31 -0
  229. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/pixellation_effect.js +29 -0
  230. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/swirl_distortion_effect.js +25 -0
  231. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/vignette_effect.js +22 -0
  232. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/wave_distortion_effect.js +27 -0
  233. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/color/cosine_palette.js +15 -0
  234. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/color/tonemapping.js +151 -0
  235. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/function/bloom.js +13 -0
  236. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/function/bloom_edge_pattern.js +20 -0
  237. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/function/domain_index.js +11 -0
  238. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/function/median3.js +22 -0
  239. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/function/repeating_pattern.js +13 -0
  240. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/function/screen_aspect_uv.js +14 -0
  241. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/lighting.js +60 -0
  242. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/math/complex.js +86 -0
  243. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/math/coordinates.js +119 -0
  244. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/sdf/operations.js +24 -0
  245. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/sdf/shapes.js +182 -0
  246. package/layers/shader/additional-modular-tsl-shaders-for-claude/src/utils/math.js +33 -0
  247. package/layers/shader/additional-modular-tsl-shaders-for-claude/vite.config.js +23 -0
  248. package/layers/shader/app/assets/css/main.css +41 -0
  249. package/layers/shader/app/components/Effect/Bloom.vue +8 -0
  250. package/layers/shader/app/components/Effect/ChromaticAberration.vue +8 -0
  251. package/layers/shader/app/components/Effect/PostProcessing.vue +20 -0
  252. package/layers/shader/app/components/Material/AmbientAurora.vue +172 -0
  253. package/layers/shader/app/components/Material/AmbientFlow.vue +175 -0
  254. package/layers/shader/app/components/Material/AmbientGradientMesh.vue +173 -0
  255. package/layers/shader/app/components/Material/AmbientNebula.vue +181 -0
  256. package/layers/shader/app/components/Material/AmbientOcean.vue +161 -0
  257. package/layers/shader/app/components/Material/Fresnel.vue +89 -0
  258. package/layers/shader/app/components/Material/Gradient.vue +185 -0
  259. package/layers/shader/app/components/Material/Image.vue +232 -0
  260. package/layers/shader/app/components/Material/Node.vue +79 -0
  261. package/layers/shader/app/components/Material/Noise.vue +141 -0
  262. package/layers/shader/app/components/Mesh/Plane.vue +27 -0
  263. package/layers/shader/app/components/Shader/Background.vue +159 -0
  264. package/layers/shader/app/components/Shader/Canvas.vue +97 -0
  265. package/layers/shader/app/components/Shader/Debug.vue +66 -0
  266. package/layers/shader/app/components/WebGPUCanvas.client.vue +245 -0
  267. package/layers/shader/app/composables/useAmbientMaterials.ts +452 -0
  268. package/layers/shader/app/composables/useMousePosition.ts +94 -0
  269. package/layers/shader/app/composables/useRendererCapabilities.ts +111 -0
  270. package/layers/shader/app/composables/useShader.ts +148 -0
  271. package/layers/shader/app/composables/useShaderTime.ts +146 -0
  272. package/layers/shader/app/composables/useTSLNodes.ts +112 -0
  273. package/layers/shader/app/composables/useUniforms.ts +188 -0
  274. package/layers/shader/app/plugins/shader.client.ts +30 -0
  275. package/layers/shader/app/shaders/common/blend.ts +255 -0
  276. package/layers/shader/app/shaders/common/effects.ts +299 -0
  277. package/layers/shader/app/shaders/common/grain.ts +453 -0
  278. package/layers/shader/app/shaders/common/index.ts +22 -0
  279. package/layers/shader/app/shaders/common/lighting.ts +146 -0
  280. package/layers/shader/app/shaders/common/math.ts +250 -0
  281. package/layers/shader/app/shaders/common/noise.ts +823 -0
  282. package/layers/shader/app/shaders/common/noiseHelpers.ts +114 -0
  283. package/layers/shader/app/shaders/common/palette.ts +319 -0
  284. package/layers/shader/app/shaders/common/patterns.ts +216 -0
  285. package/layers/shader/app/shaders/common/sdf.ts +224 -0
  286. package/layers/shader/app/shaders/common/shapes.ts +366 -0
  287. package/layers/shader/app/shaders/common/tonemapping.ts +172 -0
  288. package/layers/shader/app/shaders/common/uv.ts +396 -0
  289. package/layers/shader/app/shaders/createMaterial.ts +314 -0
  290. package/layers/shader/app/shaders/index.ts +282 -0
  291. package/layers/shader/app/shaders/layers/aurora.ts +146 -0
  292. package/layers/shader/app/shaders/layers/index.ts +19 -0
  293. package/layers/shader/app/shaders/layers/meshGradient.ts +152 -0
  294. package/layers/shader/app/shaders/layers/paperShading.ts +148 -0
  295. package/layers/shader/app/shaders/layers/shaderGradient.ts +152 -0
  296. package/layers/shader/app/shaders/layers/stripe.ts +137 -0
  297. package/layers/shader/app/shaders/types.ts +12 -0
  298. package/layers/shader/app/types/index.ts +4 -0
  299. package/layers/shader/app/types/materials.ts +45 -0
  300. package/layers/shader/app/types/renderer.ts +50 -0
  301. package/layers/shader/app/types/tsl.ts +39 -0
  302. package/layers/shader/app/types/uniforms.ts +21 -0
  303. package/layers/shader/app/utils/tsl/animation.ts +251 -0
  304. package/layers/shader/app/utils/tsl/color.ts +189 -0
  305. package/layers/shader/app/utils/tsl/index.ts +84 -0
  306. package/layers/shader/app/utils/tsl/math.ts +111 -0
  307. package/layers/shader/app/utils/tsl/noise.ts +195 -0
  308. package/layers/shader/app/utils/tsl/patterns.ts +183 -0
  309. package/layers/shader/app/utils/tsl/uv.ts +145 -0
  310. package/layers/shader/app.config.ts +18 -0
  311. package/layers/shader/modular-tsl-shaders-for-claude/common/blend.tsl +1 -0
  312. package/layers/shader/modular-tsl-shaders-for-claude/common/noise.tsl +1 -0
  313. package/layers/shader/modular-tsl-shaders-for-claude/common/shapes.tsl +1 -0
  314. package/layers/shader/modular-tsl-shaders-for-claude/common/vertexFresnel.tsl +9 -0
  315. package/layers/shader/modular-tsl-shaders-for-claude/common/vertexPlane.tsl +6 -0
  316. package/layers/shader/modular-tsl-shaders-for-claude/effects/background.tsl +1 -0
  317. package/layers/shader/modular-tsl-shaders-for-claude/effects/gradient.tsl +1 -0
  318. package/layers/shader/modular-tsl-shaders-for-claude/effects/gradientLegend.tsl +1 -0
  319. package/layers/shader/modular-tsl-shaders-for-claude/effects/simpleGradient.tsl +1 -0
  320. package/layers/shader/modular-tsl-shaders-for-claude/layers/aurora.ts +1 -0
  321. package/layers/shader/modular-tsl-shaders-for-claude/layers/fragmentsTech.ts +1 -0
  322. package/layers/shader/modular-tsl-shaders-for-claude/layers/fresnel.ts +1 -0
  323. package/layers/shader/modular-tsl-shaders-for-claude/layers/linearGradient.ts +1 -0
  324. package/layers/shader/modular-tsl-shaders-for-claude/layers/meshGradient.ts +1 -0
  325. package/layers/shader/modular-tsl-shaders-for-claude/layers/noise.ts +1 -0
  326. package/layers/shader/modular-tsl-shaders-for-claude/layers/paperShading.ts +1 -0
  327. package/layers/shader/modular-tsl-shaders-for-claude/layers/radial.ts +1 -0
  328. package/layers/shader/modular-tsl-shaders-for-claude/layers/shaderGradient.ts +1 -0
  329. package/layers/shader/modular-tsl-shaders-for-claude/layers/stripe.ts +1 -0
  330. package/layers/shader/modular-tsl-shaders-for-claude/materials/createMaterial.ts +1 -0
  331. package/layers/shader/modular-tsl-shaders-for-claude/utils/glslUtils.ts +1 -0
  332. package/layers/shader/modular-tsl-shaders-for-claude/utils/palette.ts +1 -0
  333. package/layers/shader/nuxt.config.ts +48 -0
  334. package/layers/shader/package.json +17 -0
  335. package/layers/shader/tsconfig.json +6 -0
  336. package/layers/theme/app/assets/css/theme.css +47 -0
  337. package/layers/theme/app/components/ThemePicker/AccentButton.vue +51 -0
  338. package/layers/theme/app/components/ThemePicker/Colors.vue +22 -0
  339. package/layers/theme/app/components/ThemePicker/Menu.vue +108 -0
  340. package/layers/theme/app/components/ThemePicker/MenuButton.vue +9 -0
  341. package/layers/theme/app/composables/useThemePreferences.ts +158 -0
  342. package/layers/theme/app/plugins/theme.client.ts +5 -0
  343. package/layers/theme/app/types/theme.ts +34 -0
  344. package/layers/theme/app.config.ts +14 -0
  345. package/layers/theme/nuxt.config.ts +46 -0
  346. package/layers/theme/package.json +14 -0
  347. package/layers/theme/server/plugins/theme-fouc.ts +51 -0
  348. package/layers/theme/tsconfig.json +7 -0
  349. package/layers/ui/CLAUDE.MD +325 -0
  350. package/layers/ui/app/assets/css/main.css +4 -0
  351. package/layers/ui/app/components/Links/Group.vue +38 -0
  352. package/layers/ui/app/components/Links/Named.vue +32 -0
  353. package/layers/ui/app/components/Media/Picture.vue +41 -0
  354. package/layers/ui/app/components/Site/Title.vue +15 -0
  355. package/layers/ui/app/components/Typography/CodeBlock.vue +37 -0
  356. package/layers/ui/app/components/Typography/Headline.vue +73 -0
  357. package/layers/ui/app/components/Typography/QuoteBlock.vue +13 -0
  358. package/layers/ui/app/components/Typography/TextStroke.vue +109 -0
  359. package/layers/ui/app/components/Typography/index.vue +49 -0
  360. package/layers/ui/app/composables/color.ts +36 -0
  361. package/layers/ui/app/composables/picture.ts +145 -0
  362. package/layers/ui/app/composables/typography.ts +77 -0
  363. package/layers/ui/app/layouts/default.vue +4 -0
  364. package/layers/ui/app/pages/index.vue +236 -0
  365. package/layers/ui/app/types/breakpoints.ts +179 -0
  366. package/layers/ui/app/types/colors.ts +29 -0
  367. package/layers/ui/app/types/media.ts +185 -0
  368. package/layers/ui/app/types/typography.ts +108 -0
  369. package/layers/ui/app/utils/regex.ts +6 -0
  370. package/layers/ui/app.config.ts +12 -0
  371. package/layers/ui/nuxt.config.ts +38 -0
  372. package/layers/ui/package.json +14 -0
  373. package/layers/ui/tsconfig.json +6 -0
  374. package/package.json +128 -0
  375. package/playgroundOLD/app.config.ts +5 -0
  376. package/playgroundOLD/nuxt.config.ts +12 -0
  377. package/pnpm-workspace.yaml +6 -0
  378. package/prettier.config.cjs +19 -0
  379. package/stylelint.config.mjs +111 -0
  380. package/turbo.json +16 -0
@@ -0,0 +1,128 @@
1
+ import {
2
+ WebGPURenderer,
3
+ MeshBasicNodeMaterial,
4
+ PlaneGeometry,
5
+ Scene,
6
+ Mesh,
7
+ OrthographicCamera,
8
+ DoubleSide,
9
+ NoToneMapping,
10
+ LinearSRGBColorSpace,
11
+ } from 'three/webgpu'
12
+ import { vec3, Fn } from 'three/tsl'
13
+
14
+ class WebGPUSketch {
15
+ constructor(canvas, colorNode = null, onFrame = null) {
16
+ this._canvas = canvas
17
+
18
+ this._colorNode = colorNode
19
+ this._onFrame = onFrame
20
+
21
+ this._meshInitialized = false
22
+ }
23
+
24
+ async init() {
25
+ this._scene = new Scene()
26
+
27
+ // Viewport sizes
28
+ this._viewport = {
29
+ width: window.innerWidth,
30
+ height: window.innerHeight,
31
+ }
32
+
33
+ // Camera
34
+ this._camera = new OrthographicCamera(-1, 1, 1, -1, 0.1, 100)
35
+ this._camera.position.z = 1
36
+ this._scene.add(this._camera)
37
+
38
+ // Renderer
39
+ this._renderer = new WebGPURenderer({
40
+ canvas: this._canvas,
41
+ antialias: true,
42
+ toneMapping: NoToneMapping,
43
+ outputColorSpace: LinearSRGBColorSpace,
44
+ })
45
+ this._renderer.setSize(this._viewport.width, this._viewport.height)
46
+ this._renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
47
+ this._renderer.setClearColor('#000000')
48
+
49
+ window.addEventListener('resize', this._resizeHandler)
50
+ }
51
+
52
+ _initMesh() {
53
+ // Sketch geometry
54
+ this._geometry = new PlaneGeometry(1, 1, 1, 1)
55
+
56
+ // Sketch material
57
+ this._material = new MeshBasicNodeMaterial({
58
+ transparent: true,
59
+ side: DoubleSide,
60
+ depthWrite: false,
61
+ })
62
+ this._material.colorNode = this._colorNode ? this._colorNode : vec3(0, 0, 0)
63
+
64
+ // Add a fullscreeen sketch plane to the scene
65
+ this._mesh = new Mesh(this._geometry, this._material)
66
+ this._mesh.scale.set(2, 2, 1)
67
+ this._scene.add(this._mesh)
68
+ }
69
+
70
+ _resizeHandler = () => {
71
+ // Update sizes
72
+ this._viewport.width = window.innerWidth
73
+ this._viewport.height = window.innerHeight
74
+
75
+ // Update camera
76
+ this._camera.aspect = this._viewport.width / this._viewport.height
77
+ this._camera.updateProjectionMatrix()
78
+
79
+ // Update renderer
80
+ this._renderer.setSize(this._viewport.width, this._viewport.height)
81
+ this._renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
82
+ }
83
+
84
+ async render() {
85
+ if (!this._meshInitialized) {
86
+ this._initMesh()
87
+ this._meshInitialized = true
88
+ }
89
+
90
+ await this._renderer.renderAsync(this._scene, this._camera)
91
+
92
+ if (this._onFrame) {
93
+ this._onFrame(this._colorNode, this._renderer)
94
+ }
95
+
96
+ const frame = this.render.bind(this)
97
+ this._animationFrameId = window.requestAnimationFrame(frame)
98
+ }
99
+
100
+ dispose() {
101
+ // Cancel any pending animation frames
102
+ if (this._animationFrameId) {
103
+ window.cancelAnimationFrame(this._animationFrameId)
104
+ }
105
+
106
+ window.removeEventListener('resize', this._resizeHandler)
107
+
108
+ // Dispose geometry
109
+ if (this._geometry) {
110
+ this._geometry.dispose()
111
+ }
112
+
113
+ // Dispose material
114
+ if (this._material) {
115
+ this._material.dispose()
116
+ }
117
+
118
+ // Clear references
119
+ this._scene = null
120
+ this._geometry = null
121
+ this._material = null
122
+ this._camera = null
123
+ this._renderer = null
124
+ this._mesh = null
125
+ }
126
+ }
127
+
128
+ export default WebGPUSketch
@@ -0,0 +1,87 @@
1
+ .sketches-overlay {
2
+ position: fixed;
3
+ inset: 0;
4
+ pointer-events: none;
5
+ z-index: 10;
6
+ }
7
+
8
+ .sketches-toggle {
9
+ position: absolute;
10
+ top: 1rem;
11
+ left: 1rem;
12
+ pointer-events: auto;
13
+ font-size: 1.5rem;
14
+ z-index: 30;
15
+ }
16
+
17
+ .sketches-toggle__button {
18
+ padding: 8px 12px;
19
+ background: #111113;
20
+ border: none;
21
+ color: #edeef0;
22
+ transition: background 0.2s ease;
23
+ cursor: pointer;
24
+ }
25
+
26
+ .sketches-toggle__button:hover {
27
+ background: #272a2d;
28
+ }
29
+
30
+ .sketches-dropdown {
31
+ position: absolute;
32
+ top: 100%;
33
+ left: 0;
34
+ margin-top: 0.5rem;
35
+ background: rgba(0, 0, 0, 0.9);
36
+ backdrop-filter: blur(8px);
37
+ border: 1px solid rgba(255, 255, 255, 0.2);
38
+ min-width: 20rem;
39
+ max-width: 24rem;
40
+ max-height: 24rem;
41
+ overflow-y: auto;
42
+ pointer-events: auto;
43
+ z-index: 40;
44
+ }
45
+
46
+ .sketches-dropdown__content {
47
+ padding: 8px;
48
+ }
49
+
50
+ .sketches-list {
51
+ padding: 0;
52
+ font-family: ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
53
+ }
54
+
55
+ .sketches-list__grid {
56
+ display: flex;
57
+ flex-direction: column;
58
+ gap: 8px;
59
+ }
60
+
61
+ .sketch-card {
62
+ display: flex;
63
+ background: #212225;
64
+ transition:
65
+ background 0.2s ease-out,
66
+ transform 0.2s ease-out;
67
+ text-decoration: none;
68
+ flex-direction: column;
69
+ padding: 6px 10px;
70
+ }
71
+
72
+ .sketch-card:hover {
73
+ background: #272a2d;
74
+ }
75
+
76
+ .sketch-card__title {
77
+ color: white;
78
+ line-height: 1.2;
79
+ margin: 0;
80
+ font-size: 0.9rem;
81
+ font-weight: 500;
82
+ }
83
+
84
+ .sketch-card__path {
85
+ color: #9ca3af;
86
+ font-size: 0.9rem;
87
+ }
@@ -0,0 +1,169 @@
1
+ import './index.css'
2
+
3
+ class SketchesDropdown {
4
+ constructor() {
5
+ this.isVisible = false
6
+ this.sketches = []
7
+ this.dropdownRef = null
8
+ this.init()
9
+ }
10
+
11
+ async init() {
12
+ await this.loadSketches()
13
+ this.createDropdown()
14
+ this.attachEventListeners()
15
+ }
16
+
17
+ async loadSketches() {
18
+ // Use the same glob pattern as the sketches route
19
+ const sketchesGlob = import.meta.glob('@/sketches/**/*.js', {
20
+ eager: true,
21
+ })
22
+
23
+ console.log('Found sketches:', Object.keys(sketchesGlob))
24
+
25
+ this.sketches = Object.keys(sketchesGlob).map((filePath) => {
26
+ // Convert file path to URL path
27
+ // /src/sketches/flare-1.js -> flare-1
28
+ // /src/sketches/noise/dawn-1.js -> noise/dawn-1
29
+ console.log('Relative path:', filePath)
30
+ const relativePath = filePath.replace('/src/sketches/', '').replace('.js', '')
31
+ const url = `/sketches/${relativePath}`
32
+
33
+ // Extract name from path (last part before extension)
34
+ const name = relativePath.split('/').pop() || relativePath
35
+
36
+ return {
37
+ name,
38
+ path: `/${relativePath}`,
39
+ url,
40
+ }
41
+ })
42
+
43
+ console.log('Processed sketches:', this.sketches)
44
+ }
45
+
46
+ createDropdown() {
47
+ // Create the overlay container
48
+ const overlay = document.createElement('div')
49
+ overlay.className = 'sketches-overlay'
50
+
51
+ // Create the toggle container
52
+ const toggle = document.createElement('div')
53
+ toggle.className = 'sketches-toggle'
54
+
55
+ // Create the button
56
+ const button = document.createElement('button')
57
+ button.className = 'sketches-toggle__button'
58
+ button.textContent = 'Sketches'
59
+ button.addEventListener('click', () => this.toggleSketches())
60
+
61
+ // Create the dropdown
62
+ const dropdown = document.createElement('div')
63
+ dropdown.className = 'sketches-dropdown'
64
+ dropdown.style.display = 'none'
65
+
66
+ const content = document.createElement('div')
67
+ content.className = 'sketches-dropdown__content'
68
+
69
+ const list = document.createElement('div')
70
+ list.className = 'sketches-list'
71
+
72
+ const grid = document.createElement('div')
73
+ grid.className = 'sketches-list__grid'
74
+
75
+ // Create sketch cards
76
+ if (this.sketches.length === 0) {
77
+ const noSketches = document.createElement('div')
78
+ noSketches.className = 'sketch-card'
79
+ noSketches.textContent = 'No sketches found'
80
+ grid.appendChild(noSketches)
81
+ } else {
82
+ this.sketches.forEach((sketch) => {
83
+ const card = document.createElement('a')
84
+ card.className = 'sketch-card'
85
+ card.href = `#${sketch.url}`
86
+ card.addEventListener('click', (e) => {
87
+ e.preventDefault()
88
+ this.navigateToSketch(sketch.url)
89
+ this.hideSketches()
90
+ })
91
+
92
+ const title = document.createElement('h3')
93
+ title.className = 'sketch-card__title'
94
+ title.textContent = sketch.name
95
+
96
+ const path = document.createElement('div')
97
+ path.className = 'sketch-card__path'
98
+ path.textContent = sketch.path
99
+
100
+ card.appendChild(title)
101
+ card.appendChild(path)
102
+ grid.appendChild(card)
103
+ })
104
+ }
105
+
106
+ list.appendChild(grid)
107
+ content.appendChild(list)
108
+ dropdown.appendChild(content)
109
+ toggle.appendChild(button)
110
+ toggle.appendChild(dropdown)
111
+ overlay.appendChild(toggle)
112
+
113
+ // Store references
114
+ this.dropdownRef = toggle
115
+ this.dropdown = dropdown
116
+ this.overlay = overlay
117
+
118
+ // Add to DOM
119
+ document.body.appendChild(overlay)
120
+ }
121
+
122
+ attachEventListeners() {
123
+ // Handle click outside to close dropdown
124
+ document.addEventListener('mousedown', (event) => {
125
+ if (this.isVisible && this.dropdownRef && !this.dropdownRef.contains(event.target)) {
126
+ this.hideSketches()
127
+ }
128
+ })
129
+ }
130
+
131
+ toggleSketches() {
132
+ console.log('Toggle clicked, current state:', this.isVisible)
133
+ if (this.isVisible) {
134
+ this.hideSketches()
135
+ } else {
136
+ this.showSketches()
137
+ }
138
+ }
139
+
140
+ showSketches() {
141
+ console.log('Showing sketches dropdown')
142
+ this.isVisible = true
143
+ this.dropdown.style.display = 'block'
144
+ }
145
+
146
+ hideSketches() {
147
+ console.log('Hiding sketches dropdown')
148
+ this.isVisible = false
149
+ this.dropdown.style.display = 'none'
150
+ }
151
+
152
+ navigateToSketch(url) {
153
+ // Use the existing router navigation
154
+ if (window.router) {
155
+ window.router.navigate(url)
156
+ } else {
157
+ // Fallback to hash navigation
158
+ window.location.hash = url
159
+ }
160
+ }
161
+
162
+ destroy() {
163
+ if (this.overlay && this.overlay.parentNode) {
164
+ this.overlay.parentNode.removeChild(this.overlay)
165
+ }
166
+ }
167
+ }
168
+
169
+ export default SketchesDropdown
@@ -0,0 +1,25 @@
1
+ :root {
2
+ font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
3
+ line-height: 1.5;
4
+ font-weight: 400;
5
+
6
+ color-scheme: light dark;
7
+ color: rgba(255, 255, 255, 0.87);
8
+ background-color: #242424;
9
+
10
+ font-synthesis: none;
11
+ text-rendering: optimizeLegibility;
12
+ -webkit-font-smoothing: antialiased;
13
+ -moz-osx-font-smoothing: grayscale;
14
+ }
15
+
16
+ body {
17
+ margin: 0;
18
+ width: 100vw;
19
+ height: 100vh;
20
+ }
21
+
22
+ canvas {
23
+ width: 100%;
24
+ height: 100%;
25
+ }
@@ -0,0 +1,93 @@
1
+ import './index.css'
2
+
3
+ import {
4
+ WebGPURenderer,
5
+ MeshBasicNodeMaterial,
6
+ PlaneGeometry,
7
+ Scene,
8
+ Mesh,
9
+ OrthographicCamera,
10
+ DoubleSide,
11
+ NoToneMapping,
12
+ LinearSRGBColorSpace,
13
+ } from 'three/webgpu'
14
+ import Router from './router.js'
15
+ import SketchesDropdown from './components/sketches_dropdown/sketches_dropdown.js'
16
+ import WebGPUSketch from './components/sketch/webgpu_sketch.js'
17
+
18
+ // Preload all sketches using import.meta.glob
19
+ const sketches = import.meta.glob('./sketches/**/*.js', { eager: true })
20
+
21
+ let currentSketch = null
22
+
23
+ // Sketches dropdown
24
+ let sketchesDropdown = null
25
+
26
+ // Function to switch sketches using preloaded modules
27
+ async function switchSketch(sketchName) {
28
+ try {
29
+ // Dispose current sketch if it exists
30
+ if (currentSketch && currentSketch.dispose) {
31
+ currentSketch.dispose()
32
+ }
33
+
34
+ // Find the sketch module by path
35
+ const sketchPath = `./sketches/${sketchName}.js`
36
+ const sketchModule = sketches[sketchPath]
37
+
38
+ if (sketchModule) {
39
+ // Get the sketch (default export only)
40
+ const sketchExport = sketchModule.default
41
+
42
+ if (sketchExport) {
43
+ if (sketchExport instanceof WebGPUSketch) {
44
+ currentSketch = sketchExport
45
+ await currentSketch.init()
46
+ await currentSketch.render()
47
+ } else {
48
+ console.warn(`Sketch export is neither WebGPUSketch nor function: ${sketchName}`)
49
+ return
50
+ }
51
+
52
+ console.log(`Switched to sketch: ${sketchName}`)
53
+ } else {
54
+ console.warn(`Sketch function not found in module: ${sketchName}`)
55
+ }
56
+ } else {
57
+ console.warn(`Sketch not found: ${sketchName}`)
58
+ }
59
+ } catch (error) {
60
+ console.error(`Failed to load sketch: ${sketchName}`, error)
61
+ }
62
+ }
63
+
64
+ // Initialize app
65
+ async function init() {
66
+ // Initialize router with automatic route handling
67
+ const router = new Router(async (path) => {
68
+ // Handle different route patterns
69
+ if (path === '/' || path === '') {
70
+ await switchSketch('')
71
+ } else if (path.startsWith('/sketches/')) {
72
+ const sketchName = path.split('/sketches/')[1]
73
+ if (sketchName) {
74
+ await switchSketch(sketchName)
75
+ }
76
+ } else {
77
+ // Try to load sketch directly by name (remove leading slash)
78
+ const sketchName = path.slice(1)
79
+ await switchSketch(sketchName)
80
+ }
81
+ })
82
+
83
+ // Make router globally available for navigation
84
+ window.router = router
85
+
86
+ // Initialize sketches dropdown
87
+ console.log('Initializing sketches dropdown...')
88
+ sketchesDropdown = new SketchesDropdown()
89
+ console.log('Sketches dropdown initialized:', sketchesDropdown)
90
+ }
91
+
92
+ // Start the app
93
+ init()
@@ -0,0 +1,43 @@
1
+ class Router {
2
+ constructor(routeHandler) {
3
+ this.routeHandler = routeHandler
4
+ this.currentRoute = null
5
+ this.init()
6
+ }
7
+
8
+ // Initialize router and listen for hash changes
9
+ init() {
10
+ // Handle initial load
11
+ this.handleRoute()
12
+
13
+ // Listen for hash changes
14
+ window.addEventListener('hashchange', () => {
15
+ this.handleRoute()
16
+ })
17
+ }
18
+
19
+ // Parse current hash and execute route handler
20
+ handleRoute() {
21
+ const hash = window.location.hash.slice(1) // Remove #
22
+ const path = hash || '/'
23
+
24
+ this.currentRoute = path
25
+
26
+ // Call the route handler with the current path
27
+ if (this.routeHandler) {
28
+ this.routeHandler(path)
29
+ }
30
+ }
31
+
32
+ // Navigate to a route
33
+ navigate(path) {
34
+ window.location.hash = path
35
+ }
36
+
37
+ // Get current route
38
+ getCurrentRoute() {
39
+ return this.currentRoute
40
+ }
41
+ }
42
+
43
+ export default Router
@@ -0,0 +1,68 @@
1
+ /**
2
+ * @license Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)
3
+ *
4
+ * This sketch is licensed under CC BY-NC-SA 4.0. You are free to:
5
+ * - Share and adapt this work
6
+ * - Use modified versions commercially
7
+ *
8
+ * Under these conditions:
9
+ * - Attribution: Credit Ben McCormick (phobon) and link to this project
10
+ * - NonCommercial: Don't sell the original, unmodified sketch
11
+ * - ShareAlike: Distribute derivatives under the same license
12
+ */
13
+
14
+ import { abs, Fn, oneMinus, screenSize, uv, vec3, floor, sin, PI, mul, Loop, vec2 } from 'three/tsl'
15
+ import { cosinePalette } from '@/tsl/utils/color/cosine_palette'
16
+ import { screenAspectUV } from '@/tsl/utils/function/screen_aspect_uv'
17
+ import { grainTexturePattern } from '@/tsl/patterns/grain_texture_pattern'
18
+ import WebGPUSketch from '@/components/sketch/webgpu_sketch'
19
+
20
+ /**
21
+ * A gradient sketch with fractionated coordinates.
22
+ */
23
+ const flare1 = Fn(() => {
24
+ // Get aspect-corrected UVs for the screen
25
+ const _uv = screenAspectUV(screenSize)
26
+ const uv0 = uv().toVar()
27
+
28
+ // Color accumulator
29
+ const finalColor = vec3(0).toVar()
30
+
31
+ // Palette setup
32
+ const a = vec3(0.5, 0.5, 0.5)
33
+ const b = vec3(0.5, 0.5, 0.5)
34
+ const c = vec3(2.0, 1.0, 0.0)
35
+ const d = vec3(0.5, 0.2, 0.25)
36
+
37
+ // Y-repeated pattern for banding
38
+ const repetitions = 12
39
+ const uvR = floor(_uv.y.mul(repetitions))
40
+
41
+ // Sine wave for vertical offset
42
+ const s = sin(uv0.y.mul(PI))
43
+
44
+ // Loop over bands
45
+ // @ts-ignore
46
+ Loop({ start: 0, end: repetitions }, ({ i: _i }) => {
47
+ const f = mul(uvR.mul(_i), 0.005)
48
+ const offsetUv = vec2(_uv.x, _uv.y.add(f).add(mul(s, 0.05)))
49
+
50
+ // Compound radial gradient
51
+ const r = oneMinus(abs(offsetUv.x.mul(1.5))).add(abs(offsetUv.y.mul(1.5)))
52
+
53
+ // Palette-based color
54
+ const col = cosinePalette(uv0.y.mul(0.25), a, b, c, d)
55
+
56
+ finalColor.assign(col.mul(r))
57
+ })
58
+ // Add grain for texture
59
+ const g = grainTexturePattern(uv0).mul(0.1)
60
+ finalColor.addAssign(g)
61
+
62
+ return finalColor
63
+ })
64
+
65
+ const canvas = document.querySelector('#webgpu-canvas')
66
+ const sketch = new WebGPUSketch(canvas, flare1())
67
+
68
+ export default sketch
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @license Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)
3
+ *
4
+ * This sketch is licensed under CC BY-NC-SA 4.0. You are free to:
5
+ * - Share and adapt this work
6
+ * - Use modified versions commercially
7
+ *
8
+ * Under these conditions:
9
+ * - Attribution: Credit Ben McCormick (phobon) and link to this project
10
+ * - NonCommercial: Don't sell the original, unmodified sketch
11
+ * - ShareAlike: Distribute derivatives under the same license
12
+ */
13
+
14
+ import { Fn, screenSize, vec3, fract, pow, time } from 'three/tsl'
15
+ import { cosinePalette } from '@/tsl/utils/color/cosine_palette'
16
+ import { screenAspectUV } from '@/tsl/utils/function/screen_aspect_uv'
17
+ import WebGPUSketch from '@/components/sketch/webgpu_sketch'
18
+ import { grainTexturePattern } from '@/tsl/patterns/grain_texture_pattern'
19
+
20
+ /**
21
+ * A gradient sketch tribute to Rik Oostenbroek.
22
+ */
23
+ const dawn1 = Fn(() => {
24
+ // Get aspect-corrected UVs for the screen
25
+ const _uv = screenAspectUV(screenSize).toVar()
26
+ const uv0 = screenAspectUV(screenSize).toVar()
27
+
28
+ // Color accumulator
29
+ const finalColor = vec3(0.0).toVar()
30
+
31
+ // Palette setup
32
+ const a = vec3(0.5, 0.5, 0.5)
33
+ const b = vec3(0.5, 0.5, 0.5)
34
+ const c = vec3(1.0, 1.0, 0.5)
35
+ const d = vec3(0.8, 0.9, 0.3)
36
+
37
+ // Animated vertical gradient using cosine palette
38
+ const col = cosinePalette(uv0.y.add(0.5).add(time.mul(0.01)), a, b, c, d)
39
+
40
+ // Repeated sawtooth pattern in Y, softened
41
+ const repeatedPattern = fract(_uv.y.mul(24)).mul(0.3)
42
+
43
+ // Add pattern to color, boost with pow for punch
44
+ finalColor.assign(col.add(pow(repeatedPattern, 2.0)))
45
+
46
+ // Add grain for texture
47
+ const _grain = grainTexturePattern(_uv).mul(0.2)
48
+ finalColor.addAssign(_grain)
49
+
50
+ return finalColor
51
+ })
52
+
53
+ const canvas = document.querySelector('#webgpu-canvas')
54
+ const sketch = new WebGPUSketch(canvas, dawn1())
55
+
56
+ export default sketch
@@ -0,0 +1,35 @@
1
+ import { Fn, vec2, float, length, normalize, mul, min, oneMinus, pow, smoothstep } from 'three/tsl'
2
+
3
+ /**
4
+ * Applies a bulge or pinch distortion to UV coordinates.
5
+ * @param {vec2} _uv - The UV coordinates - aspect corrected provide best results
6
+ * @param {Object} [options] - Optional configuration values.
7
+ * @param {number} [options.strength=0.5] - Strength of the effect (positive=bulge, negative=pinch)
8
+ * @param {number} [options.radius=0.5] - Radius of the distortion effect
9
+ * @param {number} [options.power=1.0] - Power curve for the falloff (higher = stronger center effect)
10
+ * @param {vec2} [options.center=vec2(0.0)] - Center point of the distortion
11
+ * @returns {vec2} Distorted UV coordinates
12
+ */
13
+ export const bulgeDistortion = Fn(([_uv, options = {}]) => {
14
+ const {
15
+ strength = float(0.5),
16
+ radius = float(0.5),
17
+ power = float(1.0),
18
+ center = vec2(0),
19
+ } = options
20
+ const uv = _uv.toVar()
21
+ const offset = uv.sub(center).toVar()
22
+ const dist = length(offset).toVar()
23
+
24
+ // Normalized distance within radius (0-1), smoothed to create a cleaner effect
25
+ const normalizedDist = smoothstep(0, 1, min(dist.div(radius), 1)).toVar()
26
+
27
+ // Use power curve to create stronger effect in the center
28
+ const falloff = pow(oneMinus(normalizedDist), power).mul(strength)
29
+
30
+ // Apply radial displacement
31
+ const direction = normalize(offset)
32
+ const displacedUV = center.add(direction.mul(dist.mul(falloff.add(float(1.0)))))
33
+
34
+ return displacedUV
35
+ })