@wise/art 2.6.0 → 2.7.0-beta.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 (120) hide show
  1. package/dist/CheckMark-365a1dc6.js +39 -0
  2. package/dist/CheckMark-365a1dc6.js.map +1 -0
  3. package/dist/CheckMark-5b996187.esm.js +37 -0
  4. package/dist/CheckMark-5b996187.esm.js.map +1 -0
  5. package/dist/Confetti-b6bfa95b.js +36 -0
  6. package/dist/Confetti-b6bfa95b.js.map +1 -0
  7. package/dist/Confetti-c865d663.esm.js +34 -0
  8. package/dist/Confetti-c865d663.esm.js.map +1 -0
  9. package/dist/Flower-1987844c.esm.js +27 -0
  10. package/dist/Flower-1987844c.esm.js.map +1 -0
  11. package/dist/Flower-385aa337.js +29 -0
  12. package/dist/Flower-385aa337.js.map +1 -0
  13. package/dist/Globe-b5acfedf.js +45 -0
  14. package/dist/Globe-b5acfedf.js.map +1 -0
  15. package/dist/Globe-df8b4bbd.esm.js +43 -0
  16. package/dist/Globe-df8b4bbd.esm.js.map +1 -0
  17. package/dist/Graph-bc618890.js +33 -0
  18. package/dist/Graph-bc618890.js.map +1 -0
  19. package/dist/Graph-e48b9d55.esm.js +31 -0
  20. package/dist/Graph-e48b9d55.esm.js.map +1 -0
  21. package/dist/Illustration.css +19 -0
  22. package/dist/Jars-b371f7ec.esm.js +50 -0
  23. package/dist/Jars-b371f7ec.esm.js.map +1 -0
  24. package/dist/Jars-b80056b7.js +52 -0
  25. package/dist/Jars-b80056b7.js.map +1 -0
  26. package/dist/Lock-0d8008b7.esm.js +41 -0
  27. package/dist/Lock-0d8008b7.esm.js.map +1 -0
  28. package/dist/Lock-841864c6.js +43 -0
  29. package/dist/Lock-841864c6.js.map +1 -0
  30. package/dist/MagnifyingGlass-7b6dda3b.esm.js +30 -0
  31. package/dist/MagnifyingGlass-7b6dda3b.esm.js.map +1 -0
  32. package/dist/MagnifyingGlass-de98441e.js +32 -0
  33. package/dist/MagnifyingGlass-de98441e.js.map +1 -0
  34. package/dist/Marble-5a115e95.esm.js +42 -0
  35. package/dist/Marble-5a115e95.esm.js.map +1 -0
  36. package/dist/Marble-c42785f3.js +44 -0
  37. package/dist/Marble-c42785f3.js.map +1 -0
  38. package/dist/MarbleCard-1792cf0c.esm.js +45 -0
  39. package/dist/MarbleCard-1792cf0c.esm.js.map +1 -0
  40. package/dist/MarbleCard-50b56966.js +47 -0
  41. package/dist/MarbleCard-50b56966.js.map +1 -0
  42. package/dist/MultiCurrency-4735dbb2.esm.js +61 -0
  43. package/dist/MultiCurrency-4735dbb2.esm.js.map +1 -0
  44. package/dist/MultiCurrency-fcf4b9a2.js +63 -0
  45. package/dist/MultiCurrency-fcf4b9a2.js.map +1 -0
  46. package/dist/Plane-1e15b49c.esm.js +37 -0
  47. package/dist/Plane-1e15b49c.esm.js.map +1 -0
  48. package/dist/Plane-91b11234.js +39 -0
  49. package/dist/Plane-91b11234.js.map +1 -0
  50. package/dist/Scene-3830de67.esm.js +48 -0
  51. package/dist/Scene-3830de67.esm.js.map +1 -0
  52. package/dist/Scene-fa187d3a.js +50 -0
  53. package/dist/Scene-fa187d3a.js.map +1 -0
  54. package/dist/common.d.ts +5 -0
  55. package/dist/common.d.ts.map +1 -1
  56. package/dist/illustrations3d/Illustration3d.d.ts +11 -0
  57. package/dist/illustrations3d/Illustration3d.d.ts.map +1 -0
  58. package/dist/illustrations3d/Scene.d.ts +9 -0
  59. package/dist/illustrations3d/Scene.d.ts.map +1 -0
  60. package/dist/illustrations3d/index.d.ts +5 -0
  61. package/dist/illustrations3d/index.d.ts.map +1 -0
  62. package/dist/illustrations3d/models/CheckMark.d.ts +4 -0
  63. package/dist/illustrations3d/models/CheckMark.d.ts.map +1 -0
  64. package/dist/illustrations3d/models/Confetti.d.ts +4 -0
  65. package/dist/illustrations3d/models/Confetti.d.ts.map +1 -0
  66. package/dist/illustrations3d/models/Flower.d.ts +4 -0
  67. package/dist/illustrations3d/models/Flower.d.ts.map +1 -0
  68. package/dist/illustrations3d/models/Globe.d.ts +4 -0
  69. package/dist/illustrations3d/models/Globe.d.ts.map +1 -0
  70. package/dist/illustrations3d/models/Graph.d.ts +4 -0
  71. package/dist/illustrations3d/models/Graph.d.ts.map +1 -0
  72. package/dist/illustrations3d/models/Jars.d.ts +4 -0
  73. package/dist/illustrations3d/models/Jars.d.ts.map +1 -0
  74. package/dist/illustrations3d/models/Lock.d.ts +4 -0
  75. package/dist/illustrations3d/models/Lock.d.ts.map +1 -0
  76. package/dist/illustrations3d/models/MagnifyingGlass.d.ts +4 -0
  77. package/dist/illustrations3d/models/MagnifyingGlass.d.ts.map +1 -0
  78. package/dist/illustrations3d/models/Marble.d.ts +4 -0
  79. package/dist/illustrations3d/models/Marble.d.ts.map +1 -0
  80. package/dist/illustrations3d/models/MarbleCard.d.ts +4 -0
  81. package/dist/illustrations3d/models/MarbleCard.d.ts.map +1 -0
  82. package/dist/illustrations3d/models/MultiCurrency.d.ts +4 -0
  83. package/dist/illustrations3d/models/MultiCurrency.d.ts.map +1 -0
  84. package/dist/illustrations3d/models/Plane.d.ts +4 -0
  85. package/dist/illustrations3d/models/Plane.d.ts.map +1 -0
  86. package/dist/illustrations3d/utils.d.ts +9 -0
  87. package/dist/illustrations3d/utils.d.ts.map +1 -0
  88. package/dist/index-36ff762e.js +332 -0
  89. package/dist/index-36ff762e.js.map +1 -0
  90. package/dist/index-76341731.esm.js +325 -0
  91. package/dist/index-76341731.esm.js.map +1 -0
  92. package/dist/index.d.ts +3 -0
  93. package/dist/index.d.ts.map +1 -1
  94. package/dist/index.esm.js +5 -0
  95. package/dist/index.esm.js.map +1 -0
  96. package/dist/index.js +15 -155
  97. package/dist/index.js.map +1 -1
  98. package/package.json +15 -14
  99. package/src/common.ts +6 -0
  100. package/src/illustrations/Illustration.css +19 -0
  101. package/src/illustrations3d/Illustration3d.stories.tsx +89 -0
  102. package/src/illustrations3d/Illustration3d.tsx +133 -0
  103. package/src/illustrations3d/Scene.tsx +54 -0
  104. package/src/illustrations3d/index.ts +6 -0
  105. package/src/illustrations3d/models/CheckMark.tsx +30 -0
  106. package/src/illustrations3d/models/Confetti.tsx +29 -0
  107. package/src/illustrations3d/models/Flower.tsx +24 -0
  108. package/src/illustrations3d/models/Globe.tsx +41 -0
  109. package/src/illustrations3d/models/Graph.tsx +26 -0
  110. package/src/illustrations3d/models/Jars.tsx +47 -0
  111. package/src/illustrations3d/models/Lock.tsx +38 -0
  112. package/src/illustrations3d/models/MagnifyingGlass.tsx +30 -0
  113. package/src/illustrations3d/models/Marble.tsx +47 -0
  114. package/src/illustrations3d/models/MarbleCard.tsx +50 -0
  115. package/src/illustrations3d/models/MultiCurrency.tsx +58 -0
  116. package/src/illustrations3d/models/Plane.tsx +33 -0
  117. package/src/illustrations3d/utils.ts +68 -0
  118. package/src/index.ts +5 -0
  119. package/dist/index.mjs +0 -159
  120. package/dist/index.mjs.map +0 -1
