@benjos/create-boilerplate 1.5.0 → 1.5.2

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 (92) hide show
  1. package/README.md +6 -5
  2. package/dist/index.js +5 -1
  3. package/dist/index.js.map +1 -1
  4. package/package.json +3 -2
  5. package/template-react/package-lock.json +2 -2
  6. package/template-react/package.json +1 -1
  7. package/template-vanilla/package-lock.json +2 -2
  8. package/template-vanilla/package.json +1 -1
  9. package/template-vanilla/readme.md +12 -9
  10. package/template-vue/.prettierignore +6 -0
  11. package/template-vue/.prettierrc +10 -0
  12. package/template-vue/eslint.config.js +130 -0
  13. package/template-vue/index.html +17 -0
  14. package/template-vue/package-lock.json +4082 -0
  15. package/template-vue/package.json +43 -0
  16. package/template-vue/public/assets/fonts/LICENSE +13 -0
  17. package/template-vue/public/assets/fonts/template.typeface.json +1 -0
  18. package/template-vue/public/assets/hdrs/template.hdr +0 -0
  19. package/template-vue/public/assets/icons/benjosLogoBlack.svg +5 -0
  20. package/template-vue/public/assets/loaders/draco/README.md +32 -0
  21. package/template-vue/public/assets/loaders/draco/draco_decoder.js +34 -0
  22. package/template-vue/public/assets/loaders/draco/draco_decoder.wasm +0 -0
  23. package/template-vue/public/assets/loaders/draco/draco_encoder.js +33 -0
  24. package/template-vue/public/assets/loaders/draco/draco_wasm_wrapper.js +117 -0
  25. package/template-vue/public/assets/loaders/draco/gltf/draco_decoder.js +33 -0
  26. package/template-vue/public/assets/loaders/draco/gltf/draco_decoder.wasm +0 -0
  27. package/template-vue/public/assets/loaders/draco/gltf/draco_encoder.js +33 -0
  28. package/template-vue/public/assets/loaders/draco/gltf/draco_wasm_wrapper.js +116 -0
  29. package/template-vue/public/assets/models/template.glb +0 -0
  30. package/template-vue/public/assets/textures/template.jpg +0 -0
  31. package/template-vue/readme.md +34 -0
  32. package/template-vue/src/experiences/Experience.ts +27 -0
  33. package/template-vue/src/experiences/cameras/threes/DebugThreeCameraController.ts +55 -0
  34. package/template-vue/src/experiences/cameras/threes/LoaderThreeCameraController.ts +25 -0
  35. package/template-vue/src/experiences/cameras/threes/MainThreeCameraController.ts +24 -0
  36. package/template-vue/src/experiences/cameras/threes/bases/ThreeCameraControllerBase.ts +90 -0
  37. package/template-vue/src/experiences/commands/InitCommand.ts +50 -0
  38. package/template-vue/src/experiences/constants/experiences/AnimationId.ts +3 -0
  39. package/template-vue/src/experiences/constants/experiences/AssetId.ts +8 -0
  40. package/template-vue/src/experiences/constants/experiences/CameraId.ts +7 -0
  41. package/template-vue/src/experiences/constants/experiences/DebugGuiTitle.ts +6 -0
  42. package/template-vue/src/experiences/constants/experiences/Object3dId.ts +3 -0
  43. package/template-vue/src/experiences/constants/experiences/ViewId.ts +16 -0
  44. package/template-vue/src/experiences/constants/experiences/ViewType.ts +6 -0
  45. package/template-vue/src/experiences/engines/threes/MainThree.ts +11 -0
  46. package/template-vue/src/experiences/engines/threes/app/LoaderThreeApp.ts +49 -0
  47. package/template-vue/src/experiences/engines/threes/app/MainThreeApp.ts +109 -0
  48. package/template-vue/src/experiences/engines/threes/app/bases/ThreeAppBase.ts +128 -0
  49. package/template-vue/src/experiences/engines/vues/MainVue.vue +9 -0
  50. package/template-vue/src/experiences/managers/DebugManager.ts +87 -0
  51. package/template-vue/src/experiences/managers/LoaderManager.ts +177 -0
  52. package/template-vue/src/experiences/managers/threes/ThreeAssetsManager.ts +263 -0
  53. package/template-vue/src/experiences/managers/threes/ThreeCameraControllerManager.ts +46 -0
  54. package/template-vue/src/experiences/managers/threes/ThreeRaycasterManager.ts +21 -0
  55. package/template-vue/src/experiences/materials/threes/loaders/LoaderMaterial.ts +44 -0
  56. package/template-vue/src/experiences/renderers/threes/LoaderRenderer.ts +18 -0
  57. package/template-vue/src/experiences/renderers/threes/Renderer.ts +71 -0
  58. package/template-vue/src/experiences/renderers/threes/bases/WebGLRendererBase.ts +29 -0
  59. package/template-vue/src/experiences/shaders/threes/loaders/LoaderFragmentShader.glsl +8 -0
  60. package/template-vue/src/experiences/shaders/threes/loaders/LoaderVertexShader.glsl +3 -0
  61. package/template-vue/src/experiences/styles/abstracts/_import.scss +5 -0
  62. package/template-vue/src/experiences/styles/abstracts/functions.scss +3 -0
  63. package/template-vue/src/experiences/styles/abstracts/mixins.scss +0 -0
  64. package/template-vue/src/experiences/styles/abstracts/variables.scss +7 -0
  65. package/template-vue/src/experiences/styles/commons/fonts.scss +10 -0
  66. package/template-vue/src/experiences/styles/commons/main.scss +59 -0
  67. package/template-vue/src/experiences/styles/commons/texts.scss +1 -0
  68. package/template-vue/src/experiences/styles/style.scss +7 -0
  69. package/template-vue/src/experiences/styles/views/loader.scss +70 -0
  70. package/template-vue/src/experiences/types/assetTypes.ts +8 -0
  71. package/template-vue/src/experiences/types/cameraTypes.ts +37 -0
  72. package/template-vue/src/experiences/types/global.d.ts +9 -0
  73. package/template-vue/src/experiences/types/shaders.d.ts +4 -0
  74. package/template-vue/src/experiences/views/threes/bases/ThreeViewBase.ts +49 -0
  75. package/template-vue/src/experiences/views/threes/loaders/LoaderThreeView.ts +28 -0
  76. package/template-vue/src/experiences/views/threes/loaders/components/TemplateLoaderThreeActor.ts +49 -0
  77. package/template-vue/src/experiences/views/threes/worlds/World2ThreeView.ts +35 -0
  78. package/template-vue/src/experiences/views/threes/worlds/WorldThreeView.ts +35 -0
  79. package/template-vue/src/experiences/views/threes/worlds/components/Environment.ts +89 -0
  80. package/template-vue/src/experiences/views/threes/worlds/components/actors/TemplateFont.ts +58 -0
  81. package/template-vue/src/experiences/views/threes/worlds/components/actors/TemplateMesh.ts +65 -0
  82. package/template-vue/src/experiences/views/threes/worlds/components/actors/TemplateMesh2.ts +71 -0
  83. package/template-vue/src/experiences/views/threes/worlds/components/actors/TemplateModel.ts +33 -0
  84. package/template-vue/src/experiences/views/threes/worlds/components/actors/bases/ThreeActorBase.ts +44 -0
  85. package/template-vue/src/experiences/views/threes/worlds/components/actors/bases/ThreeAnimatedModelBase.ts +63 -0
  86. package/template-vue/src/experiences/views/threes/worlds/components/actors/bases/ThreeModelBase.ts +48 -0
  87. package/template-vue/src/experiences/views/vues/LoaderView.vue +55 -0
  88. package/template-vue/src/main.ts +7 -0
  89. package/template-vue/tsconfig.app.json +14 -0
  90. package/template-vue/tsconfig.json +7 -0
  91. package/template-vue/tsconfig.node.json +17 -0
  92. package/template-vue/vite.config.ts +16 -0
