mobile animation WIP

This commit is contained in:
tglide
2023-09-08 13:22:02 +01:00
parent c91605c35f
commit d5ef1acdfd

View File

@@ -3,8 +3,8 @@
import { import {
animate, animate,
spring, spring,
type AnimationControls,
type AnimationListOptions, type AnimationListOptions,
type MotionKeyframesDefinition,
type SpringOptions type SpringOptions
} from 'motion'; } from 'motion';
@@ -14,75 +14,101 @@
y: { easing: spring(springOptions) } y: { easing: spring(springOptions) }
}; };
let animated = [] as string[]; let animated = [] as AnimationControls[];
const getAnimateFn = (id: string, keyframes: MotionKeyframesDefinition) => { type Animation = {
return () => { mobile?: () => AnimationControls;
if (animated.includes(id)) return; desktop: () => AnimationControls;
animated.push(id);
return animate(id, keyframes, animationOptions);
};
}; };
const animations = [ const animations: Animation[] = [
getAnimateFn('#oss-discord', { x: [-100, 20], y: [0, '-80vh'], rotate: 15 }), {
getAnimateFn('#oss-github', { rotate: 6.26, x: [0, -100], y: [0, '-55vh'] }), mobile() {
getAnimateFn('#oss-twitter', { return animate(
rotate: -15, '#oss-discord',
x: [0, 100], { x: [-100, 20], y: [0, '-80vh'], rotate: 15 },
y: [0, '-70vh'] animationOptions
}), );
getAnimateFn('#oss-youtube', { },
rotate: -3.77, desktop() {
x: [0, -100], return animate(
y: [0, '-60vh'] '#oss-discord',
}), { x: [-100, 20], y: [0, '-80vh'], rotate: 15 },
getAnimateFn('#oss-commits', { animationOptions
rotate: -10.2, );
x: [0, 100], }
y: [0, '-80vh'] },
}) {
desktop: function () {
return animate(
'#oss-github',
{ rotate: 6.26, x: [0, -100], y: [0, '-55vh'] },
animationOptions
);
}
},
{
desktop: function () {
return animate(
'#oss-twitter',
{ rotate: -15, x: [0, 100], y: [0, '-70vh'] },
animationOptions
);
}
},
{
desktop: function () {
return animate(
'#oss-youtube',
{ rotate: -3.77, x: [0, -100], y: [0, '-60vh'] },
animationOptions
);
}
},
{
desktop: function () {
return animate(
'#oss-commits',
{ rotate: -10.2, x: [0, 100], y: [0, '-80vh'] },
animationOptions
);
}
}
]; ];
const mobileAnimations = [ const executeAnimation = (index: number) => {
getAnimateFn('#oss-discord', { x: ['-100%', 0], rotate: 15 }), if (animated[index]) return;
getAnimateFn('#oss-github', { rotate: 6.26, x: [0, -100], y: [0, '-55vh'] }), const { mobile, desktop } = animations[index];
getAnimateFn('#oss-twitter', { if (isMobile()) {
rotate: -15, animated[index] = mobile ? mobile() : desktop();
x: [0, 100], } else {
y: [0, '-70vh'] animated[index] = desktop();
}), }
getAnimateFn('#oss-youtube', { };
rotate: -3.77,
x: [0, -100],
y: [0, '-60vh']
}),
getAnimateFn('#oss-commits', {
rotate: -10.2,
x: [0, 100],
y: [0, '-80vh']
})
];
const startPercentage = 0.05; const startPercentage = 0.05;
const endPercentage = 0.8; const endPercentage = 0.8;
let wrapper: HTMLElement; let wrapper: HTMLElement;
const isMobile = () => {
return window.innerWidth < 1024;
};
</script> </script>
<svelte:window <svelte:window
on:resize={() => {
animated.forEach((animation) => animation.cancel());
animated = [];
}}
on:scroll={() => { on:scroll={() => {
const { top, height } = wrapper.getBoundingClientRect(); const { top, height } = wrapper.getBoundingClientRect();
const { innerHeight, innerWidth } = window; const { innerHeight } = window;
const scrollHeight = height - innerHeight; const scrollHeight = height - innerHeight;
const scrollPercentage = (-1 * top) / scrollHeight; const scrollPercentage = (-1 * top) / scrollHeight;
const isMobile = innerWidth < 1024;
for (let i = 0; i < animations.length; i++) { for (let i = 0; i < animations.length; i++) {
const animation = animations[i];
const animStartPercentage = toScale( const animStartPercentage = toScale(
i, i,
{ {
@@ -96,7 +122,7 @@
); );
if (scrollPercentage >= animStartPercentage) { if (scrollPercentage >= animStartPercentage) {
animation(); executeAnimation(i);
} }
} }
}} }}
@@ -185,27 +211,35 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
gap: 1.25rem; gap: 1.25rem;
padding-inline: 1.25rem;
width: 100%; width: 100%;
height: 100vh; height: 100vh;
text-align: center; text-align: center;
h3 {
max-width: 61.375rem;
}
p { p {
max-width: 48.875rem; max-width: 48.875rem;
} }
.cards-wrapper { .cards-wrapper {
position: absolute; position: relative;
height: 100vh; height: 22.5rem;
width: clamp(1024px, 90vw, 1440px); }
top: 0;
left: 50%; @media (min-width: 1024px) {
transform: translateX(-50%); h3 {
max-width: 61.375rem;
}
.cards-wrapper {
position: absolute;
height: 100vh;
width: clamp(1024px, 90vw, 1440px);
top: 0;
left: 50%;
transform: translateX(-50%);
}
} }
} }
@@ -229,32 +263,49 @@
#oss-discord { #oss-discord {
position: absolute; position: absolute;
bottom: -400px; left: 50%;
left: 1%; transform: translateX(-200vw);
transform: rotate(15deg);
@media (min-width: 1024px) {
bottom: -400px;
left: 1%;
transform: rotate(15deg);
}
} }
#oss-github { #oss-github {
position: absolute; position: absolute;
bottom: -400px; opacity: 0;
left: 19%; @media (min-width: 1024px) {
bottom: -400px;
left: 19%;
}
} }
#oss-twitter { #oss-twitter {
position: absolute; position: absolute;
bottom: -400px; opacity: 0;
left: clamp(20%, 22vw, 29%); @media (min-width: 1024px) {
bottom: -400px;
left: clamp(20%, 22vw, 29%);
}
} }
#oss-youtube { #oss-youtube {
position: absolute; position: absolute;
bottom: -400px; opacity: 0;
left: clamp(64%, calc(1024px - 10vw), 70%); @media (min-width: 1024px) {
bottom: -400px;
left: clamp(64%, calc(1024px - 10vw), 70%);
}
} }
#oss-commits { #oss-commits {
position: absolute; position: absolute;
bottom: -400px; opacity: 0;
right: 10%; @media (min-width: 1024px) {
bottom: -400px;
right: 10%;
}
} }
</style> </style>