@3driseai/3drise-viewer 0.1.39 → 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 (315) hide show
  1. package/dist/animationsV2/ClipsRuntime.d.ts +30 -0
  2. package/dist/animationsV2/ClipsRuntime.d.ts.map +1 -1
  3. package/dist/animationsV2/ClipsRuntime.js +185 -14
  4. package/dist/animationsV2/clipUtils.d.ts +15 -0
  5. package/dist/animationsV2/clipUtils.d.ts.map +1 -1
  6. package/dist/animationsV2/clipUtils.js +39 -2
  7. package/dist/animationsV2/normalize.d.ts.map +1 -1
  8. package/dist/animationsV2/normalize.js +4 -0
  9. package/dist/animationsV2/types.d.ts +12 -0
  10. package/dist/animationsV2/types.d.ts.map +1 -1
  11. package/dist/api/sceneHandle.d.ts +40 -3
  12. package/dist/api/sceneHandle.d.ts.map +1 -1
  13. package/dist/api/sceneHandle.js +40 -0
  14. package/dist/components/AnimatedObject.d.ts.map +1 -1
  15. package/dist/components/AnimatedObject.js +6 -2
  16. package/dist/components/EnabledContext.d.ts +12 -0
  17. package/dist/components/EnabledContext.d.ts.map +1 -0
  18. package/dist/components/EnabledContext.js +12 -0
  19. package/dist/components/GalleryObject.d.ts +13 -0
  20. package/dist/components/GalleryObject.d.ts.map +1 -0
  21. package/dist/components/GalleryObject.js +46 -0
  22. package/dist/components/ImageObject.d.ts +9 -0
  23. package/dist/components/ImageObject.d.ts.map +1 -0
  24. package/dist/components/ImageObject.js +26 -0
  25. package/dist/components/ObjectNode.d.ts.map +1 -1
  26. package/dist/components/ObjectNode.js +17 -6
  27. package/dist/components/ObjectsRenderer.d.ts.map +1 -1
  28. package/dist/components/ObjectsRenderer.js +9 -0
  29. package/dist/components/ProjectLoader.d.ts +2 -0
  30. package/dist/components/ProjectLoader.d.ts.map +1 -1
  31. package/dist/components/ProjectLoader.js +2 -2
  32. package/dist/components/SceneBuilder.d.ts +10 -0
  33. package/dist/components/SceneBuilder.d.ts.map +1 -1
  34. package/dist/components/SceneBuilder.js +3 -2
  35. package/dist/components/gallery/BasicCarouselGallery.d.ts +18 -0
  36. package/dist/components/gallery/BasicCarouselGallery.d.ts.map +1 -0
  37. package/dist/components/gallery/BasicCarouselGallery.js +9 -0
  38. package/dist/components/gallery/ContourLinesGallery.d.ts +18 -0
  39. package/dist/components/gallery/ContourLinesGallery.d.ts.map +1 -0
  40. package/dist/components/gallery/ContourLinesGallery.js +9 -0
  41. package/dist/components/gallery/DepthLayersGallery.d.ts +18 -0
  42. package/dist/components/gallery/DepthLayersGallery.d.ts.map +1 -0
  43. package/dist/components/gallery/DepthLayersGallery.js +9 -0
  44. package/dist/components/gallery/EngravingGallery.d.ts +18 -0
  45. package/dist/components/gallery/EngravingGallery.d.ts.map +1 -0
  46. package/dist/components/gallery/EngravingGallery.js +9 -0
  47. package/dist/components/gallery/FlowLinesGallery.d.ts +18 -0
  48. package/dist/components/gallery/FlowLinesGallery.d.ts.map +1 -0
  49. package/dist/components/gallery/FlowLinesGallery.js +9 -0
  50. package/dist/components/gallery/FoldGallery.d.ts +18 -0
  51. package/dist/components/gallery/FoldGallery.d.ts.map +1 -0
  52. package/dist/components/gallery/FoldGallery.js +9 -0
  53. package/dist/components/gallery/GlassPanesGallery.d.ts +18 -0
  54. package/dist/components/gallery/GlassPanesGallery.d.ts.map +1 -0
  55. package/dist/components/gallery/GlassPanesGallery.js +9 -0
  56. package/dist/components/gallery/HaloGallery.d.ts +18 -0
  57. package/dist/components/gallery/HaloGallery.d.ts.map +1 -0
  58. package/dist/components/gallery/HaloGallery.js +9 -0
  59. package/dist/components/gallery/LightThreadsGallery.d.ts +18 -0
  60. package/dist/components/gallery/LightThreadsGallery.d.ts.map +1 -0
  61. package/dist/components/gallery/LightThreadsGallery.js +9 -0
  62. package/dist/components/gallery/LoomGallery.d.ts +18 -0
  63. package/dist/components/gallery/LoomGallery.d.ts.map +1 -0
  64. package/dist/components/gallery/LoomGallery.js +9 -0
  65. package/dist/components/gallery/PaperLanternsGallery.d.ts +18 -0
  66. package/dist/components/gallery/PaperLanternsGallery.d.ts.map +1 -0
  67. package/dist/components/gallery/PaperLanternsGallery.js +9 -0
  68. package/dist/components/gallery/ParticleShiftGallery.d.ts +18 -0
  69. package/dist/components/gallery/ParticleShiftGallery.d.ts.map +1 -0
  70. package/dist/components/gallery/ParticleShiftGallery.js +9 -0
  71. package/dist/components/gallery/PinscreenGallery.d.ts +18 -0
  72. package/dist/components/gallery/PinscreenGallery.d.ts.map +1 -0
  73. package/dist/components/gallery/PinscreenGallery.js +9 -0
  74. package/dist/components/gallery/PopUpGallery.d.ts +18 -0
  75. package/dist/components/gallery/PopUpGallery.d.ts.map +1 -0
  76. package/dist/components/gallery/PopUpGallery.js +9 -0
  77. package/dist/components/gallery/PrismSplitGallery.d.ts +18 -0
  78. package/dist/components/gallery/PrismSplitGallery.d.ts.map +1 -0
  79. package/dist/components/gallery/PrismSplitGallery.js +9 -0
  80. package/dist/components/gallery/RidgelinesGallery.d.ts +18 -0
  81. package/dist/components/gallery/RidgelinesGallery.d.ts.map +1 -0
  82. package/dist/components/gallery/RidgelinesGallery.js +9 -0
  83. package/dist/components/gallery/ShadowBoxGallery.d.ts +18 -0
  84. package/dist/components/gallery/ShadowBoxGallery.d.ts.map +1 -0
  85. package/dist/components/gallery/ShadowBoxGallery.js +9 -0
  86. package/dist/components/gallery/SilkGallery.d.ts +18 -0
  87. package/dist/components/gallery/SilkGallery.d.ts.map +1 -0
  88. package/dist/components/gallery/SilkGallery.js +9 -0
  89. package/dist/components/gallery/SlatsGallery.d.ts +18 -0
  90. package/dist/components/gallery/SlatsGallery.d.ts.map +1 -0
  91. package/dist/components/gallery/SlatsGallery.js +9 -0
  92. package/dist/components/gallery/StrataGallery.d.ts +18 -0
  93. package/dist/components/gallery/StrataGallery.d.ts.map +1 -0
  94. package/dist/components/gallery/StrataGallery.js +9 -0
  95. package/dist/components/gallery/TerracesGallery.d.ts +18 -0
  96. package/dist/components/gallery/TerracesGallery.d.ts.map +1 -0
  97. package/dist/components/gallery/TerracesGallery.js +9 -0
  98. package/dist/components/gallery/WireReliefGallery.d.ts +18 -0
  99. package/dist/components/gallery/WireReliefGallery.d.ts.map +1 -0
  100. package/dist/components/gallery/WireReliefGallery.js +9 -0
  101. package/dist/components/gallery/index.d.ts +46 -0
  102. package/dist/components/gallery/index.d.ts.map +1 -0
  103. package/dist/components/gallery/index.js +22 -0
  104. package/dist/components/gallery/kit/GalleryVariant.d.ts +68 -0
  105. package/dist/components/gallery/kit/GalleryVariant.d.ts.map +1 -0
  106. package/dist/components/gallery/kit/GalleryVariant.js +231 -0
  107. package/dist/components/gallery/kit/feeds.d.ts +7 -0
  108. package/dist/components/gallery/kit/feeds.d.ts.map +1 -0
  109. package/dist/components/gallery/kit/feeds.js +83 -0
  110. package/dist/components/gallery/kit/galleryKit.d.ts +118 -0
  111. package/dist/components/gallery/kit/galleryKit.d.ts.map +1 -0
  112. package/dist/components/gallery/kit/galleryKit.js +298 -0
  113. package/dist/components/gallery/kit/lookBase.d.ts +157 -0
  114. package/dist/components/gallery/kit/lookBase.d.ts.map +1 -0
  115. package/dist/components/gallery/kit/lookBase.js +211 -0
  116. package/dist/components/gallery/kit/pictures.d.ts +14 -0
  117. package/dist/components/gallery/kit/pictures.d.ts.map +1 -0
  118. package/dist/components/gallery/kit/pictures.js +81 -0
  119. package/dist/components/gallery/looks/basicCarousel.d.ts +177 -0
  120. package/dist/components/gallery/looks/basicCarousel.d.ts.map +1 -0
  121. package/dist/components/gallery/looks/basicCarousel.js +315 -0
  122. package/dist/components/gallery/looks/contourLines.d.ts +153 -0
  123. package/dist/components/gallery/looks/contourLines.d.ts.map +1 -0
  124. package/dist/components/gallery/looks/contourLines.js +91 -0
  125. package/dist/components/gallery/looks/depthLayers.d.ts +155 -0
  126. package/dist/components/gallery/looks/depthLayers.d.ts.map +1 -0
  127. package/dist/components/gallery/looks/depthLayers.js +87 -0
  128. package/dist/components/gallery/looks/engraving.d.ts +162 -0
  129. package/dist/components/gallery/looks/engraving.d.ts.map +1 -0
  130. package/dist/components/gallery/looks/engraving.js +96 -0
  131. package/dist/components/gallery/looks/flowLines.d.ts +180 -0
  132. package/dist/components/gallery/looks/flowLines.d.ts.map +1 -0
  133. package/dist/components/gallery/looks/flowLines.js +113 -0
  134. package/dist/components/gallery/looks/fold.d.ts +209 -0
  135. package/dist/components/gallery/looks/fold.d.ts.map +1 -0
  136. package/dist/components/gallery/looks/fold.js +155 -0
  137. package/dist/components/gallery/looks/glassPanes.d.ts +133 -0
  138. package/dist/components/gallery/looks/glassPanes.d.ts.map +1 -0
  139. package/dist/components/gallery/looks/glassPanes.js +208 -0
  140. package/dist/components/gallery/looks/halo.d.ts +100 -0
  141. package/dist/components/gallery/looks/halo.d.ts.map +1 -0
  142. package/dist/components/gallery/looks/halo.js +119 -0
  143. package/dist/components/gallery/looks/lightThreads.d.ts +199 -0
  144. package/dist/components/gallery/looks/lightThreads.d.ts.map +1 -0
  145. package/dist/components/gallery/looks/lightThreads.js +246 -0
  146. package/dist/components/gallery/looks/loom.d.ts +238 -0
  147. package/dist/components/gallery/looks/loom.d.ts.map +1 -0
  148. package/dist/components/gallery/looks/loom.js +256 -0
  149. package/dist/components/gallery/looks/paperLanterns.d.ts +181 -0
  150. package/dist/components/gallery/looks/paperLanterns.d.ts.map +1 -0
  151. package/dist/components/gallery/looks/paperLanterns.js +399 -0
  152. package/dist/components/gallery/looks/particleShift.d.ts +193 -0
  153. package/dist/components/gallery/looks/particleShift.d.ts.map +1 -0
  154. package/dist/components/gallery/looks/particleShift.js +282 -0
  155. package/dist/components/gallery/looks/pinscreen.d.ts +175 -0
  156. package/dist/components/gallery/looks/pinscreen.d.ts.map +1 -0
  157. package/dist/components/gallery/looks/pinscreen.js +96 -0
  158. package/dist/components/gallery/looks/popUp.d.ts +206 -0
  159. package/dist/components/gallery/looks/popUp.d.ts.map +1 -0
  160. package/dist/components/gallery/looks/popUp.js +132 -0
  161. package/dist/components/gallery/looks/prismSplit.d.ts +151 -0
  162. package/dist/components/gallery/looks/prismSplit.d.ts.map +1 -0
  163. package/dist/components/gallery/looks/prismSplit.js +84 -0
  164. package/dist/components/gallery/looks/ridgelines.d.ts +179 -0
  165. package/dist/components/gallery/looks/ridgelines.d.ts.map +1 -0
  166. package/dist/components/gallery/looks/ridgelines.js +111 -0
  167. package/dist/components/gallery/looks/shadowBox.d.ts +152 -0
  168. package/dist/components/gallery/looks/shadowBox.d.ts.map +1 -0
  169. package/dist/components/gallery/looks/shadowBox.js +82 -0
  170. package/dist/components/gallery/looks/silk.d.ts +140 -0
  171. package/dist/components/gallery/looks/silk.d.ts.map +1 -0
  172. package/dist/components/gallery/looks/silk.js +346 -0
  173. package/dist/components/gallery/looks/slats.d.ts +176 -0
  174. package/dist/components/gallery/looks/slats.d.ts.map +1 -0
  175. package/dist/components/gallery/looks/slats.js +93 -0
  176. package/dist/components/gallery/looks/strata.d.ts +172 -0
  177. package/dist/components/gallery/looks/strata.d.ts.map +1 -0
  178. package/dist/components/gallery/looks/strata.js +88 -0
  179. package/dist/components/gallery/looks/terraces.d.ts +168 -0
  180. package/dist/components/gallery/looks/terraces.d.ts.map +1 -0
  181. package/dist/components/gallery/looks/terraces.js +91 -0
  182. package/dist/components/gallery/looks/wireRelief.d.ts +153 -0
  183. package/dist/components/gallery/looks/wireRelief.d.ts.map +1 -0
  184. package/dist/components/gallery/looks/wireRelief.js +128 -0
  185. package/dist/components/image/ContourImage.d.ts +7 -0
  186. package/dist/components/image/ContourImage.d.ts.map +1 -0
  187. package/dist/components/image/ContourImage.js +6 -0
  188. package/dist/components/image/EngravingImage.d.ts +7 -0
  189. package/dist/components/image/EngravingImage.d.ts.map +1 -0
  190. package/dist/components/image/EngravingImage.js +6 -0
  191. package/dist/components/image/FrostImage.d.ts +7 -0
  192. package/dist/components/image/FrostImage.d.ts.map +1 -0
  193. package/dist/components/image/FrostImage.js +6 -0
  194. package/dist/components/image/LenticularImage.d.ts +7 -0
  195. package/dist/components/image/LenticularImage.d.ts.map +1 -0
  196. package/dist/components/image/LenticularImage.js +6 -0
  197. package/dist/components/image/PinscreenImage.d.ts +7 -0
  198. package/dist/components/image/PinscreenImage.d.ts.map +1 -0
  199. package/dist/components/image/PinscreenImage.js +6 -0
  200. package/dist/components/image/PrismImage.d.ts +7 -0
  201. package/dist/components/image/PrismImage.d.ts.map +1 -0
  202. package/dist/components/image/PrismImage.js +6 -0
  203. package/dist/components/image/ProjectorImage.d.ts +7 -0
  204. package/dist/components/image/ProjectorImage.d.ts.map +1 -0
  205. package/dist/components/image/ProjectorImage.js +6 -0
  206. package/dist/components/image/ReliefImage.d.ts +7 -0
  207. package/dist/components/image/ReliefImage.d.ts.map +1 -0
  208. package/dist/components/image/ReliefImage.js +6 -0
  209. package/dist/components/image/RollImage.d.ts +7 -0
  210. package/dist/components/image/RollImage.d.ts.map +1 -0
  211. package/dist/components/image/RollImage.js +6 -0
  212. package/dist/components/image/ShardsImage.d.ts +126 -0
  213. package/dist/components/image/ShardsImage.d.ts.map +1 -0
  214. package/dist/components/image/ShardsImage.js +470 -0
  215. package/dist/components/image/core/contour.d.ts +126 -0
  216. package/dist/components/image/core/contour.d.ts.map +1 -0
  217. package/dist/components/image/core/contour.js +123 -0
  218. package/dist/components/image/core/engraving.d.ts +135 -0
  219. package/dist/components/image/core/engraving.d.ts.map +1 -0
  220. package/dist/components/image/core/engraving.js +163 -0
  221. package/dist/components/image/core/frost.d.ts +126 -0
  222. package/dist/components/image/core/frost.d.ts.map +1 -0
  223. package/dist/components/image/core/frost.js +156 -0
  224. package/dist/components/image/core/imageCore.d.ts +110 -0
  225. package/dist/components/image/core/imageCore.d.ts.map +1 -0
  226. package/dist/components/image/core/imageCore.js +269 -0
  227. package/dist/components/image/core/lenticular.d.ts +129 -0
  228. package/dist/components/image/core/lenticular.d.ts.map +1 -0
  229. package/dist/components/image/core/lenticular.js +132 -0
  230. package/dist/components/image/core/pinscreen.d.ts +126 -0
  231. package/dist/components/image/core/pinscreen.d.ts.map +1 -0
  232. package/dist/components/image/core/pinscreen.js +147 -0
  233. package/dist/components/image/core/prism.d.ts +120 -0
  234. package/dist/components/image/core/prism.d.ts.map +1 -0
  235. package/dist/components/image/core/prism.js +164 -0
  236. package/dist/components/image/core/projector.d.ts +135 -0
  237. package/dist/components/image/core/projector.d.ts.map +1 -0
  238. package/dist/components/image/core/projector.js +225 -0
  239. package/dist/components/image/core/relief.d.ts +111 -0
  240. package/dist/components/image/core/relief.d.ts.map +1 -0
  241. package/dist/components/image/core/relief.js +94 -0
  242. package/dist/components/image/core/roll.d.ts +114 -0
  243. package/dist/components/image/core/roll.d.ts.map +1 -0
  244. package/dist/components/image/core/roll.js +116 -0
  245. package/dist/components/image/imageVariant.d.ts +46 -0
  246. package/dist/components/image/imageVariant.d.ts.map +1 -0
  247. package/dist/components/image/imageVariant.js +128 -0
  248. package/dist/components/image/index.d.ts +22 -0
  249. package/dist/components/image/index.d.ts.map +1 -0
  250. package/dist/components/image/index.js +10 -0
  251. package/dist/components/image/pictureCycle.d.ts +15 -0
  252. package/dist/components/image/pictureCycle.d.ts.map +1 -0
  253. package/dist/components/image/pictureCycle.js +82 -0
  254. package/dist/components/index.d.ts +4 -0
  255. package/dist/components/index.d.ts.map +1 -1
  256. package/dist/components/index.js +4 -0
  257. package/dist/components/volumetricClouds/VolumetricCloudsPass.d.ts +9 -7
  258. package/dist/components/volumetricClouds/VolumetricCloudsPass.d.ts.map +1 -1
  259. package/dist/components/volumetricClouds/VolumetricCloudsPass.js +39 -27
  260. package/dist/constants.d.ts +1 -1
  261. package/dist/constants.d.ts.map +1 -1
  262. package/dist/constants.js +18 -5
  263. package/dist/galleryRuntime.d.ts +57 -0
  264. package/dist/galleryRuntime.d.ts.map +1 -0
  265. package/dist/galleryRuntime.js +105 -0
  266. package/dist/hooks/useConfigLive.d.ts +1 -1
  267. package/dist/hooks/useConfigLive.d.ts.map +1 -1
  268. package/dist/index.d.ts +4 -1
  269. package/dist/index.d.ts.map +1 -1
  270. package/dist/index.js +4 -0
  271. package/dist/keyPad/KeyPadControls.d.ts +16 -0
  272. package/dist/keyPad/KeyPadControls.d.ts.map +1 -0
  273. package/dist/keyPad/KeyPadControls.js +176 -0
  274. package/dist/keyPad/index.d.ts +16 -0
  275. package/dist/keyPad/index.d.ts.map +1 -0
  276. package/dist/keyPad/index.js +8 -0
  277. package/dist/keyPad/keyBindings.d.ts +43 -0
  278. package/dist/keyPad/keyBindings.d.ts.map +1 -0
  279. package/dist/keyPad/keyBindings.js +92 -0
  280. package/dist/keyPad/keyPadAnimation.d.ts +28 -0
  281. package/dist/keyPad/keyPadAnimation.d.ts.map +1 -0
  282. package/dist/keyPad/keyPadAnimation.js +131 -0
  283. package/dist/keyPad/keyPadMotion.d.ts +68 -0
  284. package/dist/keyPad/keyPadMotion.d.ts.map +1 -0
  285. package/dist/keyPad/keyPadMotion.js +283 -0
  286. package/dist/keyPad/keyPadStore.d.ts +25 -0
  287. package/dist/keyPad/keyPadStore.d.ts.map +1 -0
  288. package/dist/keyPad/keyPadStore.js +63 -0
  289. package/dist/keyPad/types.d.ts +23 -0
  290. package/dist/keyPad/types.d.ts.map +1 -0
  291. package/dist/keyPad/types.js +9 -0
  292. package/dist/operations/catalogue/motionTrail.d.ts.map +1 -1
  293. package/dist/operations/catalogue/motionTrail.js +8 -1
  294. package/dist/operations/catalogue/visibility.d.ts.map +1 -1
  295. package/dist/operations/catalogue/visibility.js +23 -1
  296. package/dist/shaders/clouds/CloudResolveMaterial.d.ts +2 -1
  297. package/dist/shaders/clouds/CloudResolveMaterial.d.ts.map +1 -1
  298. package/dist/shaders/clouds/CloudResolveMaterial.js +37 -12
  299. package/dist/shaders/clouds/CloudVolumeMaterial.d.ts +4 -0
  300. package/dist/shaders/clouds/CloudVolumeMaterial.d.ts.map +1 -1
  301. package/dist/shaders/clouds/CloudVolumeMaterial.js +15 -3
  302. package/dist/triggers/kinds/gallery.d.ts +2 -0
  303. package/dist/triggers/kinds/gallery.d.ts.map +1 -0
  304. package/dist/triggers/kinds/gallery.js +39 -0
  305. package/dist/triggers/kinds/index.d.ts +1 -0
  306. package/dist/triggers/kinds/index.d.ts.map +1 -1
  307. package/dist/triggers/kinds/index.js +1 -0
  308. package/dist/ui/UiAnchorUpdater.d.ts.map +1 -1
  309. package/dist/ui/UiAnchorUpdater.js +2 -1
  310. package/dist/utils/cursorPicking.d.ts.map +1 -1
  311. package/dist/utils/cursorPicking.js +2 -1
  312. package/dist/utils/shownInScene.d.ts +13 -0
  313. package/dist/utils/shownInScene.d.ts.map +1 -0
  314. package/dist/utils/shownInScene.js +16 -0
  315. package/package.json +2 -2
