diff --git a/src/animations/index.ts b/src/animations/index.ts index 09b3a77..0a28195 100644 --- a/src/animations/index.ts +++ b/src/animations/index.ts @@ -239,6 +239,42 @@ const animateNavbarLeave = ( resetOpacity(contactSelector); }; +// ! Loading animation +const animateLoadingPath = ( + path: Ref, + targetPath: string, + isSamsung: boolean, +) => { + const tl = gsap.timeline({}); + tl.to('#loading-screen', { + delay: 3, + bottom: '100%', + duration: 1, + ease: 'power2.inOut', + onStart: () => { + setTimeout(() => { + animateHeroNav(); + samsungErrorModal(isSamsung); + document.body.classList.remove('stop-scrolling'); + window.scrollTo(0, 0); + }, 120); + }, + }); + + tl.to( + path.value, + { + duration: 1, + attr: { d: targetPath }, + ease: 'power2.inOut', + onComplete: () => { + gsap.set('#loading-screen', { display: 'none' }); + }, + }, + '<20%', + ); +}; + const animateLoadingTextContainer = () => { gsap.fromTo( '#text', @@ -344,14 +380,14 @@ const animateHeroNav = () => { // A little bit about me animation const animateAboutMeSectionLeave = (id: string) => { gsap.to(id, { - yPercent: -5, + yPercent: -10, scale: 0.95, - // ease: 'power1', + ease: 'power1', scrollTrigger: { trigger: id, start: '75% bottom', // end: 'bottom top', - scrub: 0.1, + scrub: 1, }, }); }; @@ -364,7 +400,7 @@ export { resetMagneto, animateNavbarEnter, animateNavbarLeave, - samsungErrorModal, + animateLoadingPath, animateLoadingText, animateLoadingTextContainer, animateHeroNav, diff --git a/src/components/design/LoadingScreen.vue b/src/components/design/LoadingScreen.vue index 15a204f..361468b 100644 --- a/src/components/design/LoadingScreen.vue +++ b/src/components/design/LoadingScreen.vue @@ -56,12 +56,10 @@ import { useWindowSize } from '@vueuse/core'; import { computed, onMounted, Ref, ref, watch } from 'vue'; import { - animateHeroNav, + animateLoadingPath, animateLoadingText, animateLoadingTextContainer, - samsungErrorModal, } from '@/animations'; - import gsap from 'gsap'; const emit = defineEmits(['isLoading']); @@ -86,7 +84,6 @@ // multiplier *= -1; return height.value + height.value * multiplier; }); - const initialPath = ref( `M0 0 L${width.value} 0 L${width.value} ${height.value} Q${width.value / 2} ${curveHeight.value} 0 ${height.value} L0 0`, ); @@ -96,53 +93,20 @@ const isSamsungBrowser = /samsung/i.test(navigator.userAgent); - let tl = gsap.timeline({}); - const animateLoadingPath = ( - path: Ref, - isSamsung: boolean, - ) => { - tl.to('#loading-screen', { - delay: 3, - bottom: '100%', - duration: 1, - ease: 'power2.inOut', - onStart: () => { - setTimeout(() => { - animateHeroNav(); - samsungErrorModal(isSamsung); - document.body.classList.remove('stop-scrolling'); - window.scrollTo(0, 0); - }, 120); - }, - }); - - tl.to( - path.value, - { - duration: 1, - attr: { d: targetPath.value }, - ease: 'power2.inOut', - onComplete: () => { - gsap.set('#loading-screen', { display: 'none' }); - }, - }, - '<20%', - ); - }; onMounted(() => { index.value++; pathData.value = initialPath.value; animateLoadingTextContainer(); animateLoadingText('span.loading-text'); - animateLoadingPath(path as Ref, isSamsungBrowser); - }); - - watch(targetPath, () => { - tl.clear(); - animateLoadingPath(path as Ref, isSamsungBrowser); + animateLoadingPath( + path as Ref, + targetPath.value, + isSamsungBrowser, + ); }); + // TODO: remove it watch( [width, height], () => { @@ -159,4 +123,4 @@ watch(isLoading, (newVal) => { emit('isLoading', newVal); }); - + \ No newline at end of file diff --git a/src/components/design/index.ts b/src/components/design/index.ts index 468fafc..b51e748 100644 --- a/src/components/design/index.ts +++ b/src/components/design/index.ts @@ -1,14 +1,13 @@ -import { defineAsyncComponent } from 'vue'; - import LoadingScreen from './LoadingScreen.vue'; -const Circles = defineAsyncComponent(() => import('./Circles.vue')); -const MyName = defineAsyncComponent(() => import('./MyName.vue')); -const Star = defineAsyncComponent(() => import('./Star.vue')); -const SamsungError = defineAsyncComponent(() => import('./SamsungError.vue')); -const Marquee = defineAsyncComponent(() => import('./Marquee.vue')); -const Slider = defineAsyncComponent(() => import('./Slider.vue')); -const Footer = defineAsyncComponent(() => import('./Footer.vue')); +import Circles from './Circles.vue'; +import MyName from './MyName.vue'; +import Star from './Star.vue'; +import SamsungError from './SamsungError.vue'; +import Marquee from './Marquee.vue'; +import Slider from './Slider.vue'; +import Footer from './Footer.vue'; + import Cursor from './Cursor.vue'; export {