@3driseai/3drise-viewer 0.1.40 → 0.1.41

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 (297) hide show
  1. package/dist/animationsV2/ClipsRuntime.d.ts.map +1 -1
  2. package/dist/animationsV2/ClipsRuntime.js +9 -5
  3. package/dist/animationsV2/clipUtils.d.ts +9 -0
  4. package/dist/animationsV2/clipUtils.d.ts.map +1 -1
  5. package/dist/animationsV2/clipUtils.js +11 -2
  6. package/dist/animationsV2/normalize.d.ts.map +1 -1
  7. package/dist/animationsV2/normalize.js +2 -0
  8. package/dist/animationsV2/types.d.ts +4 -0
  9. package/dist/animationsV2/types.d.ts.map +1 -1
  10. package/dist/api/sceneHandle.d.ts +40 -3
  11. package/dist/api/sceneHandle.d.ts.map +1 -1
  12. package/dist/api/sceneHandle.js +40 -0
  13. package/dist/components/GalleryObject.d.ts +13 -0
  14. package/dist/components/GalleryObject.d.ts.map +1 -0
  15. package/dist/components/GalleryObject.js +46 -0
  16. package/dist/components/ImageObject.d.ts +9 -0
  17. package/dist/components/ImageObject.d.ts.map +1 -0
  18. package/dist/components/ImageObject.js +26 -0
  19. package/dist/components/ObjectNode.d.ts.map +1 -1
  20. package/dist/components/ObjectNode.js +11 -5
  21. package/dist/components/ProjectLoader.d.ts +2 -0
  22. package/dist/components/ProjectLoader.d.ts.map +1 -1
  23. package/dist/components/ProjectLoader.js +2 -2
  24. package/dist/components/SceneBuilder.d.ts +10 -0
  25. package/dist/components/SceneBuilder.d.ts.map +1 -1
  26. package/dist/components/SceneBuilder.js +3 -2
  27. package/dist/components/gallery/BasicCarouselGallery.d.ts +18 -0
  28. package/dist/components/gallery/BasicCarouselGallery.d.ts.map +1 -0
  29. package/dist/components/gallery/BasicCarouselGallery.js +9 -0
  30. package/dist/components/gallery/ContourLinesGallery.d.ts +18 -0
  31. package/dist/components/gallery/ContourLinesGallery.d.ts.map +1 -0
  32. package/dist/components/gallery/ContourLinesGallery.js +9 -0
  33. package/dist/components/gallery/DepthLayersGallery.d.ts +18 -0
  34. package/dist/components/gallery/DepthLayersGallery.d.ts.map +1 -0
  35. package/dist/components/gallery/DepthLayersGallery.js +9 -0
  36. package/dist/components/gallery/EngravingGallery.d.ts +18 -0
  37. package/dist/components/gallery/EngravingGallery.d.ts.map +1 -0
  38. package/dist/components/gallery/EngravingGallery.js +9 -0
  39. package/dist/components/gallery/FlowLinesGallery.d.ts +18 -0
  40. package/dist/components/gallery/FlowLinesGallery.d.ts.map +1 -0
  41. package/dist/components/gallery/FlowLinesGallery.js +9 -0
  42. package/dist/components/gallery/FoldGallery.d.ts +18 -0
  43. package/dist/components/gallery/FoldGallery.d.ts.map +1 -0
  44. package/dist/components/gallery/FoldGallery.js +9 -0
  45. package/dist/components/gallery/GlassPanesGallery.d.ts +18 -0
  46. package/dist/components/gallery/GlassPanesGallery.d.ts.map +1 -0
  47. package/dist/components/gallery/GlassPanesGallery.js +9 -0
  48. package/dist/components/gallery/HaloGallery.d.ts +18 -0
  49. package/dist/components/gallery/HaloGallery.d.ts.map +1 -0
  50. package/dist/components/gallery/HaloGallery.js +9 -0
  51. package/dist/components/gallery/LightThreadsGallery.d.ts +18 -0
  52. package/dist/components/gallery/LightThreadsGallery.d.ts.map +1 -0
  53. package/dist/components/gallery/LightThreadsGallery.js +9 -0
  54. package/dist/components/gallery/LoomGallery.d.ts +18 -0
  55. package/dist/components/gallery/LoomGallery.d.ts.map +1 -0
  56. package/dist/components/gallery/LoomGallery.js +9 -0
  57. package/dist/components/gallery/PaperLanternsGallery.d.ts +18 -0
  58. package/dist/components/gallery/PaperLanternsGallery.d.ts.map +1 -0
  59. package/dist/components/gallery/PaperLanternsGallery.js +9 -0
  60. package/dist/components/gallery/ParticleShiftGallery.d.ts +18 -0
  61. package/dist/components/gallery/ParticleShiftGallery.d.ts.map +1 -0
  62. package/dist/components/gallery/ParticleShiftGallery.js +9 -0
  63. package/dist/components/gallery/PinscreenGallery.d.ts +18 -0
  64. package/dist/components/gallery/PinscreenGallery.d.ts.map +1 -0
  65. package/dist/components/gallery/PinscreenGallery.js +9 -0
  66. package/dist/components/gallery/PopUpGallery.d.ts +18 -0
  67. package/dist/components/gallery/PopUpGallery.d.ts.map +1 -0
  68. package/dist/components/gallery/PopUpGallery.js +9 -0
  69. package/dist/components/gallery/PrismSplitGallery.d.ts +18 -0
  70. package/dist/components/gallery/PrismSplitGallery.d.ts.map +1 -0
  71. package/dist/components/gallery/PrismSplitGallery.js +9 -0
  72. package/dist/components/gallery/RidgelinesGallery.d.ts +18 -0
  73. package/dist/components/gallery/RidgelinesGallery.d.ts.map +1 -0
  74. package/dist/components/gallery/RidgelinesGallery.js +9 -0
  75. package/dist/components/gallery/ShadowBoxGallery.d.ts +18 -0
  76. package/dist/components/gallery/ShadowBoxGallery.d.ts.map +1 -0
  77. package/dist/components/gallery/ShadowBoxGallery.js +9 -0
  78. package/dist/components/gallery/SilkGallery.d.ts +18 -0
  79. package/dist/components/gallery/SilkGallery.d.ts.map +1 -0
  80. package/dist/components/gallery/SilkGallery.js +9 -0
  81. package/dist/components/gallery/SlatsGallery.d.ts +18 -0
  82. package/dist/components/gallery/SlatsGallery.d.ts.map +1 -0
  83. package/dist/components/gallery/SlatsGallery.js +9 -0
  84. package/dist/components/gallery/StrataGallery.d.ts +18 -0
  85. package/dist/components/gallery/StrataGallery.d.ts.map +1 -0
  86. package/dist/components/gallery/StrataGallery.js +9 -0
  87. package/dist/components/gallery/TerracesGallery.d.ts +18 -0
  88. package/dist/components/gallery/TerracesGallery.d.ts.map +1 -0
  89. package/dist/components/gallery/TerracesGallery.js +9 -0
  90. package/dist/components/gallery/WireReliefGallery.d.ts +18 -0
  91. package/dist/components/gallery/WireReliefGallery.d.ts.map +1 -0
  92. package/dist/components/gallery/WireReliefGallery.js +9 -0
  93. package/dist/components/gallery/index.d.ts +46 -0
  94. package/dist/components/gallery/index.d.ts.map +1 -0
  95. package/dist/components/gallery/index.js +22 -0
  96. package/dist/components/gallery/kit/GalleryVariant.d.ts +68 -0
  97. package/dist/components/gallery/kit/GalleryVariant.d.ts.map +1 -0
  98. package/dist/components/gallery/kit/GalleryVariant.js +231 -0
  99. package/dist/components/gallery/kit/feeds.d.ts +7 -0
  100. package/dist/components/gallery/kit/feeds.d.ts.map +1 -0
  101. package/dist/components/gallery/kit/feeds.js +83 -0
  102. package/dist/components/gallery/kit/galleryKit.d.ts +118 -0
  103. package/dist/components/gallery/kit/galleryKit.d.ts.map +1 -0
  104. package/dist/components/gallery/kit/galleryKit.js +298 -0
  105. package/dist/components/gallery/kit/lookBase.d.ts +157 -0
  106. package/dist/components/gallery/kit/lookBase.d.ts.map +1 -0
  107. package/dist/components/gallery/kit/lookBase.js +211 -0
  108. package/dist/components/gallery/kit/pictures.d.ts +14 -0
  109. package/dist/components/gallery/kit/pictures.d.ts.map +1 -0
  110. package/dist/components/gallery/kit/pictures.js +81 -0
  111. package/dist/components/gallery/looks/basicCarousel.d.ts +177 -0
  112. package/dist/components/gallery/looks/basicCarousel.d.ts.map +1 -0
  113. package/dist/components/gallery/looks/basicCarousel.js +315 -0
  114. package/dist/components/gallery/looks/contourLines.d.ts +153 -0
  115. package/dist/components/gallery/looks/contourLines.d.ts.map +1 -0
  116. package/dist/components/gallery/looks/contourLines.js +91 -0
  117. package/dist/components/gallery/looks/depthLayers.d.ts +155 -0
  118. package/dist/components/gallery/looks/depthLayers.d.ts.map +1 -0
  119. package/dist/components/gallery/looks/depthLayers.js +87 -0
  120. package/dist/components/gallery/looks/engraving.d.ts +162 -0
  121. package/dist/components/gallery/looks/engraving.d.ts.map +1 -0
  122. package/dist/components/gallery/looks/engraving.js +96 -0
  123. package/dist/components/gallery/looks/flowLines.d.ts +180 -0
  124. package/dist/components/gallery/looks/flowLines.d.ts.map +1 -0
  125. package/dist/components/gallery/looks/flowLines.js +113 -0
  126. package/dist/components/gallery/looks/fold.d.ts +209 -0
  127. package/dist/components/gallery/looks/fold.d.ts.map +1 -0
  128. package/dist/components/gallery/looks/fold.js +155 -0
  129. package/dist/components/gallery/looks/glassPanes.d.ts +133 -0
  130. package/dist/components/gallery/looks/glassPanes.d.ts.map +1 -0
  131. package/dist/components/gallery/looks/glassPanes.js +208 -0
  132. package/dist/components/gallery/looks/halo.d.ts +100 -0
  133. package/dist/components/gallery/looks/halo.d.ts.map +1 -0
  134. package/dist/components/gallery/looks/halo.js +119 -0
  135. package/dist/components/gallery/looks/lightThreads.d.ts +199 -0
  136. package/dist/components/gallery/looks/lightThreads.d.ts.map +1 -0
  137. package/dist/components/gallery/looks/lightThreads.js +246 -0
  138. package/dist/components/gallery/looks/loom.d.ts +238 -0
  139. package/dist/components/gallery/looks/loom.d.ts.map +1 -0
  140. package/dist/components/gallery/looks/loom.js +256 -0
  141. package/dist/components/gallery/looks/paperLanterns.d.ts +181 -0
  142. package/dist/components/gallery/looks/paperLanterns.d.ts.map +1 -0
  143. package/dist/components/gallery/looks/paperLanterns.js +399 -0
  144. package/dist/components/gallery/looks/particleShift.d.ts +193 -0
  145. package/dist/components/gallery/looks/particleShift.d.ts.map +1 -0
  146. package/dist/components/gallery/looks/particleShift.js +282 -0
  147. package/dist/components/gallery/looks/pinscreen.d.ts +175 -0
  148. package/dist/components/gallery/looks/pinscreen.d.ts.map +1 -0
  149. package/dist/components/gallery/looks/pinscreen.js +96 -0
  150. package/dist/components/gallery/looks/popUp.d.ts +206 -0
  151. package/dist/components/gallery/looks/popUp.d.ts.map +1 -0
  152. package/dist/components/gallery/looks/popUp.js +132 -0
  153. package/dist/components/gallery/looks/prismSplit.d.ts +151 -0
  154. package/dist/components/gallery/looks/prismSplit.d.ts.map +1 -0
  155. package/dist/components/gallery/looks/prismSplit.js +84 -0
  156. package/dist/components/gallery/looks/ridgelines.d.ts +179 -0
  157. package/dist/components/gallery/looks/ridgelines.d.ts.map +1 -0
  158. package/dist/components/gallery/looks/ridgelines.js +111 -0
  159. package/dist/components/gallery/looks/shadowBox.d.ts +152 -0
  160. package/dist/components/gallery/looks/shadowBox.d.ts.map +1 -0
  161. package/dist/components/gallery/looks/shadowBox.js +82 -0
  162. package/dist/components/gallery/looks/silk.d.ts +140 -0
  163. package/dist/components/gallery/looks/silk.d.ts.map +1 -0
  164. package/dist/components/gallery/looks/silk.js +346 -0
  165. package/dist/components/gallery/looks/slats.d.ts +176 -0
  166. package/dist/components/gallery/looks/slats.d.ts.map +1 -0
  167. package/dist/components/gallery/looks/slats.js +93 -0
  168. package/dist/components/gallery/looks/strata.d.ts +172 -0
  169. package/dist/components/gallery/looks/strata.d.ts.map +1 -0
  170. package/dist/components/gallery/looks/strata.js +88 -0
  171. package/dist/components/gallery/looks/terraces.d.ts +168 -0
  172. package/dist/components/gallery/looks/terraces.d.ts.map +1 -0
  173. package/dist/components/gallery/looks/terraces.js +91 -0
  174. package/dist/components/gallery/looks/wireRelief.d.ts +153 -0
  175. package/dist/components/gallery/looks/wireRelief.d.ts.map +1 -0
  176. package/dist/components/gallery/looks/wireRelief.js +128 -0
  177. package/dist/components/image/ContourImage.d.ts +7 -0
  178. package/dist/components/image/ContourImage.d.ts.map +1 -0
  179. package/dist/components/image/ContourImage.js +6 -0
  180. package/dist/components/image/EngravingImage.d.ts +7 -0
  181. package/dist/components/image/EngravingImage.d.ts.map +1 -0
  182. package/dist/components/image/EngravingImage.js +6 -0
  183. package/dist/components/image/FrostImage.d.ts +7 -0
  184. package/dist/components/image/FrostImage.d.ts.map +1 -0
  185. package/dist/components/image/FrostImage.js +6 -0
  186. package/dist/components/image/LenticularImage.d.ts +7 -0
  187. package/dist/components/image/LenticularImage.d.ts.map +1 -0
  188. package/dist/components/image/LenticularImage.js +6 -0
  189. package/dist/components/image/PinscreenImage.d.ts +7 -0
  190. package/dist/components/image/PinscreenImage.d.ts.map +1 -0
  191. package/dist/components/image/PinscreenImage.js +6 -0
  192. package/dist/components/image/PrismImage.d.ts +7 -0
  193. package/dist/components/image/PrismImage.d.ts.map +1 -0
  194. package/dist/components/image/PrismImage.js +6 -0
  195. package/dist/components/image/ProjectorImage.d.ts +7 -0
  196. package/dist/components/image/ProjectorImage.d.ts.map +1 -0
  197. package/dist/components/image/ProjectorImage.js +6 -0
  198. package/dist/components/image/ReliefImage.d.ts +7 -0
  199. package/dist/components/image/ReliefImage.d.ts.map +1 -0
  200. package/dist/components/image/ReliefImage.js +6 -0
  201. package/dist/components/image/RollImage.d.ts +7 -0
  202. package/dist/components/image/RollImage.d.ts.map +1 -0
  203. package/dist/components/image/RollImage.js +6 -0
  204. package/dist/components/image/ShardsImage.d.ts +126 -0
  205. package/dist/components/image/ShardsImage.d.ts.map +1 -0
  206. package/dist/components/image/ShardsImage.js +470 -0
  207. package/dist/components/image/core/contour.d.ts +126 -0
  208. package/dist/components/image/core/contour.d.ts.map +1 -0
  209. package/dist/components/image/core/contour.js +123 -0
  210. package/dist/components/image/core/engraving.d.ts +135 -0
  211. package/dist/components/image/core/engraving.d.ts.map +1 -0
  212. package/dist/components/image/core/engraving.js +163 -0
  213. package/dist/components/image/core/frost.d.ts +126 -0
  214. package/dist/components/image/core/frost.d.ts.map +1 -0
  215. package/dist/components/image/core/frost.js +156 -0
  216. package/dist/components/image/core/imageCore.d.ts +110 -0
  217. package/dist/components/image/core/imageCore.d.ts.map +1 -0
  218. package/dist/components/image/core/imageCore.js +269 -0
  219. package/dist/components/image/core/lenticular.d.ts +129 -0
  220. package/dist/components/image/core/lenticular.d.ts.map +1 -0
  221. package/dist/components/image/core/lenticular.js +132 -0
  222. package/dist/components/image/core/pinscreen.d.ts +126 -0
  223. package/dist/components/image/core/pinscreen.d.ts.map +1 -0
  224. package/dist/components/image/core/pinscreen.js +147 -0
  225. package/dist/components/image/core/prism.d.ts +120 -0
  226. package/dist/components/image/core/prism.d.ts.map +1 -0
  227. package/dist/components/image/core/prism.js +164 -0
  228. package/dist/components/image/core/projector.d.ts +135 -0
  229. package/dist/components/image/core/projector.d.ts.map +1 -0
  230. package/dist/components/image/core/projector.js +225 -0
  231. package/dist/components/image/core/relief.d.ts +111 -0
  232. package/dist/components/image/core/relief.d.ts.map +1 -0
  233. package/dist/components/image/core/relief.js +94 -0
  234. package/dist/components/image/core/roll.d.ts +114 -0
  235. package/dist/components/image/core/roll.d.ts.map +1 -0
  236. package/dist/components/image/core/roll.js +116 -0
  237. package/dist/components/image/imageVariant.d.ts +46 -0
  238. package/dist/components/image/imageVariant.d.ts.map +1 -0
  239. package/dist/components/image/imageVariant.js +128 -0
  240. package/dist/components/image/index.d.ts +22 -0
  241. package/dist/components/image/index.d.ts.map +1 -0
  242. package/dist/components/image/index.js +10 -0
  243. package/dist/components/image/pictureCycle.d.ts +15 -0
  244. package/dist/components/image/pictureCycle.d.ts.map +1 -0
  245. package/dist/components/image/pictureCycle.js +82 -0
  246. package/dist/components/index.d.ts +4 -0
  247. package/dist/components/index.d.ts.map +1 -1
  248. package/dist/components/index.js +4 -0
  249. package/dist/components/volumetricClouds/VolumetricCloudsPass.d.ts +9 -7
  250. package/dist/components/volumetricClouds/VolumetricCloudsPass.d.ts.map +1 -1
  251. package/dist/components/volumetricClouds/VolumetricCloudsPass.js +39 -27
  252. package/dist/constants.d.ts.map +1 -1
  253. package/dist/constants.js +2 -0
  254. package/dist/galleryRuntime.d.ts +57 -0
  255. package/dist/galleryRuntime.d.ts.map +1 -0
  256. package/dist/galleryRuntime.js +105 -0
  257. package/dist/hooks/useConfigLive.d.ts +1 -1
  258. package/dist/hooks/useConfigLive.d.ts.map +1 -1
  259. package/dist/index.d.ts +4 -1
  260. package/dist/index.d.ts.map +1 -1
  261. package/dist/index.js +4 -0
  262. package/dist/keyPad/KeyPadControls.d.ts +16 -0
  263. package/dist/keyPad/KeyPadControls.d.ts.map +1 -0
  264. package/dist/keyPad/KeyPadControls.js +176 -0
  265. package/dist/keyPad/index.d.ts +16 -0
  266. package/dist/keyPad/index.d.ts.map +1 -0
  267. package/dist/keyPad/index.js +8 -0
  268. package/dist/keyPad/keyBindings.d.ts +43 -0
  269. package/dist/keyPad/keyBindings.d.ts.map +1 -0
  270. package/dist/keyPad/keyBindings.js +92 -0
  271. package/dist/keyPad/keyPadAnimation.d.ts +28 -0
  272. package/dist/keyPad/keyPadAnimation.d.ts.map +1 -0
  273. package/dist/keyPad/keyPadAnimation.js +131 -0
  274. package/dist/keyPad/keyPadMotion.d.ts +68 -0
  275. package/dist/keyPad/keyPadMotion.d.ts.map +1 -0
  276. package/dist/keyPad/keyPadMotion.js +283 -0
  277. package/dist/keyPad/keyPadStore.d.ts +25 -0
  278. package/dist/keyPad/keyPadStore.d.ts.map +1 -0
  279. package/dist/keyPad/keyPadStore.js +63 -0
  280. package/dist/keyPad/types.d.ts +23 -0
  281. package/dist/keyPad/types.d.ts.map +1 -0
  282. package/dist/keyPad/types.js +9 -0
  283. package/dist/operations/catalogue/visibility.d.ts.map +1 -1
  284. package/dist/operations/catalogue/visibility.js +23 -1
  285. package/dist/shaders/clouds/CloudResolveMaterial.d.ts +2 -1
  286. package/dist/shaders/clouds/CloudResolveMaterial.d.ts.map +1 -1
  287. package/dist/shaders/clouds/CloudResolveMaterial.js +37 -12
  288. package/dist/shaders/clouds/CloudVolumeMaterial.d.ts +4 -0
  289. package/dist/shaders/clouds/CloudVolumeMaterial.d.ts.map +1 -1
  290. package/dist/shaders/clouds/CloudVolumeMaterial.js +15 -3
  291. package/dist/triggers/kinds/gallery.d.ts +2 -0
  292. package/dist/triggers/kinds/gallery.d.ts.map +1 -0
  293. package/dist/triggers/kinds/gallery.js +39 -0
  294. package/dist/triggers/kinds/index.d.ts +1 -0
  295. package/dist/triggers/kinds/index.d.ts.map +1 -1
  296. package/dist/triggers/kinds/index.js +1 -0
  297. package/package.json +2 -2