@@ -0,0 +1,263 @@
1
+ import { Action, AssetUtils } from '@benjos/cookware';
2
+ import {
3
+ DataTexture,
4
+ EquirectangularRefractionMapping,
5
+ LinearSRGBColorSpace,
6
+ RepeatWrapping,
7
+ Texture,
8
+ TextureLoader,
9
+ type ColorSpace,
10
+ type Mapping,
11
+ type Wrapping,
12
+ } from 'three';
13
+ import { DRACOLoader, Font, FontLoader, GLTFLoader, HDRLoader, type GLTF } from 'three/examples/jsm/Addons.js';
14
+ import type { AssetId } from '../../constants/experiences/AssetId';
15
+ import { AssetType } from '../../types/assetTypes';
16
+
17
+ export interface ThreeAssetToLoad {
18
+ id: AssetId;
19
+ type: AssetType;
20
+ path: string;
21
+ option?: ThreeAssetOption;
22
+ loadedSize: number;
23
+ totalSize: number;
24
+ }
25
+
26
+ export interface ThreeAssetOption {}
27
+
28
+ export interface ThreeTextureOption extends ThreeAssetOption {
29
+ colorSpace?: ColorSpace;
30
+ wrapping?: Wrapping;
31
+ repeatX?: number;
32
+ repeatY?: number;
33
+ centerX?: number;
34
+ centerY?: number;
35
+ }
36
+
37
+ export interface ThreeHDROption extends ThreeAssetOption {
38
+ mapping?: Mapping;
39
+ colorSpace?: ColorSpace;
40
+ }
41
+
42
+ export interface ThreeModelOption extends ThreeAssetOption {}
43
+
44
+ export interface ThreeFontOption extends ThreeAssetOption {}
45
+
46
+ class ThreeAssetsManager {
47
+ private static readonly _DRACO_LOADER_PATH: string = 'loaders/draco/';
48
+ private static readonly _DEFAULT_TEXTURE_OPTION_COLOR_SPACE: ColorSpace = LinearSRGBColorSpace;
49
+ private static readonly _DEFAULT_TEXTURE_OPTION_WRAPPING: Wrapping = RepeatWrapping;
50
+ private static readonly _DEFAULT_TEXTURE_OPTION_REPEAT_X: number = 1;
51
+ private static readonly _DEFAULT_TEXTURE_OPTION_REPEAT_Y: number = 1;
52
+ private static readonly _DEFAULT_TEXTURE_OPTION_CENTER_X: number = 0.5;
53
+ private static readonly _DEFAULT_TEXTURE_OPTION_CENTER_Y: number = 0.5;
54
+ private static readonly _DEFAULT_HDR_MAPPING: Mapping = EquirectangularRefractionMapping;
55
+ private static readonly _DEFAULT_HDR_COLOR_SPACE: ColorSpace = LinearSRGBColorSpace;
56
+ private static readonly _DEFAULT_LOADED_SIZE: number = 0;
57
+ private static readonly _DEFAULT_TOTAL_SIZE: number = -1;
58
+ private static readonly _DEFAULT_TEXTURE_TOTAL_SIZE: number = 1;
59
+
60
+ private readonly _assets: Map<string, Texture | DataTexture | GLTF | Font> = new Map<
61
+ string,
62
+ Texture | GLTF | Font
63
+ >();
64
+ private readonly _toLoadList: ThreeAssetToLoad[] = [];
65
+ private _expectedAssetsCount = 0;
66
+
67
+ private readonly _textureLoader = new TextureLoader();
68
+ private readonly _hdrLoader = new HDRLoader();
69
+ private readonly _gltfLoader = new GLTFLoader();
70
+ private readonly _dracoLoader = new DRACOLoader();
71
+ private readonly _fontLoader = new FontLoader();
72
+
73
+ public readonly onLoad = new Action();
74
+ public readonly onProgress = new Action();
75
+
76
+ public init(): void {
77
+ this._dracoLoader.setDecoderPath(AssetUtils.GetPath(ThreeAssetsManager._DRACO_LOADER_PATH));
78
+ this._gltfLoader.setDRACOLoader(this._dracoLoader);
79
+ }
80
+
81
+ public addTexture(id: AssetId, path: string, textureOption?: ThreeTextureOption): void {
82
+ this._toLoadList.push({
83
+ id,
84
+ type: AssetType.TEXTURE,
85
+ path,
86
+ option: textureOption,
87
+ loadedSize: ThreeAssetsManager._DEFAULT_LOADED_SIZE,
88
+ totalSize: ThreeAssetsManager._DEFAULT_TEXTURE_TOTAL_SIZE,
89
+ });
90
+ this._expectedAssetsCount++;
91
+ }
92
+
93
+ public addHDR(id: AssetId, path: string, hdrOption?: ThreeHDROption): void {
94
+ this._toLoadList.push({
95
+ id,
96
+ type: AssetType.HDR,
97
+ path,
98
+ option: hdrOption,
99
+ loadedSize: ThreeAssetsManager._DEFAULT_LOADED_SIZE,
100
+ totalSize: ThreeAssetsManager._DEFAULT_TOTAL_SIZE,
101
+ });
102
+ this._expectedAssetsCount++;
103
+ }
104
+
105
+ public addModel(id: AssetId, path: string, modelOption?: ThreeModelOption): void {
106
+ this._toLoadList.push({
107
+ id,
108
+ type: AssetType.MODEL,
109
+ path,
110
+ option: modelOption,
111
+ loadedSize: ThreeAssetsManager._DEFAULT_LOADED_SIZE,
112
+ totalSize: ThreeAssetsManager._DEFAULT_TOTAL_SIZE,
113
+ });
114
+ this._expectedAssetsCount++;
115
+ }
116
+
117
+ public addFont(id: AssetId, path: string, fontOption?: ThreeFontOption): void {
118
+ this._toLoadList.push({
119
+ id,
120
+ type: AssetType.FONT,
121
+ path,
122
+ option: fontOption,
123
+ loadedSize: ThreeAssetsManager._DEFAULT_LOADED_SIZE,
124
+ totalSize: ThreeAssetsManager._DEFAULT_TOTAL_SIZE,
125
+ });
126
+ this._expectedAssetsCount++;
127
+ }
128
+
129
+ public beginLoad(): void {
130
+ if (this._toLoadList.length === 0) {
131
+ this.onLoad.execute();
132
+ return;
133
+ }
134
+ for (const asset of this._toLoadList) {
135
+ if (asset.type === AssetType.TEXTURE) this._loadTexture(asset);
136
+ else if (asset.type === AssetType.HDR) this._loadHDR(asset);
137
+ else if (asset.type === AssetType.MODEL) this._loadModel(asset);
138
+ else if (asset.type === AssetType.FONT) this._loadFont(asset);
139
+ }
140
+ }
141
+
142
+ public finishLoad(): void {
143
+ this._toLoadList.length = 0;
144
+ }
145
+
146
+ private _loadTexture(asset: ThreeAssetToLoad): void {
147
+ const option = asset.option as ThreeTextureOption | undefined;
148
+ this._textureLoader.load(
149
+ asset.path,
150
+ (texture) => {
151
+ texture.colorSpace = option?.colorSpace ?? ThreeAssetsManager._DEFAULT_TEXTURE_OPTION_COLOR_SPACE;
152
+ texture.wrapS = texture.wrapT = option?.wrapping ?? ThreeAssetsManager._DEFAULT_TEXTURE_OPTION_WRAPPING;
153
+ texture.repeat.set(
154
+ option?.repeatX ?? ThreeAssetsManager._DEFAULT_TEXTURE_OPTION_REPEAT_X,
155
+ option?.repeatY ?? ThreeAssetsManager._DEFAULT_TEXTURE_OPTION_REPEAT_Y
156
+ );
157
+ texture.center.set(
158
+ option?.centerX ?? ThreeAssetsManager._DEFAULT_TEXTURE_OPTION_CENTER_X,
159
+ option?.centerY ?? ThreeAssetsManager._DEFAULT_TEXTURE_OPTION_CENTER_Y
160
+ );
161
+ asset.loadedSize = asset.totalSize;
162
+ this._onLoad(asset.id, texture);
163
+ },
164
+ (event: ProgressEvent) => this._onProgress(asset, event),
165
+ () => this._onError(AssetType.TEXTURE, asset.id, asset.path)
166
+ );
167
+ }
168
+
169
+ private _loadHDR(asset: ThreeAssetToLoad): void {
170
+ const option = asset.option as ThreeHDROption | undefined;
171
+ this._hdrLoader.load(
172
+ asset.path,
173
+ (dataTexture) => {
174
+ dataTexture.mapping = option?.mapping ?? ThreeAssetsManager._DEFAULT_HDR_MAPPING;
175
+ dataTexture.colorSpace = option?.colorSpace ?? ThreeAssetsManager._DEFAULT_HDR_COLOR_SPACE;
176
+ this._onLoad(asset.id, dataTexture);
177
+ },
178
+ (event: ProgressEvent) => this._onProgress(asset, event),
179
+ () => this._onError(AssetType.HDR, asset.id, asset.path)
180
+ );
181
+ }
182
+
183
+ private _loadModel(asset: ThreeAssetToLoad): void {
184
+ this._gltfLoader.load(
185
+ asset.path,
186
+ (model) => this._onLoad(asset.id, model),
187
+ (event: ProgressEvent) => this._onProgress(asset, event),
188
+ () => this._onError(AssetType.MODEL, asset.id, asset.path)
189
+ );
190
+ }
191
+
192
+ private _loadFont(asset: ThreeAssetToLoad): void {
193
+ this._fontLoader.load(
194
+ asset.path,
195
+ (font) => this._onLoad(asset.id, font),
196
+ (event: ProgressEvent) => this._onProgress(asset, event),
197
+ () => this._onError(AssetType.FONT, asset.id, asset.path)
198
+ );
199
+ }
200
+
201
+ private _onLoad(id: AssetId, asset: Texture | GLTF | Font): void {
202
+ this._assets.set(id, asset);
203
+ this.onLoad.execute();
204
+ }
205
+
206
+ private _onProgress(asset: ThreeAssetToLoad, event: ProgressEvent): void {
207
+ if (asset.totalSize === ThreeAssetsManager._DEFAULT_TOTAL_SIZE) asset.totalSize = event.total;
208
+ asset.loadedSize = event.loaded;
209
+ this.onProgress.execute();
210
+ }
211
+
212
+ private _onError(type: AssetType, id: AssetId, path: string): void {
213
+ throw new Error(`ThreeAssetsManager: Failed to load ${type} with id '${id}' from path '${path}'`);
214
+ }
215
+
216
+ public getTexture(id: AssetId): Texture {
217
+ const asset = this._assets.get(id);
218
+ if (!asset) throw new Error(`Texture with id '${id}' not found!`);
219
+ return asset as Texture;
220
+ }
221
+
222
+ public getHDR(id: AssetId): DataTexture {
223
+ const asset = this._assets.get(id);
224
+ if (!asset) throw new Error(`HDR with id '${id}' not found!`);
225
+ return asset as DataTexture;
226
+ }
227
+
228
+ public getModel(id: AssetId): GLTF {
229
+ const asset = this._assets.get(id);
230
+ if (!asset) throw new Error(`Model with id '${id}' not found!`);
231
+ return asset as GLTF;
232
+ }
233
+
234
+ public getFont(id: AssetId): Font {
235
+ const asset = this._assets.get(id);
236
+ if (!asset) throw new Error(`Font with id '${id}' not found!`);
237
+ return asset as Font;
238
+ }
239
+
240
+ //#region Getters
241
+ //
242
+ public get isLoaded(): boolean {
243
+ return this._assets.size === this._expectedAssetsCount;
244
+ }
245
+ public get totalSize(): number {
246
+ let totalSize = 0;
247
+ for (const asset of this._toLoadList) {
248
+ totalSize += asset.totalSize;
249
+ }
250
+ return totalSize;
251
+ }
252
+ public get loadedSize(): number {
253
+ let loadedSize = 0;
254
+ for (const asset of this._toLoadList) {
255
+ loadedSize += asset.loadedSize;
256
+ }
257
+ return loadedSize;
258
+ }
259
+ //
260
+ //#endregion
261
+ }
262
+
263
+ export default new ThreeAssetsManager();
@@ -0,0 +1,46 @@
1
+ import { Action } from '@benjos/cookware';
2
+ import type ThreeCameraControllerBase from '../../cameras/threes/bases/ThreeCameraControllerBase';
3
+ import type { CameraId } from '../../constants/experiences/CameraId';
4
+
5
+ class ThreeCameraControllerManager {
6
+ declare private _threeCameraControllers: Map<CameraId, ThreeCameraControllerBase>;
7
+ declare private _activeThreeCameraController: ThreeCameraControllerBase;
8
+
9
+ public readonly onActiveThreeCameraControllerChange = new Action();
10
+
11
+ public init(): void {
12
+ this._threeCameraControllers = new Map();
13
+ this._threeCameraControllers.clear();
14
+ }
15
+
16
+ public add(threeCameraController: ThreeCameraControllerBase, isActive = false): void {
17
+ this._threeCameraControllers.set(threeCameraController.cameraId, threeCameraController);
18
+ if (isActive) this.setActiveCamera(threeCameraController.cameraId);
19
+ }
20
+
21
+ public get(cameraId: CameraId): ThreeCameraControllerBase {
22
+ const threeCameraController = this._threeCameraControllers.get(cameraId);
23
+ if (!threeCameraController) {
24
+ throw new Error(`CameraControllerManager: No camera found with id ${cameraId}`);
25
+ }
26
+ return threeCameraController;
27
+ }
28
+
29
+ public setActiveCamera(cameraId: CameraId): void {
30
+ const threeCameraController = this.get(cameraId);
31
+ this._activeThreeCameraController?.disable();
32
+ this._activeThreeCameraController = threeCameraController;
33
+ this._activeThreeCameraController.enable();
34
+ this.onActiveThreeCameraControllerChange.execute();
35
+ }
36
+
37
+ //#region Getters
38
+ //
39
+ public get activeThreeCameraController(): ThreeCameraControllerBase {
40
+ return this._activeThreeCameraController;
41
+ }
42
+ //
43
+ //#endregion
44
+ }
45
+
46
+ export default new ThreeCameraControllerManager();
@@ -0,0 +1,21 @@
1
+ import { DomPointerManager } from '@benjos/cookware';
2
+ import { Object3D, Raycaster, Vector2, type Intersection, type Object3DEventMap } from 'three';
3
+ import MainThreeApp from '../../engines/threes/app/MainThreeApp';
4
+
5
+ class ThreeRaycasterManager {
6
+ private readonly _raycaster = new Raycaster();
7
+ private readonly _pointerPosition = new Vector2();
8
+
9
+ public init(): void {
10
+ //
11
+ }
12
+
13
+ public castFromCameraToPointer(objects: Object3D[], recursive = true): Intersection<Object3D<Object3DEventMap>>[] {
14
+ this._pointerPosition.set(DomPointerManager.ndcX, DomPointerManager.ndcY);
15
+ this._raycaster.setFromCamera(this._pointerPosition, MainThreeApp.cameraController.camera);
16
+ const intersects = this._raycaster.intersectObjects(objects, recursive);
17
+ return intersects;
18
+ }
19
+ }
20
+
21
+ export default new ThreeRaycasterManager();
@@ -0,0 +1,44 @@
1
+ import gsap from 'gsap';
2
+ import { Color, ShaderMaterial } from 'three';
3
+ import LoaderFragmentShader from '../../../shaders/threes/loaders/LoaderFragmentShader.glsl';
4
+ import LoaderVertexShader from '../../../shaders/threes/loaders/LoaderVertexShader.glsl';
5
+
6
+ export default class LoaderMaterial extends ShaderMaterial {
7
+ private static readonly _DEFAULT_UNIFORMS_ALPHA: number = 1;
8
+ private static readonly _DEFAULT_UNIFORMS_COLOR: number = 0x3f79f3;
9
+ private static readonly _GSAP_DURATION_FADE_IN: number = 0.5;
10
+ private static readonly _GSAP_EASE_FADE_IN: string = 'power2.out';
11
+ private static readonly _GSAP_DURATION_FADE_OUT: number = 1.5;
12
+ private static readonly _GSAP_EASE_FADE_OUT: string = 'power2.in';
13
+
14
+ constructor() {
15
+ super({
16
+ transparent: true,
17
+ uniforms: {
18
+ uAlpha: { value: LoaderMaterial._DEFAULT_UNIFORMS_ALPHA },
19
+ uColor: { value: new Color(LoaderMaterial._DEFAULT_UNIFORMS_COLOR) },
20
+ },
21
+ vertexShader: LoaderVertexShader,
22
+ fragmentShader: LoaderFragmentShader,
23
+ });
24
+ }
25
+
26
+ public async show(): Promise<void> {
27
+ gsap.killTweensOf(this.uniforms.uAlpha);
28
+ await gsap.to(this.uniforms.uAlpha, {
29
+ value: 1,
30
+ duration: LoaderMaterial._GSAP_DURATION_FADE_IN,
31
+ ease: LoaderMaterial._GSAP_EASE_FADE_IN,
32
+ });
33
+ }
34
+
35
+ public async hide(): Promise<void> {
36
+ gsap.killTweensOf(this.uniforms.uAlpha);
37
+ this.uniforms.uAlpha.value = 1;
38
+ await gsap.to(this.uniforms.uAlpha, {
39
+ value: 0,
40
+ duration: LoaderMaterial._GSAP_DURATION_FADE_OUT,
41
+ ease: LoaderMaterial._GSAP_EASE_FADE_OUT,
42
+ });
43
+ }
44
+ }
@@ -0,0 +1,18 @@
1
+ import { Camera, NoToneMapping, Scene, SRGBColorSpace, type WebGLRendererParameters } from 'three';
2
+ import WebGLRendererBase from './bases/WebGLRendererBase';
3
+
4
+ export default class LoaderRenderer extends WebGLRendererBase {
5
+ private static readonly _DEFAULT_TONE_MAPPING = NoToneMapping;
6
+ private static readonly _DEFAULT_OUTPUT_COLOR_SPACE = SRGBColorSpace;
7
+ private static readonly _DEFAULT_TONE_MAPPING_EXPOSURE = 1;
8
+ private static readonly _DEFAULT_CLEAR_COLOR = 0x000000;
9
+ private static readonly _DEFAULT_CLEAR_ALPHA = 0;
10
+
11
+ constructor(scene: Scene, camera: Camera, parameters: WebGLRendererParameters = {}) {
12
+ super(scene, camera, parameters);
13
+ this.toneMapping = LoaderRenderer._DEFAULT_TONE_MAPPING;
14
+ this.toneMappingExposure = LoaderRenderer._DEFAULT_TONE_MAPPING_EXPOSURE;
15
+ this.outputColorSpace = LoaderRenderer._DEFAULT_OUTPUT_COLOR_SPACE;
16
+ this.setClearColor(LoaderRenderer._DEFAULT_CLEAR_COLOR, LoaderRenderer._DEFAULT_CLEAR_ALPHA);
17
+ }
18
+ }
@@ -0,0 +1,71 @@
1
+ import {
2
+ ACESFilmicToneMapping,
3
+ AgXToneMapping,
4
+ Camera,
5
+ CineonToneMapping,
6
+ CustomToneMapping,
7
+ LinearSRGBColorSpace,
8
+ LinearToneMapping,
9
+ NeutralToneMapping,
10
+ NoToneMapping,
11
+ PCFSoftShadowMap,
12
+ ReinhardToneMapping,
13
+ Scene,
14
+ SRGBColorSpace,
15
+ type ColorSpace,
16
+ type ToneMapping,
17
+ type WebGLRendererParameters,
18
+ } from 'three';
19
+ import { DebugGuiTitle } from '../../constants/experiences/DebugGuiTitle';
20
+ import DebugManager from '../../managers/DebugManager';
21
+ import WebGLRendererBase from './bases/WebGLRendererBase';
22
+
23
+ export default class Renderer extends WebGLRendererBase {
24
+ private static readonly _DEFAULT_TONE_MAPPING = CineonToneMapping;
25
+ private static readonly _DEFAULT_OUTPUT_COLOR_SPACE = SRGBColorSpace;
26
+ private static readonly _DEFAULT_SHADOW_MAP_TYPE = PCFSoftShadowMap;
27
+ private static readonly _DEFAULT_TONE_MAPPING_EXPOSURE = 1;
28
+ private static readonly _DEFAULT_CLEAR_COLOR = 0xfafafa;
29
+ private static readonly _DEFAULT_CLEAR_ALPHA = 0;
30
+
31
+ constructor(scene: Scene, camera: Camera, parameters: WebGLRendererParameters = {}) {
32
+ super(scene, camera, parameters);
33
+ this.toneMapping = Renderer._DEFAULT_TONE_MAPPING;
34
+ this.toneMappingExposure = Renderer._DEFAULT_TONE_MAPPING_EXPOSURE;
35
+ this.outputColorSpace = Renderer._DEFAULT_OUTPUT_COLOR_SPACE;
36
+ this.shadowMap.enabled = true;
37
+ this.shadowMap.type = Renderer._DEFAULT_SHADOW_MAP_TYPE;
38
+ this.setClearColor(Renderer._DEFAULT_CLEAR_COLOR, Renderer._DEFAULT_CLEAR_ALPHA);
39
+
40
+ if (DebugManager.isActive) {
41
+ const rendererFolder = DebugManager.getGuiFolder(DebugGuiTitle.THREE_RENDERER)
42
+ rendererFolder
43
+ .add(this, 'toneMapping', {
44
+ NoToneMapping,
45
+ LinearToneMapping,
46
+ ReinhardToneMapping,
47
+ CineonToneMapping,
48
+ ACESFilmicToneMapping,
49
+ CustomToneMapping,
50
+ AgXToneMapping,
51
+ NeutralToneMapping,
52
+ })
53
+ .onChange((value: ToneMapping) => {
54
+ this.toneMapping = value;
55
+ });
56
+ rendererFolder.add(this, 'toneMappingExposure', 0, 10, 0.001);
57
+ rendererFolder
58
+ .add(this, 'outputColorSpace', { SRGBColorSpace, LinearSRGBColorSpace })
59
+ .onChange((value: ColorSpace) => {
60
+ this.outputColorSpace = value;
61
+ });
62
+ }
63
+ }
64
+
65
+ public override update(dt: number): void {
66
+ const isDebug = DebugManager.isActive;
67
+ if (isDebug) DebugManager.beginThreePerf();
68
+ super.update(dt);
69
+ if (isDebug) DebugManager.endThreePerf();
70
+ }
71
+ }
@@ -0,0 +1,29 @@
1
+ import { DomResizeManager } from '@benjos/cookware';
2
+ import { Camera, Scene, WebGLRenderer, type WebGLRendererParameters } from 'three';
3
+
4
+ export default abstract class WebGLRendererBase extends WebGLRenderer {
5
+ private readonly _scene: Scene;
6
+ private _camera: Camera;
7
+
8
+ constructor(scene: Scene, camera: Camera, parameters: WebGLRendererParameters = {}) {
9
+ super(parameters);
10
+
11
+ this._scene = scene;
12
+ this._camera = camera;
13
+
14
+ this.resize();
15
+ }
16
+
17
+ public setCamera(camera: Camera): void {
18
+ this._camera = camera;
19
+ }
20
+
21
+ public resize(): void {
22
+ this.setSize(DomResizeManager.width, DomResizeManager.height);
23
+ this.setPixelRatio(DomResizeManager.pixelRatio);
24
+ }
25
+
26
+ public update(_dt: number): void {
27
+ this.render(this._scene, this._camera);
28
+ }
29
+ }
@@ -0,0 +1,8 @@
1
+ uniform vec3 uColor;
2
+ uniform float uAlpha;
3
+
4
+ void main() {
5
+ gl_FragColor = vec4(uColor, uAlpha);
6
+ #include <tonemapping_fragment>
7
+ #include <colorspace_fragment>
8
+ }
@@ -0,0 +1,3 @@
1
+ void main() {
2
+ gl_Position = vec4(position, 1.0);
3
+ }
@@ -0,0 +1,5 @@
1
+ @forward 'variables';
2
+ @forward 'mixins';
3
+ @forward 'functions';
4
+
5
+ // @use 'path/to/_import.scss' as *;
@@ -0,0 +1,3 @@
1
+ @function getAssetUrl($url) {
2
+ @return url('/assets/#{$url}');
3
+ }
@@ -0,0 +1,7 @@
1
+ $white: #fafafa;
2
+ $whiteAntiFlashs: #ededed;
3
+ $darkGrey: #666666;
4
+ $black: #050505;
5
+ $jet: #333333;
6
+ $silverGrey: #aaaaaa;
7
+ $blue: #3f79f3;
@@ -0,0 +1,10 @@
1
+ @use '../abstracts/import.scss' as *;
2
+
3
+ // @font-face {
4
+ // font-family: 'din-condensed';
5
+ // src: getAssetUrl('fonts/din_bold_c.woff') format('woff'),
6
+ // getAssetUrl('fonts/din_bold_c.woff2') format('woff2');
7
+ // font-weight: bold;
8
+ // font-style: normal;
9
+ // font-display: swap;
10
+ // }
@@ -0,0 +1,59 @@
1
+ @use '../abstracts/import.scss' as *;
2
+
3
+ $viewTransition: 0.5s;
4
+
5
+ * {
6
+ box-sizing: border-box;
7
+ user-select: none;
8
+ overscroll-behavior: none;
9
+ }
10
+
11
+ body {
12
+ position: relative;
13
+ width: 100dvw;
14
+ height: 100dvh;
15
+ margin: 0;
16
+ padding: 0;
17
+ overflow: hidden;
18
+
19
+ > #app,
20
+ > #root {
21
+ position: relative;
22
+ width: 100%;
23
+ height: 100%;
24
+
25
+ > #loader {
26
+ position: absolute;
27
+ top: 0;
28
+ left: 0;
29
+ width: 100%;
30
+ height: 100%;
31
+ pointer-events: none;
32
+ }
33
+
34
+ canvas,
35
+ #webgl {
36
+ width: 100%;
37
+ height: 100%;
38
+ }
39
+
40
+ .html-view {
41
+ position: absolute;
42
+ top: 0;
43
+ left: 0;
44
+ width: 100%;
45
+ height: 100%;
46
+ opacity: 0;
47
+ transition: opacity $viewTransition ease;
48
+
49
+ &.show {
50
+ opacity: 1;
51
+ }
52
+ }
53
+ }
54
+
55
+ .lil-gui,
56
+ #three-perf-ui {
57
+ z-index: 999999;
58
+ }
59
+ }
@@ -0,0 +1 @@
1
+ @use '../abstracts/import.scss' as *;
@@ -0,0 +1,7 @@
1
+ @use './abstracts/import.scss' as *;
2
+
3
+ @use './commons/main.scss';
4
+ @use './commons/texts.scss';
5
+ @use './commons/fonts.scss';
6
+
7
+ @use './views/loader.scss';
@@ -0,0 +1,70 @@
1
+ @use '../abstracts/import.scss' as *;
2
+
3
+ $outroFadeOutDuration: 1.5s;
4
+
5
+ body {
6
+
7
+ >#app,
8
+ >#root {
9
+ >#loader {
10
+ .html-view {
11
+ transition: opacity $outroFadeOutDuration ease;
12
+ }
13
+ }
14
+ }
15
+ }
16
+
17
+ #loader {
18
+ z-index: 999999;
19
+
20
+ .loading-screen {
21
+ position: absolute;
22
+ top: 0;
23
+ left: 0;
24
+ width: 100dvw;
25
+ height: 100dvh;
26
+
27
+ .loading-progress {
28
+ z-index: 2;
29
+ position: absolute;
30
+ top: 50%;
31
+ left: 50%;
32
+ transform: translate(-50%, -50%);
33
+ padding-bottom: 2.5rem;
34
+ opacity: 1;
35
+ font-size: 2rem;
36
+ color: $white;
37
+ display: flex;
38
+ align-items: center;
39
+ gap: 0.25rem;
40
+ }
41
+
42
+ .loading-bar {
43
+ z-index: 1;
44
+ width: 100dvw;
45
+ height: 0.25rem;
46
+ position: absolute;
47
+ top: 50%;
48
+ left: 0;
49
+ opacity: 1;
50
+ background-color: $white;
51
+ transform-origin: top left;
52
+ transform: translateY(-50%) scaleX(0);
53
+
54
+ &.ended {
55
+ transform-origin: top right;
56
+ animation: outBar $outroFadeOutDuration cubic-bezier(0.77, 0, 0.175, 1) forwards;
57
+
58
+ @keyframes outBar {
59
+ 0% {
60
+ transform: translateY(-50%) scaleX(1);
61
+ }
62
+
63
+ 100% {
64
+ transform: translateY(-50%) scaleX(0);
65
+ }
66
+ }
67
+ }
68
+ }
69
+ }
70
+ }