From d78bde8cc35075752c5a1b7ef8f846ddbd2d3055 Mon Sep 17 00:00:00 2001 From: Francisco Pessano Date: Fri, 18 Oct 2024 01:47:55 -0300 Subject: [PATCH] Scroll animations --- package.json | 1 + pnpm-lock.yaml | 42 ++++++++++++++++++----- src/app/_components/artist-showcase.tsx | 5 +-- src/app/_components/scroll-fade-in.tsx | 44 +++++++++++++++++++++++++ src/app/_components/scroll-slider.tsx | 43 ++++++++++++++++++++++++ src/app/_components/showcase.tsx | 18 ++++++---- 6 files changed, 136 insertions(+), 17 deletions(-) create mode 100644 src/app/_components/scroll-fade-in.tsx create mode 100644 src/app/_components/scroll-slider.tsx diff --git a/package.json b/package.json index e472b33..475ce0c 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "@trpc/react-query": "^11.0.0-rc.446", "@trpc/server": "^11.0.0-rc.446", "cloudinary": "^2.5.1", + "framer-motion": "^11.11.9", "geist": "^1.3.0", "ldrs": "^1.0.2", "next": "^14.2.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b30ebc3..9290956 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,6 +29,9 @@ importers: cloudinary: specifier: ^2.5.1 version: 2.5.1 + framer-motion: + specifier: ^11.11.9 + version: 11.11.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) geist: specifier: ^1.3.0 version: 1.3.1(next@14.2.15(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) @@ -880,6 +883,20 @@ packages: resolution: {integrity: sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==} deprecated: 'Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau' + framer-motion@11.11.9: + resolution: {integrity: sha512-XpdZseuCrZehdHGuW22zZt3SF5g6AHJHJi7JwQIigOznW4Jg1n0oGPMJQheMaKLC+0rp5gxUKMRYI6ytd3q4RQ==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 + react-dom: ^18.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -2572,8 +2589,8 @@ snapshots: '@typescript-eslint/parser': 8.8.1(eslint@8.57.1)(typescript@5.6.3) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.10.0(eslint@8.57.1) eslint-plugin-react: 7.37.1(eslint@8.57.1) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) @@ -2592,37 +2609,37 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1): + eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.3.7 enhanced-resolve: 5.17.1 eslint: 8.57.1 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) fast-glob: 3.3.2 get-tsconfig: 4.8.1 is-bun-module: 1.2.1 is-glob: 4.0.3 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) transitivePeerDependencies: - '@typescript-eslint/parser' - eslint-import-resolver-node - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.8.1(eslint@8.57.1)(typescript@5.6.3) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -2633,7 +2650,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -2823,6 +2840,13 @@ snapshots: formidable@1.2.6: {} + framer-motion@11.11.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + tslib: 2.7.0 + optionalDependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + fs.realpath@1.0.0: {} fsevents@2.3.3: diff --git a/src/app/_components/artist-showcase.tsx b/src/app/_components/artist-showcase.tsx index 789d698..8c8a530 100644 --- a/src/app/_components/artist-showcase.tsx +++ b/src/app/_components/artist-showcase.tsx @@ -6,6 +6,7 @@ import Tilt from "react-parallax-tilt"; import { quantum } from "ldrs"; import { ring2 } from "ldrs"; import ErrorComponent from "./error"; +import ScrollFadeIn from "./scroll-fade-in"; ring2.register(); quantum.register(); @@ -99,7 +100,7 @@ export default function ArtistShowcase({ return ( -
setShowSpookyImage(!showSpookyImage)} > @@ -180,7 +181,7 @@ export default function ArtistShowcase({ > {name}

-
+
); } diff --git a/src/app/_components/scroll-fade-in.tsx b/src/app/_components/scroll-fade-in.tsx new file mode 100644 index 0000000..76c2405 --- /dev/null +++ b/src/app/_components/scroll-fade-in.tsx @@ -0,0 +1,44 @@ +import { motion, useAnimation, useInView } from "framer-motion"; +import { useEffect, useRef } from "react"; + +export const ScrollFadeIn = ({ + children, + className = "", + onClick, +}: { + children: React.ReactNode; + className?: string; + onClick?: () => void; +}) => { + const ref = useRef(null); + const isInView = useInView(ref, { once: true }); + const controls = useAnimation(); + + useEffect(() => { + if (isInView) { + controls.start("visible"); + } + }, [isInView]); + + return ( + + {children} + + ); +}; + +export default ScrollFadeIn; diff --git a/src/app/_components/scroll-slider.tsx b/src/app/_components/scroll-slider.tsx new file mode 100644 index 0000000..52cc589 --- /dev/null +++ b/src/app/_components/scroll-slider.tsx @@ -0,0 +1,43 @@ +import { motion, useAnimation, useInView } from "framer-motion"; +import { useEffect, useRef } from "react"; + +export const ScrollSlider = ({ + children, + className = "", +}: { + children: React.ReactNode; + className?: string; +}) => { + const ref = useRef(null); + const isInview = useInView(ref, { once: true }); + const controls = useAnimation(); + + useEffect(() => { + if (isInview) { + controls.start("visible"); + } + }, [isInview]); + return ( + + {children} + + ); +}; + +export default ScrollSlider; diff --git a/src/app/_components/showcase.tsx b/src/app/_components/showcase.tsx index ecc9d5e..bed4664 100644 --- a/src/app/_components/showcase.tsx +++ b/src/app/_components/showcase.tsx @@ -7,6 +7,7 @@ import ArtistShowcase from "./artist-showcase"; import UserShowcase from "./user-showcase"; import { TypographyH2 } from "./h2"; import { TypographyH1 } from "./h1"; +import ScrollSlider from "./scroll-slider"; export function Showcase({ userData, @@ -30,9 +31,11 @@ export function Showcase({ - - Tracks by album - + + + Tracks by album + + {Object.values(tracksByAlbum) .sort((a, b) => b.position - a.position) .map((album, index) => { @@ -47,9 +50,12 @@ export function Showcase({ /> ); })} - - Artists - + + + Artists + + +