From b6f3f333caa31234a10c89ad0b5edb61410c2a47 Mon Sep 17 00:00:00 2001 From: alvarosabu Date: Wed, 31 May 2023 11:38:14 +0200 Subject: [PATCH] feat: useProgress composable --- playground/.eslintrc-auto-import.json | 5 +- playground/auto-imports.d.ts | 1 + playground/components.d.ts | 2 + playground/src/components/EnvironmentDemo.vue | 50 +++++++++++++++++++ playground/src/pages/index.vue | 2 +- src/core/abstractions/index.ts | 14 +++++- src/core/abstractions/useProgress.ts | 43 ++++++++++++++++ 7 files changed, 113 insertions(+), 4 deletions(-) create mode 100644 playground/src/components/EnvironmentDemo.vue create mode 100644 src/core/abstractions/useProgress.ts diff --git a/playground/.eslintrc-auto-import.json b/playground/.eslintrc-auto-import.json index 0f676239..e32b30f0 100644 --- a/playground/.eslintrc-auto-import.json +++ b/playground/.eslintrc-auto-import.json @@ -57,6 +57,7 @@ "watch": true, "watchEffect": true, "watchPostEffect": true, - "watchSyncEffect": true + "watchSyncEffect": true, + "toValue": true } -} \ No newline at end of file +} diff --git a/playground/auto-imports.d.ts b/playground/auto-imports.d.ts index e8959eba..4259e89c 100644 --- a/playground/auto-imports.d.ts +++ b/playground/auto-imports.d.ts @@ -45,6 +45,7 @@ declare global { const toRaw: typeof import('vue')['toRaw'] const toRef: typeof import('vue')['toRef'] const toRefs: typeof import('vue')['toRefs'] + const toValue: typeof import('vue')['toValue'] const triggerRef: typeof import('vue')['triggerRef'] const unref: typeof import('vue')['unref'] const useAttrs: typeof import('vue')['useAttrs'] diff --git a/playground/components.d.ts b/playground/components.d.ts index 22bdc176..285eb953 100644 --- a/playground/components.d.ts +++ b/playground/components.d.ts @@ -10,6 +10,8 @@ export {} declare module '@vue/runtime-core' { export interface GlobalComponents { ContactShadowsDemo: typeof import('./src/components/ContactShadowsDemo.vue')['default'] + Environment: typeof import('./src/components/Environment.vue')['default'] + EnvironmentDemo: typeof import('./src/components/EnvironmentDemo.vue')['default'] Gltf: typeof import('./src/components/gltf/index.vue')['default'] LeviosoDemo: typeof import('./src/components/LeviosoDemo.vue')['default'] MapControlsDemo: typeof import('./src/components/MapControlsDemo.vue')['default'] diff --git a/playground/src/components/EnvironmentDemo.vue b/playground/src/components/EnvironmentDemo.vue new file mode 100644 index 00000000..e774cea0 --- /dev/null +++ b/playground/src/components/EnvironmentDemo.vue @@ -0,0 +1,50 @@ + + + diff --git a/playground/src/pages/index.vue b/playground/src/pages/index.vue index 906614ae..ae57464e 100644 --- a/playground/src/pages/index.vue +++ b/playground/src/pages/index.vue @@ -1,6 +1,6 @@ diff --git a/src/core/abstractions/index.ts b/src/core/abstractions/index.ts index 703246bd..4eb80738 100644 --- a/src/core/abstractions/index.ts +++ b/src/core/abstractions/index.ts @@ -7,7 +7,19 @@ import Precipitation from './Precipitation.vue' import Smoke from './Smoke.vue' import Levioso from './Levioso.vue' import ContactShadows from './ContactShadows.vue' +import { useProgress } from './useProgress' export * from './useParallax' export * from './useEnvironment' -export { Text3D, useAnimations, Environment, MouseParallax, Stars, Smoke, Levioso, ContactShadows, Precipitation } +export { + Text3D, + useAnimations, + Environment, + MouseParallax, + Stars, + Smoke, + Levioso, + ContactShadows, + Precipitation, + useProgress, +} diff --git a/src/core/abstractions/useProgress.ts b/src/core/abstractions/useProgress.ts new file mode 100644 index 00000000..0b69d614 --- /dev/null +++ b/src/core/abstractions/useProgress.ts @@ -0,0 +1,43 @@ +import { DefaultLoadingManager } from 'three' +import { Ref, ref } from 'vue' + +let saveLastTotalLoaded = 0 + +export function useProgress(): Promise<{ + hasFinishLoading: Ref + progress: Ref + items: Ref +}> { + const hasFinishLoading = ref(false) + const progress = ref(0) + const items: Ref = ref([]) + + return new Promise(resolve => { + DefaultLoadingManager.onStart = () => { + hasFinishLoading.value = false + } + + DefaultLoadingManager.onLoad = () => { + hasFinishLoading.value = true + } + + DefaultLoadingManager.onProgress = (item, loaded, total) => { + if (loaded === total) { + saveLastTotalLoaded = total + hasFinishLoading.value = true + items.value.push(item) + } + progress.value = Math.round(((loaded - saveLastTotalLoaded) / (total - saveLastTotalLoaded)) * 100 || 100, 2) + } + + DefaultLoadingManager.onError = () => { + hasFinishLoading.value = true + } + + resolve({ + items, + hasFinishLoading, + progress, + }) + }) +}