mirror of
https://github.com/remvze/moodist.git
synced 2025-10-25 07:48:56 -04:00
refactor: seperate motion variants
This commit is contained in:
parent
b849b3aecd
commit
7fce9e1dff
@ -16,6 +16,7 @@ import { AnimatePresence, motion } from 'framer-motion';
|
||||
|
||||
import { useSoundStore } from '@/store';
|
||||
import { cn } from '@/helpers/styles';
|
||||
import { fade, mix, slideX } from '@/lib/motion';
|
||||
|
||||
import styles from './unselect.module.css';
|
||||
|
||||
@ -47,14 +48,17 @@ export function UnselectButton() {
|
||||
const hasHistory = useSoundStore(state => !!state.history);
|
||||
const unselectAll = useSoundStore(state => state.unselectAll);
|
||||
|
||||
const variants = mix(fade(), slideX(20));
|
||||
|
||||
return (
|
||||
<>
|
||||
<AnimatePresence mode="popLayout">
|
||||
{(!noSelected || hasHistory) && (
|
||||
<motion.div
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
exit={{ opacity: 0, x: 20 }}
|
||||
initial={{ opacity: 0, x: 20 }}
|
||||
animate="show"
|
||||
exit="hidden"
|
||||
initial="hidden"
|
||||
variants={variants}
|
||||
>
|
||||
<button
|
||||
disabled={noSelected && !hasHistory}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
import { Sounds } from '@/components/sounds';
|
||||
import { fade } from '@/lib/motion';
|
||||
|
||||
import styles from './category.module.css';
|
||||
|
||||
@ -24,12 +25,15 @@ export function Category({
|
||||
sounds,
|
||||
title,
|
||||
}: CategoryProps) {
|
||||
const variants = fade();
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
animate={{ opacity: 1 }}
|
||||
animate="show"
|
||||
className={styles.category}
|
||||
initial={{ opacity: 0 }}
|
||||
initial="hidden"
|
||||
layout="position"
|
||||
variants={variants}
|
||||
>
|
||||
<div className={styles.iconContainer}>
|
||||
<div className={styles.tail} />
|
||||
|
||||
@ -3,6 +3,7 @@ import { AnimatePresence, motion } from 'framer-motion';
|
||||
|
||||
import { useFavoriteStore } from '@/store/favorite';
|
||||
import { cn } from '@/helpers/styles';
|
||||
import { fade } from '@/lib/motion';
|
||||
|
||||
import styles from './like.module.css';
|
||||
|
||||
@ -14,6 +15,8 @@ export function Like({ id }: LikeProps) {
|
||||
const isFavorite = useFavoriteStore(state => state.favorites.includes(id));
|
||||
const toggleFavorite = useFavoriteStore(state => state.toggleFavorite);
|
||||
|
||||
const variants = fade();
|
||||
|
||||
return (
|
||||
<AnimatePresence initial={false} mode="wait">
|
||||
<button
|
||||
@ -25,10 +28,11 @@ export function Like({ id }: LikeProps) {
|
||||
}}
|
||||
>
|
||||
<motion.span
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
initial={{ opacity: 0 }}
|
||||
animate="show"
|
||||
exit="hidden"
|
||||
initial="hidden"
|
||||
key={isFavorite ? `${id}-is-favorite` : `${id}-not-favorite`}
|
||||
variants={variants}
|
||||
>
|
||||
{isFavorite ? <BiSolidHeart /> : <BiHeart />}
|
||||
</motion.span>
|
||||
|
||||
@ -4,6 +4,7 @@ import { AnimatePresence, motion } from 'framer-motion';
|
||||
import { Sound } from '@/components/sound';
|
||||
import { useLocalStorage } from '@/hooks/use-local-storage';
|
||||
import { cn } from '@/helpers/styles';
|
||||
import { fade, scale, mix } from '@/lib/motion';
|
||||
|
||||
import styles from './sounds.module.css';
|
||||
|
||||
@ -45,6 +46,8 @@ export function Sounds({ functional, id, sounds }: SoundsProps) {
|
||||
}));
|
||||
}, []);
|
||||
|
||||
const variants = mix(fade(), scale(0.85));
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={styles.sounds}>
|
||||
@ -68,11 +71,12 @@ export function Sounds({ functional, id, sounds }: SoundsProps) {
|
||||
{sounds.length > 6 && (
|
||||
<AnimatePresence initial={false} mode="wait">
|
||||
<motion.button
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
exit={{ opacity: 0, scale: 0.85 }}
|
||||
initial={{ opacity: 0, scale: 0.85 }}
|
||||
animate="show"
|
||||
exit="hidden"
|
||||
initial="hidden"
|
||||
key={showAll ? `${id}-show-less` : `${id}-show-more`}
|
||||
transition={{ duration: 0.2 }}
|
||||
variants={variants}
|
||||
className={cn(
|
||||
styles.button,
|
||||
hasHiddenSelection && !showAll && styles.active,
|
||||
|
||||
48
src/lib/motion.ts
Normal file
48
src/lib/motion.ts
Normal file
@ -0,0 +1,48 @@
|
||||
type Motion = {
|
||||
hidden: {
|
||||
[key: string]: number | string;
|
||||
};
|
||||
show: {
|
||||
[key: string]: number | string;
|
||||
};
|
||||
};
|
||||
|
||||
export function fade(): Motion {
|
||||
return {
|
||||
hidden: { opacity: 0 },
|
||||
show: { opacity: 1 },
|
||||
};
|
||||
}
|
||||
|
||||
export function scale(from = 0.85, to = 1): Motion {
|
||||
return {
|
||||
hidden: { scale: from },
|
||||
show: { scale: to },
|
||||
};
|
||||
}
|
||||
|
||||
export function slideX(from = -10, to = 0): Motion {
|
||||
return {
|
||||
hidden: { x: from },
|
||||
show: { x: to },
|
||||
};
|
||||
}
|
||||
|
||||
export function slideY(from = -10, to = 0): Motion {
|
||||
return {
|
||||
hidden: { Y: from },
|
||||
show: { Y: to },
|
||||
};
|
||||
}
|
||||
|
||||
export function mix(...motions: Array<Motion>): Motion {
|
||||
let hidden = {};
|
||||
let show = {};
|
||||
|
||||
motions.forEach(motion => {
|
||||
if (motion.hidden) hidden = { ...hidden, ...motion.hidden };
|
||||
if (motion.show) show = { ...show, ...motion.show };
|
||||
});
|
||||
|
||||
return { hidden, show };
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user