@@ -0,0 +1,315 @@
1
+ // The approved lab module, verbatim but for its import paths and the lab's picture loader (Claude outputs/gallery-lab/
2
+ // carousel.mjs). Plain JS-shaped code (the viewer compiles non-strict); typed at its one door, kit/GalleryVariant.tsx. Its own DEFAULTS only fill knobs the
3
+ // core defaults (DEFAULT_GALLERY_OBJECTS.basicCarousel) do not carry; its own autoplay is never used.
4
+ // carousel — a gallery variant for 3drise (type 'gallery', config.type 'carousel').
5
+ //
6
+ // Construction: the pictures sit on a conveyor of frames, one InstancedMesh (+ its
7
+ // reflection, a second draw). One number drives everything — the scroll position
8
+ // `s`, a float index — and every frame's place is a function of its offset
9
+ // d = i - s (wrapped, so the set is a ring): position along an arc that blends
10
+ // from a flat row to a circle (`curve`), a coverflow yaw toward the centre
11
+ // (`tilt`) growing with |d|, recession in depth, a lift + scale for the frame at
12
+ // d ≈ 0 (`focusScale`, `focusLift`), dimming and fade-out with distance. `s`
13
+ // is a damped spring toward the target index: next/prev/goTo set the target; a
14
+ // drag moves `s` directly and the release velocity throws it, then it snaps to
15
+ // the nearest frame — so motion is one continuous law, never a tween per frame.
16
+ // Idle: a slow breathing float with a phase per frame (zero net motion).
17
+ // The cursor: `tilt` yaws the nearby frames toward it, `lift` raises the frame
18
+ // under it; nothing is drawn at the cursor. Clicking the centre frame focuses it
19
+ // (it comes forward); clicking a neighbour scrolls to it.
20
+ import * as THREE from 'three';
21
+ import { withLean } from '../kit/galleryKit.js';
22
+ export const catalog = {
23
+ key: 'carousel',
24
+ name: 'Carousel',
25
+ description: 'A coverflow ring of framed pictures driven by one damped scroll position — next, prev, drag with inertia and snap, a lifted focus frame and a floor reflection; the cursor tilts or lifts the frames. Use for portfolios, product lines, photo showcases.',
26
+ tags: ['gallery', 'carousel', 'coverflow', 'ring', 'reflection', 'navigation', 'interactive'],
27
+ camera: { position: [0, 0.35, 4.6], target: [0, -0.1, 0] },
28
+ };
29
+ export const DEFAULTS = {
30
+ type: 'carousel',
31
+ enabled: true, lean: 1,
32
+ imageUrls: [],
33
+ autoplay: 0,
34
+ intensity: 1,
35
+ opacity: 1,
36
+ // --- structural ---
37
+ aspect: 1.5, // frame width / height
38
+ frameWidth: 1.6, // width of a frame (gallery units)
39
+ // --- layout ---
40
+ spacing: 1.15, // distance between neighbours, in frame widths
41
+ curve: 0.6, // 0 = flat row, 1 = a circle
42
+ tilt: 0.95, // coverflow yaw of the neighbours (rad)
43
+ depth: 0.9, // how far neighbours recede
44
+ visible: 3.2, // frames each side before they fade out
45
+ focusScale: 1.25, // scale of the centre frame
46
+ focusLift: 0.35, // how far the centre frame comes forward
47
+ focusAmount: 0.8, // extra forward travel when the centre frame is clicked (focused)
48
+ dim: 0.55, // darkening of the neighbours
49
+ // --- motion ---
50
+ stiffness: 60, // spring toward the target (1/s²)
51
+ damping: 12, // spring damping (1/s)
52
+ throwing: 0.18, // how far a drag release throws (s of velocity)
53
+ breathe: 0.5, // idle float
54
+ // --- look ---
55
+ reflection: 0.45,
56
+ floorGap: 0.12,
57
+ border: 0.02, // frame border, in frame units
58
+ borderColor: '#f3e6cf',
59
+ backColor: '#1a1d26',
60
+ // --- pointer ---
61
+ pointerMode: 'tilt',
62
+ pointerStrength: 1,
63
+ pointerRadius: 1.6,
64
+ pointerColor: '#ffd9a6',
65
+ };
66
+ export const STRUCTURAL = ['imageUrls', 'aspect', 'frameWidth'];
67
+ export const POINTER_MODES = ['tilt', 'lift'];
68
+ export const GUI = [
69
+ { key: 'lean', min: 0, max: 3, step: 0.01, tip: 'The gallery turns toward the cursor' },
70
+ { key: 'aspect', min: 0.5, max: 2.5, step: 0.01, tip: 'Frame width / height (rebuild)' },
71
+ { key: 'frameWidth', min: 0.5, max: 3, step: 0.01, tip: 'Frame width (rebuild)' },
72
+ { key: 'spacing', min: 0.4, max: 2.5, step: 0.01 }, { key: 'curve', min: 0, max: 1, step: 0.01 }, { key: 'tilt', min: 0, max: 1.5, step: 0.01 },
73
+ { key: 'depth', min: 0, max: 2, step: 0.01 }, { key: 'visible', min: 1, max: 8, step: 0.1 },
74
+ { key: 'focusScale', min: 1, max: 2, step: 0.01 }, { key: 'focusLift', min: 0, max: 1.5, step: 0.01 }, { key: 'focusAmount', min: 0, max: 3, step: 0.01 }, { key: 'dim', min: 0, max: 1, step: 0.01 },
75
+ { key: 'stiffness', min: 5, max: 200, step: 1 }, { key: 'damping', min: 2, max: 40, step: 0.1 }, { key: 'throwing', min: 0, max: 0.6, step: 0.01 }, { key: 'breathe', min: 0, max: 2, step: 0.01 },
76
+ { key: 'reflection', min: 0, max: 1, step: 0.01 }, { key: 'floorGap', min: 0, max: 0.6, step: 0.01 }, { key: 'border', min: 0, max: 0.08, step: 0.001 },
77
+ { key: 'autoplay', min: 0, max: 20, step: 0.5 },
78
+ { key: 'pointerMode', options: ['none', ...POINTER_MODES] }, { key: 'pointerStrength', min: 0, max: 3, step: 0.01 }, { key: 'pointerRadius', min: 0.2, max: 4, step: 0.01 },
79
+ { key: 'intensity', min: 0, max: 2, step: 0.01 }, { key: 'opacity', min: 0, max: 1, step: 0.01 },
80
+ { key: 'borderColor', color: true }, { key: 'backColor', color: true }, { key: 'pointerColor', color: true },
81
+ ];
82
+ export const PRESETS = [
83
+ { name: 'Coverflow', description: 'The default: a tilted ring with a lifted centre.', patch: {} },
84
+ { name: 'Flat row', description: 'A straight strip, no tilt, soft focus.', patch: { curve: 0, tilt: 0, depth: 0.3, spacing: 1.08, focusScale: 1.12, focusLift: 0.15, dim: 0.35, reflection: 0.3 } },
85
+ { name: 'Wheel', description: 'A tight circle: the neighbours wrap away behind.', patch: { curve: 1, tilt: 0.2, depth: 2, spacing: 0.8, visible: 5, focusScale: 1.15, focusLift: 0.25, dim: 0.7 } },
86
+ { name: 'Deck', description: 'Frames stacked close, heavy tilt, quick snap.', patch: { spacing: 0.45, tilt: 1.3, depth: 1.2, curve: 0.2, focusScale: 1.3, dim: 0.65, stiffness: 120, damping: 16 } },
87
+ ];
88
+ function col(c) { return new THREE.Color(c); }
89
+ const smooth = (a, b, x) => { const t = Math.min(1, Math.max(0, (x - a) / (b - a))); return t * t * (3 - 2 * t); };
90
+ export function createUniforms() {
91
+ return {
92
+ uTex: { value: null },
93
+ uBorder: { value: 0.02 }, uBorderColor: { value: col('#f3e6cf') }, uBackColor: { value: col('#1a1d26') },
94
+ uPointerColor: { value: col('#ffd9a6') },
95
+ uIntensity: { value: 1 }, uOpacity: { value: 1 }, uReflection: { value: 0.45 }, uAspect: { value: 1.5 },
96
+ };
97
+ }
98
+ export function applyConfig(u, c) {
99
+ const set = (k, v) => { if (v === undefined)
100
+ return; if (u[k].value && u[k].value.isColor) {
101
+ if (v.isColor)
102
+ u[k].value.copy(v);
103
+ else
104
+ u[k].value.set(v);
105
+ }
106
+ else
107
+ u[k].value = v; };
108
+ set('uBorder', c.border);
109
+ set('uBorderColor', c.borderColor);
110
+ set('uBackColor', c.backColor);
111
+ set('uPointerColor', c.pointerColor);
112
+ set('uIntensity', c.intensity);
113
+ set('uOpacity', c.opacity);
114
+ set('uReflection', c.reflection);
115
+ }
116
+ const fragHead = /* glsl */ `
117
+ layout(location = 0) out highp vec4 pc_fragColor;
118
+ #define gl_FragColor pc_fragColor
119
+ `;
120
+ const vert = /* glsl */ `
121
+ attribute float aIdx;
122
+ attribute vec4 aState; // focus, alpha, hover, dim
123
+ varying vec2 vUv; varying float vLayer; varying vec4 vState; varying vec3 vN; varying vec3 vV; varying float vBack;
124
+ void main(){
125
+ vUv = uv; vLayer = aIdx; vState = aState;
126
+ vec4 wp = instanceMatrix * vec4(position, 1.0);
127
+ vec4 mv = modelViewMatrix * wp;
128
+ vN = normalize(normalMatrix * mat3(instanceMatrix) * vec3(0.0, 0.0, 1.0));
129
+ vV = -mv.xyz;
130
+ gl_Position = projectionMatrix * mv;
131
+ }
132
+ `;
133
+ const frag = (reflect) => /* glsl */ `
134
+ ${fragHead}
135
+ precision highp sampler2DArray;
136
+ uniform sampler2DArray uTex;
137
+ uniform float uBorder, uIntensity, uOpacity, uReflection, uAspect;
138
+ uniform vec3 uBorderColor, uBackColor, uPointerColor;
139
+ varying vec2 vUv; varying float vLayer; varying vec4 vState; varying vec3 vN; varying vec3 vV;
140
+ void main(){
141
+ float focus = vState.x, alpha = vState.y, hover = vState.z, dim = vState.w;
142
+ bool front = ${reflect ? '!gl_FrontFacing' : 'gl_FrontFacing'}; // the mirrored copy has its winding flipped
143
+ vec3 c = front ? texture(uTex, vec3(vUv, vLayer)).rgb : uBackColor;
144
+ // border: a thin frame, brighter on the focused / hovered one
145
+ vec2 e = min(vUv, 1.0 - vUv) * vec2(1.0, uAspect);
146
+ float dm = min(e.x, e.y);
147
+ float fw = fwidth(dm) * 1.5;
148
+ float border = 1.0 - smoothstep(uBorder, uBorder + fw, dm);
149
+ vec3 bc = mix(uBorderColor * (0.45 + 0.55 * focus), uPointerColor, hover * 0.8);
150
+ c = mix(c, bc, border);
151
+ // neighbours dim; a soft lambert on the yawed faces so the ring reads as 3d
152
+ vec3 N = normalize(vN); vec3 V = normalize(vV);
153
+ float lam = 0.78 + 0.22 * max(dot(N, V), 0.0);
154
+ c *= lam * (1.0 - dim) + hover * 0.1;
155
+ float a = alpha * uOpacity;
156
+ ${reflect ? 'a *= uReflection * pow(1.0 - vUv.y, 1.6) * 0.8; c *= 0.85;' : ''}
157
+ if (a < 0.003) discard;
158
+ gl_FragColor = vec4(c * uIntensity * a, a);
159
+ #include <tonemapping_fragment>
160
+ #include <colorspace_fragment>
161
+ }
162
+ `;
163
+ // ---------------------------------------------------------------- images (shared with shards: cover-fit array texture)
164
+ export const TEX_W = 1024;
165
+ // ---------------------------------------------------------------- build
166
+ export function build(u, c) { return withLean(buildGallery(u, c), c); }
167
+ function buildGallery(u, c) {
168
+ const MAX = 32;
169
+ const fw = c.frameWidth, fh = c.frameWidth / c.aspect;
170
+ u.uAspect.value = c.aspect;
171
+ const geo = new THREE.PlaneGeometry(fw, fh);
172
+ const aIdx = new Float32Array(MAX);
173
+ for (let i = 0; i < MAX; i++)
174
+ aIdx[i] = i;
175
+ geo.setAttribute('aIdx', new THREE.InstancedBufferAttribute(aIdx, 1));
176
+ const state = new Float32Array(MAX * 4);
177
+ const aState = new THREE.InstancedBufferAttribute(state, 4);
178
+ aState.setUsage(THREE.DynamicDrawUsage);
179
+ geo.setAttribute('aState', aState);
180
+ const mat = new THREE.ShaderMaterial({ uniforms: u, vertexShader: vert, fragmentShader: frag(false), glslVersion: THREE.GLSL3, side: THREE.DoubleSide, transparent: true, depthWrite: true, premultipliedAlpha: true });
181
+ const rmat = new THREE.ShaderMaterial({ uniforms: u, vertexShader: vert, fragmentShader: frag(true), glslVersion: THREE.GLSL3, side: THREE.DoubleSide, transparent: true, depthWrite: false, premultipliedAlpha: true });
182
+ const frames = new THREE.InstancedMesh(geo, mat, MAX);
183
+ frames.count = 0;
184
+ frames.frustumCulled = false;
185
+ frames.userData.pick = 'frames';
186
+ const refl = new THREE.InstancedMesh(geo, rmat, MAX);
187
+ refl.count = 0;
188
+ refl.frustumCulled = false;
189
+ refl.raycast = () => { };
190
+ refl.renderOrder = -1;
191
+ const object = new THREE.Group();
192
+ object.add(refl, frames);
193
+ const st = {
194
+ count: 0, s: 0, v: 0, target: 0, dragging: false, dragS0: 0, dragX0: 0, lastDx: 0, focused: 0, focusT: 0,
195
+ time: 0, autoT: 0, hover: -1, hoverT: new Float32Array(MAX), pointer: null,
196
+ cfg: { ...c },
197
+ };
198
+ const M = new THREE.Matrix4(), P = new THREE.Vector3(), Q = new THREE.Quaternion(), S = new THREE.Vector3(), E = new THREE.Euler();
199
+ const floorY = -fh / 2 - c.floorGap;
200
+ const wrap = (d, n) => n > 1 ? ((d + n / 2) % n + n) % n - n / 2 : d;
201
+ function layout(dt) {
202
+ const k = st.cfg, n = st.count;
203
+ if (!n)
204
+ return;
205
+ const pitch = fw * k.spacing;
206
+ const gap = k.floorGap;
207
+ for (let i = 0; i < n; i++) {
208
+ const d = wrap(i - st.s, n);
209
+ const ad = Math.abs(d);
210
+ const w = smooth(0, 1.2, ad); // 0 at the centre, 1 past a neighbour
211
+ // arc: a flat row bent toward a circle of radius R = pitch * n / 2π
212
+ const R = Math.max(pitch * n / (2 * Math.PI), pitch * 1.5);
213
+ const a = (d * pitch) / R;
214
+ const x = (1 - k.curve) * d * pitch + k.curve * R * Math.sin(a);
215
+ const zArc = k.curve * (R * Math.cos(a) - R);
216
+ const z = zArc - k.depth * w * 0.9 * (1 - k.curve) - k.depth * ad * 0.12;
217
+ const focus = 1 - smooth(0, 0.9, ad);
218
+ // the focused frame comes forward and up
219
+ const lift = k.focusLift * focus + st.focusT * k.focusAmount * focus;
220
+ const yBreathe = k.breathe * 0.025 * Math.sin(st.time * 0.7 + i * 1.9);
221
+ let yaw = -Math.sign(d) * k.tilt * w - k.curve * a * 0.5;
222
+ let sc = 1 + (k.focusScale - 1) * focus + st.focusT * 0.15 * focus;
223
+ // pointer
224
+ const ht = st.hoverT[i];
225
+ if (st.pointer && k.pointerMode !== 'none') {
226
+ const dx = st.pointer.x - x, dy = st.pointer.y - 0;
227
+ const dist = Math.hypot(dx, dy);
228
+ const pw = (1 - smooth(0, k.pointerRadius, dist)) * k.pointerStrength;
229
+ if (k.pointerMode === 'tilt')
230
+ yaw += Math.atan2(dx, 2.5) * 0.35 * pw;
231
+ else
232
+ sc *= 1 + 0.08 * ht;
233
+ }
234
+ const ly = yBreathe + (k.pointerMode === 'lift' ? 0.12 * ht : 0);
235
+ P.set(x, ly, z + lift);
236
+ E.set(0, yaw, 0);
237
+ Q.setFromEuler(E);
238
+ S.set(sc, sc, 1);
239
+ M.compose(P, Q, S);
240
+ frames.setMatrixAt(i, M);
241
+ // reflection: mirror across the floor plane y = floorY - gap offset
242
+ const fy = -fh / 2 - gap;
243
+ P.set(x, 2 * fy - ly, z + lift);
244
+ S.set(sc, -sc, 1);
245
+ M.compose(P, Q, S);
246
+ refl.setMatrixAt(i, M);
247
+ const alpha = 1 - smooth(k.visible - 0.8, k.visible, ad);
248
+ state[i * 4] = focus;
249
+ state[i * 4 + 1] = alpha;
250
+ state[i * 4 + 2] = ht;
251
+ state[i * 4 + 3] = k.dim * w;
252
+ }
253
+ frames.count = n;
254
+ refl.count = n;
255
+ frames.instanceMatrix.needsUpdate = true;
256
+ refl.instanceMatrix.needsUpdate = true;
257
+ aState.needsUpdate = true;
258
+ }
259
+ const controls = {
260
+ next() { st.target = Math.round(st.target) + 1; st.focused = 0; st.autoT = 0; },
261
+ prev() { st.target = Math.round(st.target) - 1; st.focused = 0; st.autoT = 0; },
262
+ goTo(i) { const n = st.count; if (!n)
263
+ return; const cur = ((Math.round(st.s) % n) + n) % n; st.target = Math.round(st.s) + wrap(i - cur, n); st.focused = 0; st.autoT = 0; },
264
+ jump(i) { st.s = st.target = i; st.v = 0; },
265
+ focus(on) { st.focused = on === undefined ? 1 - st.focused : (on ? 1 : 0); },
266
+ get index() { const n = st.count; return n ? ((Math.round(st.s) % n) + n) % n : 0; },
267
+ get count() { return st.count; },
268
+ get busy() { return Math.abs(st.target - st.s) > 0.02 || Math.abs(st.v) > 0.05; },
269
+ setTexture(tex, count) { if (u.uTex.value)
270
+ u.uTex.value.dispose(); u.uTex.value = tex; st.count = Math.min(count, MAX); layout(0); },
271
+ /** drag in gallery x units: begin(x) / move(x) / end() — the release velocity throws, then it snaps */
272
+ dragBegin(x) { st.dragging = true; st.dragS0 = st.s; st.dragX0 = x; st.v = 0; st.lastDx = 0; },
273
+ dragMove(x) { if (!st.dragging)
274
+ return; const pitch = fw * st.cfg.spacing; const ns = st.dragS0 - (x - st.dragX0) / pitch; st.lastDx = ns - st.s; st.s = ns; },
275
+ dragEnd(dt) { if (!st.dragging)
276
+ return; st.dragging = false; st.v = st.lastDx / Math.max(dt, 1 / 120); st.target = Math.round(st.s + st.v * st.cfg.throwing); st.autoT = 0; },
277
+ get dragging() { return st.dragging; },
278
+ hover(i) { st.hover = i; },
279
+ };
280
+ object.userData.gallery = controls;
281
+ return {
282
+ object, materials: [mat, rmat], controls, frames,
283
+ apply(cfg) { Object.assign(st.cfg, cfg); applyConfig(u, cfg); },
284
+ update(dt, pointer) {
285
+ dt = Math.min(dt, 0.05);
286
+ st.time += dt;
287
+ st.pointer = pointer;
288
+ const k = st.cfg;
289
+ if (!st.dragging) {
290
+ // damped spring toward the target index (semi-implicit Euler, substepped)
291
+ const sub = 4, h = dt / sub;
292
+ for (let q = 0; q < sub; q++) {
293
+ const acc = k.stiffness * (st.target - st.s) - k.damping * st.v;
294
+ st.v += acc * h;
295
+ st.s += st.v * h;
296
+ }
297
+ if (Math.abs(st.target - st.s) < 1e-4 && Math.abs(st.v) < 1e-3) {
298
+ st.s = st.target;
299
+ st.v = 0;
300
+ }
301
+ }
302
+ if (k.autoplay > 0 && st.count > 1 && !pointer && !st.dragging) {
303
+ st.autoT += dt;
304
+ if (st.autoT >= k.autoplay)
305
+ controls.next();
306
+ }
307
+ st.focusT += ((st.focused ? 1 : 0) - st.focusT) * (1 - Math.exp(-dt * 7));
308
+ for (let i = 0; i < st.count; i++)
309
+ st.hoverT[i] += ((st.hover === i ? 1 : 0) - st.hoverT[i]) * (1 - Math.exp(-dt * 9));
310
+ layout(dt);
311
+ },
312
+ dispose() { geo.dispose(); mat.dispose(); rmat.dispose(); if (u.uTex.value)
313
+ u.uTex.value.dispose(); },
314
+ };
315
+ }
@@ -0,0 +1,153 @@
1
+ import * as THREE from 'three';
2
+ export declare const catalog: {
3
+ key: string;
4
+ name: string;
5
+ camera: {
6
+ position: number[];
7
+ target: number[];
8
+ };
9
+ description: string;
10
+ tags: string[];
11
+ };
12
+ export declare const DEFAULTS: {
13
+ type: string;
14
+ aspect: number;
15
+ width: number;
16
+ levels: number;
17
+ sparse: number;
18
+ lineWidth: number;
19
+ smoothing: number;
20
+ changeTime: number;
21
+ dim: number;
22
+ pointerMode: string;
23
+ pointerRadius: number;
24
+ lift: number;
25
+ enabled: boolean;
26
+ lean: number;
27
+ imageUrls: any[];
28
+ autoplay: number;
29
+ intensity: number;
30
+ opacity: number;
31
+ layout: string;
32
+ spacing: number;
33
+ depth: number;
34
+ visible: number;
35
+ shape: number;
36
+ stiffness: number;
37
+ damping: number;
38
+ throwing: number;
39
+ wave: number;
40
+ slant: number;
41
+ pointerStrength: number;
42
+ };
43
+ export declare const STRUCTURAL: string[];
44
+ export declare const POINTER_MODES: string[];
45
+ export declare const GUI: ({
46
+ key: string;
47
+ options: string[];
48
+ tip: string;
49
+ min?: undefined;
50
+ max?: undefined;
51
+ step?: undefined;
52
+ } | {
53
+ key: string;
54
+ min: number;
55
+ max: number;
56
+ step: number;
57
+ } | {
58
+ key: string;
59
+ options: string[];
60
+ })[];
61
+ export declare const PRESETS: ({
62
+ name: string;
63
+ description: string;
64
+ patch: {
65
+ levels?: undefined;
66
+ sparse?: undefined;
67
+ lineWidth?: undefined;
68
+ smoothing?: undefined;
69
+ };
70
+ } | {
71
+ name: string;
72
+ description: string;
73
+ patch: {
74
+ levels: number;
75
+ sparse: number;
76
+ lineWidth: number;
77
+ smoothing: number;
78
+ };
79
+ })[];
80
+ export declare function createUniforms(): {
81
+ uLevels: {
82
+ value: number;
83
+ };
84
+ uSparse: {
85
+ value: number;
86
+ };
87
+ uLine: {
88
+ value: number;
89
+ };
90
+ uSmooth: {
91
+ value: number;
92
+ };
93
+ uLift: {
94
+ value: number;
95
+ };
96
+ uTex: {
97
+ value: any;
98
+ };
99
+ uS: {
100
+ value: number;
101
+ };
102
+ uCount: {
103
+ value: number;
104
+ };
105
+ uTime: {
106
+ value: number;
107
+ };
108
+ uAct: {
109
+ value: Float32Array<ArrayBuffer>;
110
+ };
111
+ uW: {
112
+ value: number;
113
+ };
114
+ uH: {
115
+ value: number;
116
+ };
117
+ uWave: {
118
+ value: number;
119
+ };
120
+ uSlant: {
121
+ value: number;
122
+ };
123
+ uDim: {
124
+ value: number;
125
+ };
126
+ uIntensity: {
127
+ value: number;
128
+ };
129
+ uOpacity: {
130
+ value: number;
131
+ };
132
+ uPointer: {
133
+ value: THREE.Vector3;
134
+ };
135
+ uPointerActive: {
136
+ value: number;
137
+ };
138
+ uPointerMode: {
139
+ value: number;
140
+ };
141
+ uPointerStrength: {
142
+ value: number;
143
+ };
144
+ uPointerRadius: {
145
+ value: number;
146
+ };
147
+ uPlace: {
148
+ value: THREE.Matrix4[];
149
+ };
150
+ };
151
+ export declare function applyConfig(u: any, c: any): void;
152
+ export declare function build(u: any, c: any): any;
153
+ //# sourceMappingURL=contourLines.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contourLines.d.ts","sourceRoot":"","sources":["../../../../src/components/gallery/looks/contourLines.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,eAAO,MAAM,OAAO;;;;;;;;;CAEiE,CAAC;AAEtF,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAIpB,CAAC;AACF,eAAO,MAAM,UAAU,UAAmC,CAAC;AAC3D,eAAO,MAAM,aAAa,UAAW,CAAC;AACtC,eAAO,MAAM,GAAG;;;;;;;;;;;;;;;IAQf,CAAC;AACF,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;IAInB,CAAC;AACF,wBAAgB,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAA4J;AAC1L,wBAAgB,WAAW,CAAC,CAAC,KAAA,EAAE,CAAC,KAAA,QAAmL;AA2CnN,wBAAgB,KAAK,CAAC,CAAC,KAAA,EAAE,CAAC,KAAA,OAA6C"}
@@ -0,0 +1,91 @@
1
+ // The approved lab module, verbatim but for its import paths and the lab's picture loader (Claude outputs/gallery-lab/
2
+ // contours.mjs). Plain JS-shaped code (the viewer compiles non-strict); typed at its one door, kit/GalleryVariant.tsx. Its own DEFAULTS only fill knobs the
3
+ // core defaults (DEFAULT_GALLERY_OBJECTS.contourLines) do not carry; its own autoplay is never used.
4
+ // contours — "Contour Lines". Every picture is drawn as the contour lines of its own brightness, like a
5
+ // topographic map of the image: level sets of a softened luminance field, anti-aliased with fwidth so every line
6
+ // is a clean hairline at any distance. An inactive picture shows only every fourth level, thin and grey. When it
7
+ // becomes the active one a soft wave crosses it: behind the wave the missing levels appear, every line thickens
8
+ // and takes the picture's colour, until the lines meet and close into the solid picture. Leaving runs it back.
9
+ // The cursor lifts the contours near it into a soft relief (the picture's own brightness as height). Self-coloured.
10
+ import * as THREE from 'three';
11
+ import { BASE_DEFAULTS, BASE_GUI_MOTION, BASE_GUI_TAIL, LAYOUT_GUI, baseUniforms, applyBase, baseGlsl, instanced, shaderMaterial, makeGallery, withLean, fragHead } from '../kit/lookBase.js';
12
+ export const catalog = { key: 'contourLines', name: 'Contour Lines', camera: { position: [0.3, 0.15, 4.6], target: [0, 0, 0] },
13
+ description: 'Pictures drawn as the contour lines of their own brightness, like a topographic map: inactive ones are a few thin grey lines, the active one fills in as a soft wave thickens the lines into the solid picture; the cursor lifts the contours into relief. Use for architecture, data and graphic showcases.',
14
+ tags: ['gallery', 'contours', 'lines', 'topographic', 'graphic', 'interactive'] };
15
+ export const DEFAULTS = {
16
+ ...BASE_DEFAULTS, type: 'contourLines', aspect: 1.4, width: 2.2,
17
+ levels: 22, sparse: 3, lineWidth: 0.08, smoothing: 3.6, changeTime: 2.2, dim: 0.55,
18
+ pointerMode: 'lift', pointerRadius: 0.6, lift: 0.18,
19
+ };
20
+ export const STRUCTURAL = ['imageUrls', 'aspect', 'width'];
21
+ export const POINTER_MODES = ['lift'];
22
+ export const GUI = [
23
+ { key: 'lean', min: 0, max: 3, step: 0.01, tip: 'The gallery turns toward the cursor' },
24
+ { key: 'aspect', min: 0.6, max: 2.5, step: 0.01 }, { key: 'width', min: 1, max: 4, step: 0.01 },
25
+ ...LAYOUT_GUI, ...BASE_GUI_MOTION,
26
+ { key: 'levels', min: 6, max: 60, step: 1, tip: 'Contour levels over the full brightness range' }, { key: 'sparse', min: 1, max: 8, step: 1, tip: 'An inactive picture shows every n-th level' },
27
+ { key: 'lineWidth', min: 0.02, max: 0.4, step: 0.005, tip: 'Width of an inactive line, as a share of the level spacing' },
28
+ { key: 'smoothing', min: 0, max: 5, step: 0.1, tip: 'How much the brightness is smoothed before the contours are drawn' },
29
+ { key: 'pointerMode', options: ['none', ...POINTER_MODES] }, ...BASE_GUI_TAIL, { key: 'lift', min: 0, max: 0.6, step: 0.01, tip: 'Height of the cursor’s relief' },
30
+ ];
31
+ export const PRESETS = [
32
+ { name: 'Contours', description: 'The default.', patch: {} },
33
+ { name: 'Survey', description: 'Many fine levels.', patch: { levels: 48, sparse: 6, lineWidth: 0.05, smoothing: 1.5 } },
34
+ { name: 'Bold', description: 'Few broad bands.', patch: { levels: 12, sparse: 2, lineWidth: 0.16, smoothing: 3.2 } },
35
+ ];
36
+ export function createUniforms() { return { ...baseUniforms(), uLevels: { value: 28 }, uSparse: { value: 4 }, uLine: { value: 0.09 }, uSmooth: { value: 2.2 }, uLift: { value: 0.18 } }; }
37
+ export function applyConfig(u, c) { const set = applyBase(u, c, POINTER_MODES); set('uLevels', c.levels); set('uSparse', c.sparse); set('uLine', c.lineWidth); set('uSmooth', c.smoothing); set('uLift', c.lift); }
38
+ const vert = /* glsl */ `
39
+ precision highp sampler2DArray;
40
+ uniform sampler2DArray uTex;
41
+ attribute vec4 aI;
42
+ ${baseGlsl}
43
+ uniform float uLift, uSmooth;
44
+ varying vec2 vUv; varying float vImg; varying float vAct; varying float vAlpha;
45
+ void main(){
46
+ float img = aI.x; vec2 g = position.xy + 0.5;
47
+ vec2 p = vec2(position.x * uW, position.y * uH);
48
+ float L = lumOf(textureLod(uTex, vec3(g, img), uSmooth + 1.0).rgb);
49
+ float z = uLift * L * maskAt(p);
50
+ vUv = g; vImg = img; vAct = actOf(img); vAlpha = fadeAt(img);
51
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(placeAt(img, vec3(p, z)), 1.0);
52
+ }
53
+ `;
54
+ const frag = /* glsl */ `
55
+ ${fragHead}
56
+ precision highp sampler2DArray;
57
+ uniform sampler2DArray uTex;
58
+ ${baseGlsl}
59
+ uniform float uLevels, uSparse, uLine, uSmooth;
60
+ varying vec2 vUv; varying float vImg; varying float vAct; varying float vAlpha;
61
+ void main(){
62
+ vec3 pic = texture(uTex, vec3(vUv, vImg)).rgb;
63
+ float L = lumOf(textureLod(uTex, vec3(vUv, vImg), uSmooth).rgb);
64
+ float s = waveAt(vAct, vUv);
65
+ float f = L * uLevels, idx = floor(f + 0.5);
66
+ float dist = abs(f - idx); // 0 on a level, 0.5 half-way between two
67
+ float px = max(fwidth(f), 1e-4);
68
+ float keep = mix(step(mod(idx, uSparse), 0.5), 1.0, smoothstep(0.0, 0.5, s));
69
+ float width = mix(uLine, 0.56, s * s); // the lines meet (0.5) and close the picture
70
+ float line = 1.0 - smoothstep(width - px, width + px, dist);
71
+ vec3 c = mix(fadedOf(pic) * 1.4, pic, s);
72
+ float a = line * keep * vAlpha * uOpacity;
73
+ if (a < 0.003) discard;
74
+ gl_FragColor = vec4(c * uIntensity * a, a);
75
+ #include <tonemapping_fragment>
76
+ #include <colorspace_fragment>
77
+ }
78
+ `;
79
+ export function build(u, c) { return withLean(buildGallery(u, c), c); }
80
+ function buildGallery(u, c) {
81
+ const W = c.width, H = W / c.aspect;
82
+ const geo = instanced(new THREE.PlaneGeometry(1, 1, 64, 44), 1, () => [0, 0]);
83
+ const mat = shaderMaterial(u, vert, frag);
84
+ const mesh = new THREE.Mesh(geo, mat);
85
+ mesh.frustumCulled = false;
86
+ mesh.raycast = () => { };
87
+ const g = makeGallery(u, c, { W, H, meshes: [mesh], setCount: (n) => { geo.instanceCount = n; } });
88
+ const apply = g.apply;
89
+ g.apply = (k) => { apply(k); applyConfig(u, k); };
90
+ return g;
91
+ }