@@ -6,3 +6,22 @@ img.wds-illustration {
6
6
  .wds-illustration-padding {
7
7
  padding: 24px;
8
8
  }
9
+
10
+ .wds-illustration-3d {
11
+ display: inline-flex;
12
+ }
13
+
14
+ .wds-illustration-3d-small {
15
+ width: 200px;
16
+ height: 200px;
17
+ }
18
+
19
+ .wds-illustration-3d-medium {
20
+ width: 300px;
21
+ height: 300px;
22
+ }
23
+
24
+ .wds-illustration-3d-large {
25
+ width: 500px;
26
+ height: 500px;
27
+ }
@@ -0,0 +1,89 @@
1
+ /* eslint-disable @typescript-eslint/no-unsafe-return */
2
+ import React, { useEffect } from 'react';
3
+
4
+ import { Sizes } from '../common';
5
+ import { Assets } from '../illustrations/metadata';
6
+
7
+ import Illustration3d from './Illustration3d';
8
+
9
+ export default {
10
+ title: '3D Illustrations',
11
+ };
12
+
13
+ export const Confetti = () => {
14
+ return (
15
+ <>
16
+ <Illustration3d name={Assets.CONFETTI} size={Sizes.LARGE} />
17
+ </>
18
+ );
19
+ };
20
+
21
+ export const Globe = () => {
22
+ return (
23
+ <>
24
+ <Illustration3d name={Assets.GLOBE} size={Sizes.LARGE} />
25
+ </>
26
+ );
27
+ };
28
+
29
+ export const Lock = () => {
30
+ return <Illustration3d name={Assets.LOCK} size={Sizes.LARGE} />;
31
+ };
32
+
33
+ export const CheckMark = () => {
34
+ return <Illustration3d name={Assets.CHECK_MARK} size={Sizes.LARGE} />;
35
+ };
36
+
37
+ export const Flower = () => {
38
+ return <Illustration3d name={Assets.FLOWER} size={Sizes.LARGE} />;
39
+ };
40
+
41
+ export const Plane = () => {
42
+ return <Illustration3d name={Assets.PLANE} size={Sizes.LARGE} />;
43
+ };
44
+
45
+ export const Graph = () => {
46
+ return <Illustration3d name={Assets.GRAPH} size={Sizes.LARGE} />;
47
+ };
48
+
49
+ export const Marble = () => {
50
+ return <Illustration3d name={Assets.MARBLE} size={Sizes.LARGE} />;
51
+ };
52
+
53
+ export const MarbleCard = () => {
54
+ return <Illustration3d name={Assets.MARBLE_CARD} size={Sizes.LARGE} />;
55
+ };
56
+
57
+ export const MagnifyingGlass = () => {
58
+ return <Illustration3d name={Assets.MAGNIFYING_GLASS} size={Sizes.LARGE} />;
59
+ };
60
+
61
+ export const Jars = () => {
62
+ return <Illustration3d name={Assets.JARS} size={Sizes.LARGE} />;
63
+ };
64
+
65
+ export const MultiCurrency = () => {
66
+ return <Illustration3d name={Assets.MULTI_CURRENCY} size={Sizes.LARGE} />;
67
+ };
68
+
69
+ export const Fallback = () => {
70
+ // @ts-expect-error navigator has connection property
71
+ const originalNavigator = window.navigator.connection;
72
+ // mock slow internet connection
73
+ // @ts-expect-error navigator has connection property
74
+ window.navigator.connection = { effectiveType: 'slow-2g' };
75
+
76
+ useEffect(() => {
77
+ // cleanup mock on unmount
78
+ // @ts-expect-error navigator has connection property
79
+ return () => (window.navigator.connection = originalNavigator);
80
+ }, [originalNavigator]);
81
+
82
+ return (
83
+ <>
84
+ <Illustration3d name={Assets.LOCK} />
85
+ <br />
86
+ Mock slow internet connection so it fallback to static illustration
87
+ </>
88
+ );
89
+ };
@@ -0,0 +1,133 @@
1
+ /* eslint-disable fp/no-mutation */
2
+ import { clsx } from 'clsx';
3
+ import { lazy, Suspense, useEffect, useState, LazyExoticComponent } from 'react';
4
+
5
+ import { LargeSize, MediumSize, SmallSize, Sizes } from '../common';
6
+
7
+ import Illustration, { Assets } from './../illustrations';
8
+ import { useBattery, isConnectionSlow, isBatteryLow } from './utils';
9
+
10
+ export type Illustration3dNames =
11
+ | 'lock'
12
+ | 'globe'
13
+ | 'confetti'
14
+ | 'check-mark'
15
+ | 'flower'
16
+ | 'graph'
17
+ | 'jars'
18
+ | 'magnifying-glass'
19
+ | 'marble'
20
+ | 'marble-card'
21
+ | 'multi-currency'
22
+ | 'plane';
23
+
24
+ export type Props = {
25
+ name: Illustration3dNames;
26
+ size?: SmallSize | MediumSize | LargeSize;
27
+ className?: string;
28
+ };
29
+
30
+ enum RenderMode {
31
+ INIT,
32
+ FALLBACK,
33
+ ASSET_3D,
34
+ }
35
+
36
+ const Illustration3d = ({ name, size = Sizes.MEDIUM, className }: Props) => {
37
+ const [renderMode, setRenderMode] = useState<RenderMode>(RenderMode.INIT);
38
+ const [inintrinsicSize, setInintrinsicSize] = useState<Props['size']>(size);
39
+ const batteryData = useBattery();
40
+
41
+ useEffect(() => {
42
+ setRenderMode(
43
+ isConnectionSlow() || isBatteryLow(batteryData.level)
44
+ ? RenderMode.FALLBACK
45
+ : RenderMode.ASSET_3D,
46
+ );
47
+ const isMobile: boolean =
48
+ (typeof window !== undefined && window?.matchMedia('(max-width: 575px)')?.matches) ?? false;
49
+ if (isMobile) {
50
+ setInintrinsicSize(Sizes.SMALL);
51
+ }
52
+ }, [batteryData]);
53
+
54
+ return (
55
+ <div
56
+ className={clsx(
57
+ 'wds-illustration-3d',
58
+ `wds-illustration-3d-${name}`,
59
+ `wds-illustration-3d-${inintrinsicSize as string}`,
60
+ className,
61
+ )}
62
+ >
63
+ {renderMode === RenderMode.INIT ? null : renderMode === RenderMode.ASSET_3D ? (
64
+ <Suspense fallback={null}>{getModel({ name, size: inintrinsicSize })}</Suspense>
65
+ ) : (
66
+ <Illustration name={name} size={size} alt="" />
67
+ )}
68
+ </div>
69
+ );
70
+ };
71
+
72
+ function getModel({ name, size }: Props) {
73
+ // @ts-expect-error unknown generic
74
+ let Model: LazyExoticComponent = <></>;
75
+ const Scene = lazy(() => import('./Scene'));
76
+ switch (name) {
77
+ case Assets.LOCK: {
78
+ Model = lazy(() => import('./models/Lock'));
79
+ break;
80
+ }
81
+ case Assets.GLOBE: {
82
+ Model = lazy(() => import('./models/Globe'));
83
+ break;
84
+ }
85
+ case Assets.CONFETTI: {
86
+ Model = lazy(() => import('./models/Confetti'));
87
+ break;
88
+ }
89
+ case Assets.CHECK_MARK: {
90
+ Model = lazy(() => import('./models/CheckMark'));
91
+ break;
92
+ }
93
+ case Assets.FLOWER: {
94
+ Model = lazy(() => import('./models/Flower'));
95
+ break;
96
+ }
97
+ case Assets.PLANE: {
98
+ Model = lazy(() => import('./models/Plane'));
99
+ break;
100
+ }
101
+ case Assets.GRAPH: {
102
+ Model = lazy(() => import('./models/Graph'));
103
+ break;
104
+ }
105
+ case Assets.MARBLE: {
106
+ Model = lazy(() => import('./models/Marble'));
107
+ break;
108
+ }
109
+ case Assets.MARBLE_CARD: {
110
+ Model = lazy(() => import('./models/MarbleCard'));
111
+ break;
112
+ }
113
+ case Assets.MAGNIFYING_GLASS: {
114
+ Model = lazy(() => import('./models/MagnifyingGlass'));
115
+ break;
116
+ }
117
+ case Assets.JARS: {
118
+ Model = lazy(() => import('./models/Jars'));
119
+ break;
120
+ }
121
+ case Assets.MULTI_CURRENCY: {
122
+ Model = lazy(() => import('./models/MultiCurrency'));
123
+ break;
124
+ }
125
+ }
126
+ return (
127
+ <Scene assetName={name} size={size}>
128
+ <Model />
129
+ </Scene>
130
+ );
131
+ }
132
+
133
+ export default Illustration3d;
@@ -0,0 +1,54 @@
1
+ /* eslint-disable react/forbid-dom-props */
2
+ /* eslint-disable react/function-component-definition */
3
+ import { PerspectiveCamera } from '@react-three/drei';
4
+ import { Canvas } from '@react-three/fiber';
5
+ import type { PropsWithChildren } from 'react';
6
+ import { PCFShadowMap, LinearToneMapping, SRGBColorSpace } from 'three';
7
+
8
+ import { ImageSizes, LargeSize, MediumSize, Sizes, SmallSize } from '../common';
9
+ import { Assets } from '../illustrations/metadata';
10
+
11
+ import type { Illustration3dNames } from './Illustration3d';
12
+
13
+ export type Props = PropsWithChildren<{
14
+ assetName: Illustration3dNames;
15
+ size?: SmallSize | MediumSize | LargeSize;
16
+ }>;
17
+
18
+ export default function Scene({ children, assetName, size = Sizes.MEDIUM }: Props) {
19
+ const castShadows: boolean = [
20
+ Assets.LOCK as string,
21
+ Assets.MULTI_CURRENCY as string,
22
+ Assets.MAGNIFYING_GLASS as string,
23
+ ].includes(assetName);
24
+ return (
25
+ <Canvas
26
+ onCreated={({ gl }) => {
27
+ gl.setClearColor(0x000000, 0);
28
+ gl.setSize(ImageSizes[size], ImageSizes[size]);
29
+ gl.clearDepth();
30
+ }}
31
+ gl={{
32
+ alpha: true,
33
+ antialias: true,
34
+ pixelRatio: window.devicePixelRatio * 1,
35
+ toneMapping: LinearToneMapping,
36
+ outputColorSpace: SRGBColorSpace,
37
+ }}
38
+ shadows={{
39
+ type: PCFShadowMap,
40
+ enabled: castShadows,
41
+ }}
42
+ >
43
+ <PerspectiveCamera
44
+ makeDefault
45
+ far={1000000000000}
46
+ near={0.1}
47
+ fov={10.29}
48
+ aspect={window.innerWidth / window.innerHeight}
49
+ position={[0, 0, 100]}
50
+ />
51
+ {children}
52
+ </Canvas>
53
+ );
54
+ }
@@ -0,0 +1,6 @@
1
+ export { default } from './Illustration3d';
2
+ export type { Props as Illustration3dProps } from './Illustration3d';
3
+
4
+ export type { Illustration3dNames } from './Illustration3d';
5
+
6
+ export { is3dIllustrationSupported } from './utils';
@@ -0,0 +1,30 @@
1
+ import { useGLTF, useAnimations } from '@react-three/drei';
2
+ import { useFrame, useLoader } from '@react-three/fiber';
3
+ import { useRef } from 'react';
4
+ import { ObjectLoader, LoopOnce } from 'three';
5
+
6
+ import { defineSrc } from '../utils';
7
+
8
+ const CheckMark = () => {
9
+ const modelRef = useRef();
10
+ const model = useGLTF(defineSrc('check-mark.gltf'));
11
+ const { animations, scene } = model;
12
+
13
+ const lights = useLoader(ObjectLoader, defineSrc('check-mark-light.json'));
14
+
15
+ const { mixer, clips } = useAnimations(animations, modelRef);
16
+ useFrame(() => {
17
+ model.materials['Standard'].map.offset.x += -0.0025;
18
+
19
+ mixer.clipAction(clips[0]).play().setLoop(LoopOnce, 1);
20
+ });
21
+
22
+ return (
23
+ <>
24
+ <primitive ref={modelRef} scale={1.4} object={scene} />
25
+ <primitive object={lights} />
26
+ </>
27
+ );
28
+ };
29
+
30
+ export default CheckMark;
@@ -0,0 +1,29 @@
1
+ import { useGLTF, useAnimations } from '@react-three/drei';
2
+ import { useFrame, useLoader } from '@react-three/fiber';
3
+ import { useRef } from 'react';
4
+ import { ObjectLoader, LoopOnce } from 'three';
5
+
6
+ import { defineSrc } from '../utils';
7
+
8
+ const Confetti = () => {
9
+ const ref = useRef();
10
+ const model = useGLTF(defineSrc('confetti.gltf'));
11
+
12
+ const lights = useLoader(ObjectLoader, defineSrc('confetti-light.json'));
13
+
14
+ const { mixer, clips } = useAnimations(model.animations, ref);
15
+ useFrame(() => {
16
+ model.materials['Tapestry WebGL'].map.offset.x += -0.0015;
17
+
18
+ mixer.clipAction(clips[0]).play().setLoop(LoopOnce, 1);
19
+ });
20
+
21
+ return (
22
+ <>
23
+ <primitive ref={ref} scale={1.5} position={[0, 1.5, 0]} object={model.scene} />
24
+ <primitive object={lights} />
25
+ </>
26
+ );
27
+ };
28
+
29
+ export default Confetti;
@@ -0,0 +1,24 @@
1
+ import { useGLTF } from '@react-three/drei';
2
+ import { useFrame, useLoader } from '@react-three/fiber';
3
+ import { ObjectLoader } from 'three';
4
+
5
+ import { defineSrc } from '../utils';
6
+
7
+ const Flower = () => {
8
+ const model = useGLTF(defineSrc('flower.gltf'));
9
+
10
+ const lights = useLoader(ObjectLoader, defineSrc('flower-light.json'));
11
+
12
+ useFrame(() => {
13
+ model.materials['Tapestry WebGL'].map.offset.x += -0.001;
14
+ });
15
+
16
+ return (
17
+ <>
18
+ <primitive scale={1.3} position={[0, -9, 0]} object={model.scene} />
19
+ <primitive object={lights} />
20
+ </>
21
+ );
22
+ };
23
+
24
+ export default Flower;
@@ -0,0 +1,41 @@
1
+ import { useGLTF } from '@react-three/drei';
2
+ import { useFrame, useLoader } from '@react-three/fiber';
3
+ import { TextureLoader, ObjectLoader } from 'three';
4
+
5
+ import { defineSrc } from '../utils';
6
+
7
+ const Globe = () => {
8
+ const { scene } = useGLTF(defineSrc('globe.gltf'));
9
+
10
+ const lights = useLoader(ObjectLoader, defineSrc('globe-light.json'));
11
+ const wiseLogo = useLoader(TextureLoader, defineSrc('wise-flag-map-bump.jpg'));
12
+ const planet = scene.getObjectByName('Globe');
13
+ const orbit = scene.getObjectByName('Coins_Axis_Rotation_Animate');
14
+
15
+ scene.traverse((child) => {
16
+ if (child.name.startsWith('Coin_')) {
17
+ const mesh = child;
18
+
19
+ const material = mesh.material;
20
+ material.bumpMap = wiseLogo;
21
+ material.bumpMap.flipY = false;
22
+ mesh.castShadow = false;
23
+ mesh.receiveShadow = false;
24
+ }
25
+ });
26
+
27
+ useFrame(() => {
28
+ orbit.rotation.y += 0.002;
29
+
30
+ planet.material.map.offset.x += -0.0002;
31
+ });
32
+
33
+ return (
34
+ <>
35
+ <primitive position={[0, -10, 0]} scale={1.3} object={scene} />
36
+ <primitive object={lights} />
37
+ </>
38
+ );
39
+ };
40
+
41
+ export default Globe;
@@ -0,0 +1,26 @@
1
+ import { useGLTF } from '@react-three/drei';
2
+ import { useFrame, useLoader } from '@react-three/fiber';
3
+ import { ObjectLoader } from 'three';
4
+
5
+ import { defineSrc } from '../utils';
6
+
7
+ const Graph = () => {
8
+ const model = useGLTF(defineSrc(`graph.gltf`));
9
+
10
+ const lights = useLoader(ObjectLoader, defineSrc('graph-light.json'));
11
+
12
+ useFrame(() => {
13
+ const { offset } = model.materials['Standard '].map;
14
+ offset.x += -0.0015;
15
+ offset.y += 0.0015;
16
+ });
17
+
18
+ return (
19
+ <>
20
+ <primitive scale={1.3} position={[0, -10, 0]} object={model.scene} />
21
+ <primitive object={lights} />
22
+ </>
23
+ );
24
+ };
25
+
26
+ export default Graph;
@@ -0,0 +1,47 @@
1
+ import { useGLTF, useAnimations } from '@react-three/drei';
2
+ import { useFrame, useLoader } from '@react-three/fiber';
3
+ import { useRef } from 'react';
4
+ import { TextureLoader, ObjectLoader } from 'three';
5
+
6
+ import { defineSrc } from '../utils';
7
+
8
+ const Jars = () => {
9
+ const ref = useRef();
10
+ const model = useGLTF(defineSrc('jars.gltf'));
11
+ const lights = useLoader(ObjectLoader, defineSrc('jars-light.json'));
12
+ const wiseLogo = useLoader(TextureLoader, defineSrc('wise-flag-map-bump.jpg'));
13
+ const jars = [];
14
+
15
+ model.scene.traverse((child) => {
16
+ if (child.name.startsWith('Coin_')) {
17
+ child.material.bumpMap = wiseLogo;
18
+
19
+ child.material.bumpMap.flipY = false;
20
+ child.castShadow = false;
21
+ child.receiveShadow = false;
22
+ }
23
+ if (child.name.startsWith('Jar_')) {
24
+ jars.push(child);
25
+ }
26
+ });
27
+
28
+ const { mixer, clips } = useAnimations(model.animations, ref);
29
+
30
+ useFrame(() => {
31
+ mixer.clipAction(clips[0]).play();
32
+
33
+ jars.forEach((jar) => {
34
+ jar.material.map.offset.x += 0.001;
35
+ jar.material.map.offset.y += 0.0;
36
+ });
37
+ });
38
+
39
+ return (
40
+ <>
41
+ <primitive ref={ref} scale={1.3} position={[0, -10, 0]} object={model.scene} />
42
+ <primitive object={lights} />
43
+ </>
44
+ );
45
+ };
46
+
47
+ export default Jars;
@@ -0,0 +1,38 @@
1
+ import { useGLTF, useAnimations } from '@react-three/drei';
2
+ import { useFrame, useLoader } from '@react-three/fiber';
3
+ import { useRef } from 'react';
4
+ import { LoopOnce, ObjectLoader } from 'three';
5
+
6
+ import { defineSrc } from '../utils';
7
+
8
+ const Lock = () => {
9
+ const ref = useRef();
10
+ const model = useGLTF(defineSrc('lock.gltf'));
11
+
12
+ const lights = useLoader(ObjectLoader, defineSrc('lock-light.json'));
13
+
14
+ model.scene.traverse((node) => {
15
+ if (node.isMesh) {
16
+ node.castShadow = true;
17
+ node.receiveShadow = true;
18
+ }
19
+ });
20
+
21
+ const { clips, mixer } = useAnimations(model.animations, ref);
22
+ let frame = 0;
23
+ useFrame(() => {
24
+ mixer.clipAction(clips[0]).play().setLoop(LoopOnce, 1);
25
+ model.scene.position.y = Math.sin(frame++ * 0.04) * 0.2;
26
+
27
+ model.materials.Standard.map.offset.x += -0.001;
28
+ });
29
+
30
+ return (
31
+ <>
32
+ <primitive ref={ref} scale={1.4} object={model.scene} />
33
+ <primitive object={lights} />
34
+ </>
35
+ );
36
+ };
37
+
38
+ export default Lock;
@@ -0,0 +1,30 @@
1
+ import { useGLTF } from '@react-three/drei';
2
+ import { useFrame, useLoader } from '@react-three/fiber';
3
+ import { ObjectLoader } from 'three';
4
+
5
+ import { defineSrc } from '../utils';
6
+
7
+ const MagnifyingGlass = () => {
8
+ const model = useGLTF(defineSrc(`magnifying-glass.gltf`));
9
+
10
+ const lights = useLoader(ObjectLoader, defineSrc('magnifying-glass-light.json'));
11
+
12
+ const lens = model.scene.getObjectByName('Optimised_lens');
13
+
14
+ useFrame(() => {
15
+ lens.material.transparent = true;
16
+
17
+ lens.material.opacity = 0.8;
18
+
19
+ model.materials['Tapestry WebGL'].map.offset.x += -0.0006;
20
+ });
21
+
22
+ return (
23
+ <>
24
+ <primitive scale={1.5} position={[0, -12, 0]} object={model.scene} />
25
+ <primitive object={lights} />
26
+ </>
27
+ );
28
+ };
29
+
30
+ export default MagnifyingGlass;
@@ -0,0 +1,47 @@
1
+ import { useGLTF } from '@react-three/drei';
2
+ import { useFrame, useLoader } from '@react-three/fiber';
3
+ import { ObjectLoader } from 'three';
4
+
5
+ import { defineSrc } from '../utils';
6
+
7
+ const Marble = () => {
8
+ const model = useGLTF(defineSrc('marble.gltf'));
9
+
10
+ const lights = useLoader(ObjectLoader, defineSrc('marble-light.json'));
11
+
12
+ const sphere = model.scene.getObjectByName('Sphere1');
13
+ sphere.material.depthTest = true;
14
+
15
+ const stripeBottom = model.scene.getObjectByName('Strip_Center_Big_(4th_-_Bottom_Layer)');
16
+ stripeBottom.material.depthTest = false;
17
+ stripeBottom.renderOrder = 1;
18
+
19
+ const stripeLeft = model.scene.getObjectByName('Strip_Left_(3rd)');
20
+ stripeLeft.material.depthTest = false;
21
+ stripeLeft.renderOrder = 2;
22
+
23
+ const stripeRight = model.scene.getObjectByName('Strip_Left_(3rd)');
24
+ stripeRight.material.depthTest = false;
25
+ stripeRight.renderOrder = 3;
26
+
27
+ const stripeTop = model.scene.getObjectByName('Strip_Center_(1st_-_Top_Layer)');
28
+ stripeTop.material.depthTest = false;
29
+ stripeTop.renderOrder = 4;
30
+
31
+ const animatedMaps = [sphere, stripeTop, stripeBottom, stripeLeft, stripeRight].map(
32
+ (object) => object.material.map,
33
+ );
34
+
35
+ useFrame(() => {
36
+ animatedMaps.forEach((map) => (map.offset.y += -0.0015));
37
+ });
38
+
39
+ return (
40
+ <>
41
+ <primitive scale={1.4} position={[0, -11, 0]} object={model.scene} />
42
+ <primitive object={lights} />
43
+ </>
44
+ );
45
+ };
46
+
47
+ export default Marble;
@@ -0,0 +1,50 @@
1
+ import { useGLTF } from '@react-three/drei';
2
+ import { useFrame, useLoader } from '@react-three/fiber';
3
+ import { ObjectLoader } from 'three';
4
+
5
+ import { defineSrc } from '../utils';
6
+
7
+ const MarbleCard = () => {
8
+ const model = useGLTF(defineSrc('marble-card.gltf'));
9
+
10
+ const lights = useLoader(ObjectLoader, defineSrc('marble-card-light.json'));
11
+ const sphere = model.scene.getObjectByName('Sphere1');
12
+ sphere.material.depthTest = true;
13
+
14
+ const stripeBottom = model.scene.getObjectByName('Strip_Center_Big_(4th_-_Bottom_Layer)');
15
+ stripeBottom.material.depthTest = false;
16
+ stripeBottom.renderOrder = 1;
17
+
18
+ const stripeLeft = model.scene.getObjectByName('Strip_Left_(3rd)');
19
+ stripeLeft.material.depthTest = false;
20
+ stripeLeft.renderOrder = 2;
21
+
22
+ const stripeRight = model.scene.getObjectByName('Strip_Right_(2nd)');
23
+ stripeRight.material.depthTest = false;
24
+ stripeRight.renderOrder = 3;
25
+
26
+ const stripeTop = model.scene.getObjectByName('Strip_Center_(1st_-_Top_Layer)');
27
+ stripeTop.material.depthTest = false;
28
+ stripeTop.renderOrder = 4;
29
+
30
+ const card = model.scene.getObjectByName('Plane');
31
+ card.material.depthTest = false;
32
+ card.material.metalness = 0;
33
+
34
+ const animatedMaps = [sphere, stripeTop, stripeBottom, stripeLeft, stripeRight].map(
35
+ (object) => object.material.map,
36
+ );
37
+
38
+ useFrame(() => {
39
+ animatedMaps.forEach((map) => (map.offset.y += -0.0015));
40
+ });
41
+
42
+ return (
43
+ <>
44
+ <primitive scale={1.4} position={[0, -10, 0]} object={model.scene} />
45
+ <primitive object={lights} />
46
+ </>
47
+ );
48
+ };
49
+
50
+ export default MarbleCard;