@@ -0,0 +1,470 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef } from 'react';
3
+ import * as THREE from 'three';
4
+ import { useFrame } from '@react-three/fiber';
5
+ import { DEFAULT_IMAGE_OBJECTS, IMAGE_OBJECTS_ANIMATABLE } from '@3driseai/3drise-core';
6
+ import { withConfigDefaults } from '../../utils/configAnimations.js';
7
+ import { useObjectReady } from '../../hooks/useObjectReady.js';
8
+ import { useConfigDriver } from '../../hooks/useConfigDriver.js';
9
+ import { stepPointerField, usePointerField } from '../../utils/pointerField.js';
10
+ import { usePictureCycle } from './pictureCycle.js';
11
+ // =============================================================================
12
+ // ShardsImage — one picture as a slab of shards that flip to the next picture
13
+ // =============================================================================
14
+ //
15
+ // Construction (lab: Claude outputs/gallery-lab/shards.mjs): the picture is one slab tessellated into a
16
+ // jittered grid of shards (one InstancedMesh, one draw call). A change of picture is a *front*
17
+ // travelling across the slab (a linear sweep, radial, or random order): each shard, when the front reaches
18
+ // it, lifts off the slab, flips through edge-on about an in-plane axis — the texture is swapped exactly at
19
+ // the edge-on instant, so the swap is never seen — tumbles a little, and lands back in its slot showing
20
+ // the new picture. Nothing moves the slab itself: the shards return exactly to where they started. Idle:
21
+ // slow breathing of the shards and a Ken Burns drift of the picture inside them. The cursor is a field over
22
+ // the slab (tilt / lift / ripple), never a drawn thing.
23
+ //
24
+ // The component keeps the outgoing picture itself while the change plays (uTexA -> uTexB); only the list
25
+ // `config.imageUrls` is stored, shown in turn every `config.interval` seconds (./pictureCycle).
26
+ // `root.userData.applyTexture(url)` is the same door for the displayImage operation (a gallery
27
+ // sending a clicked frame here).
28
+ //
29
+ export const POINTER_MODES = ['tilt', 'lift', 'ripple'];
30
+ export const ORDERS = ['sweep', 'radial', 'random'];
31
+ function mulberry32(a) {
32
+ return function () {
33
+ a |= 0;
34
+ a = (a + 0x6D2B79F5) | 0;
35
+ let t = Math.imul(a ^ (a >>> 15), 1 | a);
36
+ t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
37
+ return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
38
+ };
39
+ }
40
+ const col = (c) => new THREE.Color(c);
41
+ /** A 1×1 dark texture: what the first picture assembles in from. */
42
+ function blankTexture() {
43
+ const t = new THREE.DataTexture(new Uint8Array([14, 16, 22, 255]), 1, 1);
44
+ t.colorSpace = THREE.SRGBColorSpace;
45
+ t.needsUpdate = true;
46
+ return t;
47
+ }
48
+ // ---------------------------------------------------------------- uniforms
49
+ export function createUniforms() {
50
+ return {
51
+ uTexA: { value: null }, uTexB: { value: null },
52
+ /** cover-fit of each picture into the slab: scale.xy, offset.xy */
53
+ uFitA: { value: new THREE.Vector4(1, 1, 0, 0) }, uFitB: { value: new THREE.Vector4(1, 1, 0, 0) },
54
+ uPhase: { value: 1 }, // 1 = idle, showing B
55
+ uSweep: { value: new THREE.Vector2(1, 0) },
56
+ uOrder: { value: 0 },
57
+ uSpread: { value: 0.5 }, uJitter: { value: 0.15 },
58
+ uLift: { value: 0.35 }, uDrift: { value: 0.08 }, uSpin: { value: 0.6 },
59
+ uBreathe: { value: 0.5 }, uSeams: { value: 0.12 },
60
+ uTime: { value: 0 },
61
+ uHalfH: { value: 0.625 },
62
+ uKbZoom: { value: 1 }, uKbPan: { value: new THREE.Vector2(0, 0) },
63
+ uEdgeColor: { value: col('#0b0d12') }, uRimColor: { value: col('#ffd9a6') },
64
+ uPointerColor: { value: col('#9ad7ff') },
65
+ uRim: { value: 0.8 }, uIntensity: { value: 1 }, uOpacity: { value: 1 },
66
+ uPointer: { value: new THREE.Vector3(0, 0, 0) }, uPointerVel: { value: new THREE.Vector3(0, 0, 0) },
67
+ uPointerActive: { value: 0 }, uPointerMode: { value: 0 },
68
+ uPointerStrength: { value: 1 }, uPointerRadius: { value: 0.6 }, uPointerT: { value: 0 },
69
+ uBackColor: { value: col('#101218') }, uFlight: { value: 0 },
70
+ };
71
+ }
72
+ /** Every non-structural knob reaches a uniform here — the single door; the animatable list is what it writes. */
73
+ export function applyConfig(u, c) {
74
+ const num = (k, v) => { if (typeof v === 'number')
75
+ u[k].value = v; };
76
+ const color = (k, v) => {
77
+ const target = u[k].value;
78
+ if (v?.isColor)
79
+ target.copy(v);
80
+ else if (typeof v === 'string')
81
+ target.set(v);
82
+ };
83
+ num('uSpread', c.spread);
84
+ num('uJitter', c.delayJitter);
85
+ num('uLift', c.lift);
86
+ num('uDrift', c.drift);
87
+ num('uSpin', c.spin);
88
+ num('uBreathe', c.breathe);
89
+ num('uSeams', c.seams);
90
+ num('uRim', c.rim);
91
+ num('uIntensity', c.intensity);
92
+ num('uOpacity', c.opacity);
93
+ color('uEdgeColor', c.edgeColor);
94
+ color('uRimColor', c.rimColor);
95
+ color('uBackColor', c.backColor);
96
+ color('uPointerColor', c.pointerColor);
97
+ num('uPointerStrength', c.pointerStrength);
98
+ num('uPointerRadius', c.pointerRadius);
99
+ if (typeof c.pointerMode === 'string')
100
+ u.uPointerMode.value = POINTER_MODES.indexOf(c.pointerMode);
101
+ if (typeof c.order === 'string')
102
+ u.uOrder.value = Math.max(0, ORDERS.indexOf(c.order));
103
+ if (typeof c.sweepAngle === 'number') {
104
+ const a = THREE.MathUtils.degToRad(c.sweepAngle);
105
+ u.uSweep.value.set(Math.cos(a), Math.sin(a));
106
+ }
107
+ }
108
+ // ---------------------------------------------------------------- GLSL
109
+ const common = /* glsl */ `
110
+ #define PI 3.14159265
111
+ vec3 rot(vec3 p, vec3 ax, float a){ float c = cos(a), s = sin(a); return p * c + cross(ax, p) * s + ax * dot(ax, p) * (1.0 - c); }
112
+ float hash1(float n){ return fract(sin(n * 127.1) * 43758.5453); }
113
+ `;
114
+ const heroVert = /* glsl */ `
115
+ ${common}
116
+ attribute vec4 aC0; // corner 0, corner 1 (slab units)
117
+ attribute vec4 aC1; // corner 2, corner 3
118
+ attribute vec4 aMeta; // centre.xy, hash, hash2
119
+ uniform float uPhase, uOrder, uSpread, uJitter, uLift, uDrift, uSpin, uBreathe, uTime, uHalfH;
120
+ uniform vec2 uSweep;
121
+ uniform vec3 uPointer; uniform float uPointerActive, uPointerMode, uPointerStrength, uPointerRadius, uPointerT;
122
+ varying vec2 vUv; varying vec2 vTile; varying vec3 vN; varying vec3 vV;
123
+ varying float vLayer; varying float vFlight; varying float vPw; varying float vSeamW;
124
+
125
+ void main(){
126
+ vec2 c0 = aC0.xy, c1 = aC0.zw, c2 = aC1.xy, c3 = aC1.zw;
127
+ vec2 corner = mix(mix(c0, c1, uv.x), mix(c3, c2, uv.x), uv.y);
128
+ vec2 ctr = aMeta.xy; float h1 = aMeta.z, h2 = aMeta.w;
129
+ vec2 cn = vec2(ctr.x, ctr.y / uHalfH); // slab normalised to [-1,1]^2
130
+
131
+ // --- departure order: a front travelling over the slab -------------
132
+ float ord;
133
+ if (uOrder < 0.5) ord = dot(cn, uSweep) * 0.5 + 0.5;
134
+ else if (uOrder < 1.5) ord = length(cn) * 0.7071;
135
+ else ord = h1;
136
+ ord = mix(ord, h2, uJitter);
137
+ float w = max(uSpread, 0.02);
138
+ float s = clamp((uPhase * (1.0 + w) - ord) / w, 0.0, 1.0);
139
+ s = s * s * (3.0 - 2.0 * s);
140
+ float f = sin(PI * s); // 0 at rest, 1 at apex, 0 landed
141
+
142
+ // --- flip about an in-plane axis, edge-on at s = 0.5 ---------------
143
+ vec2 axP;
144
+ if (uOrder < 0.5) axP = vec2(-uSweep.y, uSweep.x);
145
+ else if (uOrder < 1.5) axP = vec2(-cn.y, cn.x) / max(length(cn), 1e-3);
146
+ else axP = vec2(cos(h2 * 6.2832), sin(h2 * 6.2832));
147
+ vec3 axis = normalize(vec3(axP, 0.0));
148
+ float ang = PI * s - PI * step(0.5, s); // 0 -> pi/2 | -pi/2 -> 0
149
+ vec3 lp = vec3(corner - ctr, 0.0) * (1.0 - 0.18 * f);
150
+ vec3 n = vec3(0.0, 0.0, 1.0);
151
+ lp = rot(lp, axis, ang); n = rot(n, axis, ang);
152
+ vec3 tax = normalize(vec3(h1 - 0.5, h2 - 0.5, hash1(h1 + h2) - 0.5));
153
+ float tum = uSpin * f * (h2 - 0.5) * 2.0;
154
+ lp = rot(lp, tax, tum); n = rot(n, tax, tum);
155
+
156
+ // --- flight path --------------------------------------------------
157
+ vec3 disp = vec3((vec2(h1, h2) - 0.5) * 2.0 * uDrift * f + uSweep * uDrift * f * 0.5, uLift * f);
158
+ // idle relief: two slow waves through the slab (shear, no net motion)
159
+ float br = sin(ctr.x * 2.3 + uTime * 0.35) * sin(ctr.y * 3.1 - uTime * 0.27) + 0.5 * sin((ctr.x + ctr.y) * 4.0 + uTime * 0.5);
160
+ disp.z += uBreathe * 0.03 * br;
161
+ float tilt = uBreathe * 0.06 * (sin(ctr.y * 3.1 + uTime * 0.3) * 0.5 + 0.5 * sin(ctr.x * 2.0 - uTime * 0.21));
162
+ lp = rot(lp, vec3(1.0, 0.0, 0.0), tilt); n = rot(n, vec3(1.0, 0.0, 0.0), tilt);
163
+
164
+ // --- pointer field ------------------------------------------------
165
+ vec2 dp = ctr - uPointer.xy; float d = length(dp);
166
+ float pw = uPointerActive * smoothstep(uPointerRadius, 0.0, d);
167
+ if (uPointerMode > -0.5) {
168
+ if (uPointerMode < 0.5) { // tilt: shards face the cursor
169
+ vec3 tax2 = normalize(vec3(-dp.y, dp.x, 0.0) + 1e-4);
170
+ float ta = -pw * uPointerStrength * 0.8;
171
+ lp = rot(lp, tax2, ta); n = rot(n, tax2, ta);
172
+ } else if (uPointerMode < 1.5) { // lift: shards float up under the cursor
173
+ disp.z += pw * uPointerStrength * 0.4;
174
+ lp *= 1.0 + 0.12 * pw;
175
+ } else { // ripple: rings run out from the cursor
176
+ float rp = sin(d * 16.0 - uPointerT * 6.0) * exp(-d * 2.4) * uPointerActive * uPointerStrength * 0.09;
177
+ disp.z += rp;
178
+ vec3 tax3 = normalize(vec3(-dp.y, dp.x, 0.0) + 1e-4);
179
+ float ta = cos(d * 16.0 - uPointerT * 6.0) * exp(-d * 2.4) * uPointerActive * uPointerStrength * 0.35;
180
+ lp = rot(lp, tax3, ta); n = rot(n, tax3, ta);
181
+ }
182
+ } else { pw = 0.0; }
183
+
184
+ vec3 p = vec3(ctr, 0.0) + lp + disp;
185
+ vUv = vec2(corner.x * 0.5 + 0.5, corner.y / uHalfH * 0.5 + 0.5);
186
+ vTile = uv;
187
+ vSeamW = 0.009 / max(0.5 * (length(c1 - c0) + length(c3 - c0)), 1e-3); // seam width in tile uv, constant in slab units
188
+ vLayer = step(0.5, s);
189
+ vFlight = f; vPw = pw;
190
+ vec4 mv = modelViewMatrix * vec4(p, 1.0);
191
+ vN = normalize(normalMatrix * n); vV = -mv.xyz;
192
+ gl_Position = projectionMatrix * mv;
193
+ }
194
+ `;
195
+ const heroFrag = /* glsl */ `
196
+ uniform sampler2D uTexA, uTexB;
197
+ uniform vec4 uFitA, uFitB;
198
+ uniform float uKbZoom; uniform vec2 uKbPan;
199
+ uniform vec3 uEdgeColor, uRimColor, uPointerColor;
200
+ uniform float uRim, uIntensity, uOpacity, uSeams;
201
+ varying vec2 vUv; varying vec2 vTile; varying vec3 vN; varying vec3 vV;
202
+ varying float vLayer; varying float vFlight; varying float vPw; varying float vSeamW;
203
+ void main(){
204
+ vec2 uv = (vUv - 0.5) * uKbZoom + 0.5 + uKbPan;
205
+ vec3 ca = texture2D(uTexA, uv * uFitA.xy + uFitA.zw).rgb;
206
+ vec3 cb = texture2D(uTexB, uv * uFitB.xy + uFitB.zw).rgb;
207
+ vec3 c = mix(ca, cb, vLayer);
208
+ vec3 N = normalize(vN); vec3 V = normalize(vV);
209
+ float ndv = abs(dot(N, V));
210
+ // shards in flight are lit as little slabs; at rest the picture is untouched
211
+ vec3 L = normalize(vec3(0.35, 0.55, 0.75));
212
+ float lam = 0.72 + 0.28 * max(dot(N, L), 0.0);
213
+ c *= mix(1.0, lam, clamp(vFlight * 2.0 + vPw, 0.0, 1.0));
214
+ // bevel / seam
215
+ vec2 e = min(vTile, 1.0 - vTile); float dm = min(e.x, e.y);
216
+ float fw = fwidth(dm) * 1.5;
217
+ float seam = 1.0 - smoothstep(0.0, min(vSeamW, 0.2) + fw, dm);
218
+ float seamVis = mix(uSeams * 0.6, 0.85, clamp(vFlight * 3.0 + vPw, 0.0, 1.0));
219
+ c = mix(c, uEdgeColor, seam * seamVis);
220
+ // light caught on the tilted faces
221
+ float rim = pow(1.0 - ndv, 3.0) * uRim * (0.25 + vFlight + vPw * 0.6);
222
+ vec3 rimCol = mix(uRimColor, uPointerColor, vPw);
223
+ c += rimCol * rim * (1.0 - seam * 0.5) + uPointerColor * vPw * 0.08;
224
+ gl_FragColor = vec4(c * uIntensity, uOpacity);
225
+ #include <tonemapping_fragment>
226
+ #include <colorspace_fragment>
227
+ }
228
+ `;
229
+ const backVert = /* glsl */ `
230
+ varying vec2 vUv;
231
+ void main(){ vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); }
232
+ `;
233
+ const backFrag = /* glsl */ `
234
+ uniform vec3 uBackColor; uniform float uFlight, uOpacity;
235
+ varying vec2 vUv;
236
+ void main(){
237
+ vec2 q = vUv - 0.5; float r = length(q * vec2(1.0, 1.4));
238
+ float vig = smoothstep(0.2, 0.75, r);
239
+ vec3 c = uBackColor * (1.0 - 0.6 * vig) * (1.0 - 0.35 * uFlight);
240
+ float a = (1.0 - smoothstep(0.55, 0.78, r)) * uOpacity;
241
+ gl_FragColor = vec4(c * a, a);
242
+ #include <tonemapping_fragment>
243
+ #include <colorspace_fragment>
244
+ }
245
+ `;
246
+ /** The slab: a jittered grid of shards (shared corners, so no gaps) and a dark backing. */
247
+ function build(u, c, aspect) {
248
+ const halfH = 1 / Math.max(0.2, aspect);
249
+ u.uHalfH.value = halfH;
250
+ const rnd = mulberry32(c.seed | 0);
251
+ const cols = Math.max(1, c.cols | 0), rows = Math.max(1, c.rows | 0);
252
+ const vx = new Float32Array((cols + 1) * (rows + 1) * 2);
253
+ for (let j = 0; j <= rows; j++)
254
+ for (let i = 0; i <= cols; i++) {
255
+ const k = (j * (cols + 1) + i) * 2;
256
+ const jx = (i === 0 || i === cols) ? 0 : (rnd() - 0.5) * c.tiling * 0.9;
257
+ const jy = (j === 0 || j === rows) ? 0 : (rnd() - 0.5) * c.tiling * 0.9;
258
+ vx[k] = -1 + ((i + jx) / cols) * 2;
259
+ vx[k + 1] = -halfH + ((j + jy) / rows) * 2 * halfH;
260
+ }
261
+ const n = cols * rows;
262
+ const aC0 = new Float32Array(n * 4), aC1 = new Float32Array(n * 4), aMeta = new Float32Array(n * 4);
263
+ let q = 0;
264
+ const v = (ii, jj) => { const k = (jj * (cols + 1) + ii) * 2; return [vx[k], vx[k + 1]]; };
265
+ for (let j = 0; j < rows; j++)
266
+ for (let i = 0; i < cols; i++) {
267
+ const p0 = v(i, j), p1 = v(i + 1, j), p2 = v(i + 1, j + 1), p3 = v(i, j + 1);
268
+ aC0.set([p0[0], p0[1], p1[0], p1[1]], q * 4);
269
+ aC1.set([p2[0], p2[1], p3[0], p3[1]], q * 4);
270
+ aMeta.set([(p0[0] + p1[0] + p2[0] + p3[0]) / 4, (p0[1] + p1[1] + p2[1] + p3[1]) / 4, rnd(), rnd()], q * 4);
271
+ q++;
272
+ }
273
+ const geo = new THREE.InstancedBufferGeometry();
274
+ const base = new THREE.PlaneGeometry(1, 1);
275
+ geo.index = base.index;
276
+ geo.attributes.position = base.attributes.position;
277
+ geo.attributes.uv = base.attributes.uv;
278
+ geo.setAttribute('aC0', new THREE.InstancedBufferAttribute(aC0, 4));
279
+ geo.setAttribute('aC1', new THREE.InstancedBufferAttribute(aC1, 4));
280
+ geo.setAttribute('aMeta', new THREE.InstancedBufferAttribute(aMeta, 4));
281
+ geo.instanceCount = n;
282
+ geo.boundingSphere = new THREE.Sphere(new THREE.Vector3(0, 0, 0), 1.8);
283
+ const heroMat = new THREE.ShaderMaterial({ uniforms: u, vertexShader: heroVert, fragmentShader: heroFrag, side: THREE.DoubleSide, transparent: true, depthWrite: true });
284
+ const hero = new THREE.Mesh(geo, heroMat);
285
+ hero.frustumCulled = false;
286
+ hero.raycast = () => { };
287
+ const backMat = new THREE.ShaderMaterial({ uniforms: u, vertexShader: backVert, fragmentShader: backFrag, transparent: true, depthWrite: false, premultipliedAlpha: true });
288
+ const back = new THREE.Mesh(new THREE.PlaneGeometry(2.6, halfH * 2 + 0.6), backMat);
289
+ back.position.z = -0.05;
290
+ back.renderOrder = -1;
291
+ // the picture's pick proxy: clicks (interactions) and the selection box land on the slab
292
+ const pick = new THREE.Mesh(new THREE.PlaneGeometry(2, halfH * 2), new THREE.MeshBasicMaterial({ visible: false }));
293
+ const object = new THREE.Group();
294
+ object.add(back, hero, pick);
295
+ return {
296
+ object, halfH,
297
+ dispose() {
298
+ geo.dispose();
299
+ base.dispose();
300
+ back.geometry.dispose();
301
+ pick.geometry.dispose();
302
+ heroMat.dispose();
303
+ backMat.dispose();
304
+ pick.material.dispose();
305
+ },
306
+ };
307
+ }
308
+ /** cover-fit: the picture (w×h) fills the slab (aspect) — scale.xy, offset.xy for the uv. */
309
+ function fitOf(tex, aspect, out) {
310
+ const img = tex?.image;
311
+ const iw = img?.width || 1, ih = img?.height || 1;
312
+ const ia = iw / ih;
313
+ if (ia > aspect) {
314
+ const s = aspect / ia;
315
+ out.set(s, 1, (1 - s) / 2, 0);
316
+ }
317
+ else {
318
+ const s = ia / aspect;
319
+ out.set(1, s, 0, (1 - s) / 2);
320
+ }
321
+ }
322
+ const loader = new THREE.TextureLoader();
323
+ loader.setCrossOrigin('anonymous');
324
+ function loadPicture(url) {
325
+ return new Promise((resolve, reject) => loader.load(url, (t) => {
326
+ t.colorSpace = THREE.SRGBColorSpace;
327
+ t.wrapS = t.wrapT = THREE.ClampToEdgeWrapping;
328
+ t.anisotropy = 4;
329
+ resolve(t);
330
+ }, undefined, reject));
331
+ }
332
+ // =============================================================================
333
+ const DEFAULTS = DEFAULT_IMAGE_OBJECTS.shards;
334
+ /** Knobs that rebuild the object: never live, they change once, on commit. */
335
+ const STRUCTURAL = ['imageUrls', 'cols', 'rows', 'tiling', 'aspect', 'seed'];
336
+ /** Knobs a keyframe or pointer binding may drive per frame — exactly what applyConfig pushes. */
337
+ const ANIMATABLE = new Set(IMAGE_OBJECTS_ANIMATABLE.shards.map((p) => p.value));
338
+ const POINTER_NORMAL = new THREE.Vector3(0, 0, 1);
339
+ const POINTER_ANCHOR = new THREE.Vector3(0, 0, 0);
340
+ /**
341
+ * A picture tessellated into shards that lift, flip edge-on and land as the next picture in a travelling wave whenever the image changes; the cursor tilts, lifts or ripples the shards. Use for hero images, portfolios and product reveals.
342
+ */
343
+ const ShardsImage = ({ config, id, keyframes, mouseMove, onObjectReady, onObjectDispose }) => {
344
+ const rootRef = useRef(null);
345
+ useObjectReady(rootRef, config, onObjectReady, onObjectDispose);
346
+ const cfg = useMemo(() => withConfigDefaults(DEFAULTS, config), [config]);
347
+ const uniforms = useMemo(() => createUniforms(), []);
348
+ const blank = useMemo(() => blankTexture(), []);
349
+ // ---- pictures: current (B) and the one leaving (A); the slab's aspect comes from the first picture unless set
350
+ const st = useRef({
351
+ aspect: 0, shown: '', texA: null, texB: null,
352
+ phase: 1, pending: null, loading: '', time: 0, shownT: 0, kbDir: new THREE.Vector2(1, 0), pointerT: 0,
353
+ cache: new Map(),
354
+ });
355
+ const [aspectKey, setAspectKey] = React.useState(0);
356
+ const aspect = cfg.aspect > 0 ? cfg.aspect : (st.current.aspect || 1.6);
357
+ const instance = useMemo(() => build(uniforms, cfg, aspect), [uniforms, cfg.cols, cfg.rows, cfg.tiling, cfg.seed, aspect, aspectKey]); // eslint-disable-line react-hooks/exhaustive-deps
358
+ useEffect(() => () => instance.dispose(), [instance]);
359
+ useEffect(() => {
360
+ fitOf(st.current.texA, aspect, uniforms.uFitA.value);
361
+ fitOf(st.current.texB, aspect, uniforms.uFitB.value);
362
+ }, [instance, aspect, uniforms]);
363
+ /** The one door for a picture change: loads it, then runs the change front (queued while one plays). */
364
+ const show = useCallback((url) => {
365
+ const s = st.current;
366
+ if (!url || url === s.shown || url === s.loading)
367
+ return;
368
+ s.loading = url;
369
+ const got = s.cache.get(url);
370
+ const ready = got ? Promise.resolve(got) : loadPicture(url).then((t) => { s.cache.set(url, t); return t; });
371
+ ready.then((tex) => {
372
+ if (s.loading !== url)
373
+ return; // superseded
374
+ s.loading = '';
375
+ if (!s.texB) { // first picture: it assembles in from the backing
376
+ if (cfg.aspect <= 0) {
377
+ const img = tex.image;
378
+ s.aspect = img.width / img.height;
379
+ setAspectKey((k) => k + 1);
380
+ }
381
+ s.texA = blank;
382
+ s.texB = tex;
383
+ s.shown = url;
384
+ s.phase = 0;
385
+ uniforms.uTexA.value = blank;
386
+ uniforms.uTexB.value = tex;
387
+ fitOf(blank, aspect, uniforms.uFitA.value);
388
+ fitOf(tex, s.aspect || aspect, uniforms.uFitB.value);
389
+ return;
390
+ }
391
+ if (s.phase < 1) {
392
+ s.pending = url;
393
+ return;
394
+ }
395
+ s.texA = s.texB;
396
+ s.texB = tex;
397
+ s.shown = url;
398
+ s.phase = 0;
399
+ s.shownT = 0;
400
+ s.kbDir.set(Math.cos(url.length * 2.4), Math.sin(url.length * 2.4)).normalize();
401
+ uniforms.uTexA.value = s.texA;
402
+ uniforms.uTexB.value = tex;
403
+ fitOf(s.texA, aspect, uniforms.uFitA.value);
404
+ fitOf(tex, aspect, uniforms.uFitB.value);
405
+ }).catch(() => { if (s.loading === url)
406
+ s.loading = ''; }); // a missing picture leaves the current one
407
+ }, [aspect, blank, cfg.aspect, uniforms]);
408
+ const preload = useCallback((url) => {
409
+ const s = st.current;
410
+ if (s.cache.has(url))
411
+ return;
412
+ loadPicture(url).then((t) => { if (!s.cache.has(url))
413
+ s.cache.set(url, t);
414
+ else
415
+ t.dispose(); }).catch(() => { });
416
+ }, []);
417
+ const busy = useCallback(() => { const s = st.current; return s.phase < 1 || !!s.loading || !!s.pending; }, []);
418
+ const { showExternal, feed } = usePictureCycle({ urls: cfg.imageUrls, interval: cfg.interval, show, preload, busy });
419
+ useEffect(() => {
420
+ const root = rootRef.current;
421
+ if (!root)
422
+ return;
423
+ root.userData.applyTexture = (url) => showExternal(url);
424
+ root.userData.feedImage = feed; // a gallery's feeds (gallery/kit/feeds.ts)
425
+ return () => { delete root.userData.applyTexture; delete root.userData.feedImage; };
426
+ }, [showExternal, feed]);
427
+ useEffect(() => () => { for (const t of st.current.cache.values())
428
+ t.dispose(); blank.dispose(); }, [blank]); // eslint-disable-line react-hooks/exhaustive-deps
429
+ useLayoutEffect(() => { applyConfig(uniforms, cfg); }, [uniforms, cfg]);
430
+ const push = useCallback((merged) => { applyConfig(uniforms, merged); }, [uniforms]);
431
+ useConfigDriver({ rootRef, id, family: 'image', base: cfg, structural: STRUCTURAL, allowed: ANIMATABLE, keyframes, mouseMove, push });
432
+ const pointer = usePointerField();
433
+ useFrame((state, delta) => {
434
+ const dt = Math.min(delta, 0.1);
435
+ const s = st.current;
436
+ s.time += dt;
437
+ uniforms.uTime.value = s.time;
438
+ if (s.phase < 1) {
439
+ s.phase = Math.min(1, s.phase + dt / Math.max(0.05, cfg.duration));
440
+ if (s.phase >= 1) {
441
+ s.texA = s.texB;
442
+ uniforms.uTexA.value = s.texB;
443
+ uniforms.uFitA.value.copy(uniforms.uFitB.value);
444
+ if (s.pending) {
445
+ const p = s.pending;
446
+ s.pending = null;
447
+ show(p);
448
+ }
449
+ }
450
+ }
451
+ uniforms.uPhase.value = s.phase;
452
+ uniforms.uFlight.value = s.phase < 1 ? Math.sin(Math.PI * s.phase) : 0;
453
+ // ken burns: slow zoom-in with a drift, restarting on each picture
454
+ s.shownT += dt;
455
+ const kb = 1 - Math.exp(-s.shownT / 9);
456
+ const zoom = 1 - cfg.kenBurns * 0.14 * kb;
457
+ uniforms.uKbZoom.value = zoom;
458
+ uniforms.uKbPan.value.copy(s.kbDir).multiplyScalar((1 - zoom) * 0.5 * kb);
459
+ // the cursor on the slab's own plane
460
+ stepPointerField(uniforms, pointer, state.camera, instance.object, 1, dt, POINTER_ANCHOR, POINTER_NORMAL);
461
+ if (uniforms.uPointerActive.value > 0.01) {
462
+ s.pointerT += dt;
463
+ uniforms.uPointerT.value = s.pointerT;
464
+ }
465
+ });
466
+ if (!cfg.enabled)
467
+ return null;
468
+ return (_jsx("group", { ref: rootRef, children: _jsx("primitive", { object: instance.object }) }));
469
+ };
470
+ export default ShardsImage;
@@ -0,0 +1,126 @@
1
+ import * as THREE from 'three';
2
+ export declare const POINTER_MODES: string[];
3
+ export declare const STRUCTURAL: string[];
4
+ export declare function createUniforms(): {
5
+ uLevels: {
6
+ value: number;
7
+ };
8
+ uLineW: {
9
+ value: number;
10
+ };
11
+ uDepth: {
12
+ value: number;
13
+ };
14
+ uOpen: {
15
+ value: number;
16
+ };
17
+ uSmooth: {
18
+ value: number;
19
+ };
20
+ uIdle: {
21
+ value: number;
22
+ };
23
+ uTint: {
24
+ value: number;
25
+ };
26
+ uLineColor: {
27
+ value: THREE.Color;
28
+ };
29
+ uTexA: {
30
+ value: any;
31
+ };
32
+ uTexB: {
33
+ value: any;
34
+ };
35
+ uFitA: {
36
+ value: THREE.Vector2;
37
+ };
38
+ uFitB: {
39
+ value: THREE.Vector2;
40
+ };
41
+ uP: {
42
+ value: number;
43
+ };
44
+ uHasA: {
45
+ value: number;
46
+ };
47
+ uSeq: {
48
+ value: number;
49
+ };
50
+ uSize: {
51
+ value: THREE.Vector2;
52
+ };
53
+ uTime: {
54
+ value: number;
55
+ };
56
+ uDir: {
57
+ value: THREE.Vector2;
58
+ };
59
+ uSpread: {
60
+ value: number;
61
+ };
62
+ uBlank: {
63
+ value: THREE.Color;
64
+ };
65
+ uIntensity: {
66
+ value: number;
67
+ };
68
+ uOpacity: {
69
+ value: number;
70
+ };
71
+ uBreathe: {
72
+ value: number;
73
+ };
74
+ uPointer: {
75
+ value: THREE.Vector3;
76
+ };
77
+ uPointerVel: {
78
+ value: THREE.Vector2;
79
+ };
80
+ uPointerActive: {
81
+ value: number;
82
+ };
83
+ uPointerMode: {
84
+ value: number;
85
+ };
86
+ uPointerStrength: {
87
+ value: number;
88
+ };
89
+ uPointerRadius: {
90
+ value: number;
91
+ };
92
+ uPointerColor: {
93
+ value: THREE.Color;
94
+ };
95
+ };
96
+ export declare function applyConfig(u: any, c: any): void;
97
+ export declare function build(u: any, c: any): {
98
+ object: THREE.Group<THREE.Object3DEventMap>;
99
+ materials: THREE.ShaderMaterial[];
100
+ controls: {
101
+ show: (t: any) => void;
102
+ readonly busy: boolean;
103
+ pic: {
104
+ st: {
105
+ A: any;
106
+ B: any;
107
+ aspA: number;
108
+ aspB: number;
109
+ p: number;
110
+ dir: number;
111
+ pending: any;
112
+ seq: number;
113
+ frame: number;
114
+ };
115
+ show: (tex: any) => void;
116
+ jump: (tex: any) => void;
117
+ step: (dt: any) => void;
118
+ readonly busy: boolean;
119
+ dispose(): void;
120
+ };
121
+ };
122
+ apply(k: any): void;
123
+ update(dt: any, pointer: any): void;
124
+ dispose(): void;
125
+ };
126
+ //# sourceMappingURL=contour.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contour.d.ts","sourceRoot":"","sources":["../../../../src/components/image/core/contour.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,eAAO,MAAM,aAAa,UAAqB,CAAC;AAEhD,eAAO,MAAM,UAAU,UAAgB,CAAC;AAExC,wBAAgB,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAE7B;AACD,wBAAgB,WAAW,CAAC,CAAC,KAAA,EAAE,CAAC,KAAA,QAG/B;AAgED,wBAAgB,KAAK,CAAC,CAAC,KAAA,EAAE,CAAC,KAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuBzB"}