Skip to content

Commit

Permalink
Merge pull request #55 from Valik3201/feature/animations
Browse files Browse the repository at this point in the history
Feature/animations
  • Loading branch information
Valik3201 authored Jun 23, 2024
2 parents 0fa710f + 42afd34 commit 5ef3ccb
Show file tree
Hide file tree
Showing 7 changed files with 216 additions and 63 deletions.
40 changes: 40 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@
"date-fns": "^3.6.0",
"firebase": "^10.12.2",
"formik": "^2.4.6",
"framer-motion": "^11.2.11",
"nanoid": "^5.0.7",
"next": "14.2.4",
"next-themes": "^0.3.0",
"react": "^18",
"react-dom": "^18",
"react-easy-crop": "^5.0.7",
"react-intersection-observer": "^9.10.3",
"react-redux": "^9.1.2",
"tailwind-datepicker-react": "^1.4.3",
"yup": "^1.4.0"
Expand Down
33 changes: 25 additions & 8 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use client";

import AnimatedSection from "../components/Home/AnimatedSection";
import Hero from "../components/Home/Hero";
import InvoiceStatus from "../components/Home/InvoiceStatus";
import ManageInvoices from "../components/Home/ManageInvoices";
Expand All @@ -12,14 +13,30 @@ import CreateFirstInvoice from "../components/Home/CreateFirstInvoice";
export default function Home() {
return (
<div className="container mx-auto space-y-8">
<Hero />
<InvoiceStatus />
<ManageInvoices />
<FilterInvoices />
<Flexibility />
<PersonalizeWorkspace />
<ResponsiveDesign />
<CreateFirstInvoice />
<AnimatedSection delay={0}>
<Hero />
</AnimatedSection>
<AnimatedSection delay={0.2}>
<InvoiceStatus />
</AnimatedSection>
<AnimatedSection delay={0.4}>
<ManageInvoices />
</AnimatedSection>
<AnimatedSection delay={0.6}>
<FilterInvoices />
</AnimatedSection>
<AnimatedSection delay={0.8}>
<Flexibility />
</AnimatedSection>
<AnimatedSection delay={1.0}>
<PersonalizeWorkspace />
</AnimatedSection>
<AnimatedSection delay={0.7}>
<ResponsiveDesign />
</AnimatedSection>
<AnimatedSection delay={0.4}>
<CreateFirstInvoice />
</AnimatedSection>
</div>
);
}
30 changes: 30 additions & 0 deletions src/components/Home/AnimatedSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { ReactNode } from "react";
import { motion } from "framer-motion";
import { useInView } from "react-intersection-observer";

export default function AnimatedSection({
children,
delay,
}: {
children: ReactNode;
delay: number;
}) {
const [ref, inView] = useInView({ triggerOnce: true, threshold: 0.1 });

const animations = {
hidden: { opacity: 0, y: 50 },
visible: { opacity: 1, y: 0 },
};

return (
<motion.div
ref={ref}
initial="hidden"
animate={inView ? "visible" : "hidden"}
variants={animations}
transition={{ duration: 0.5, delay }}
>
{children}
</motion.div>
);
}
75 changes: 54 additions & 21 deletions src/components/Home/Flexibility.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
import { motion, useScroll, useTransform } from "framer-motion";
import Image from "next/image";

export default function Flexibility() {
const { scrollYProgress } = useScroll();

const rotateMarkAsPaid = useTransform(scrollYProgress, [0, 1], [12, -12]);
const rotateSaveAsDraft = useTransform(scrollYProgress, [0, 1], [-6, 0]);
const translateXSaveAsDraft = useTransform(
scrollYProgress,
[0, 1],
[50, -30]
);
const scaleMarkAsPaid = useTransform(scrollYProgress, [0, 1], [1, 1.25]);
const scaleSaveAsDraft = useTransform(scrollYProgress, [0, 1], [1, 1.25]);

return (
<div className="flex flex-col md:flex-row items-center justify-between bg-white rounded-lg p-8 shadow-item dark:bg-dark-light">
<div className="md:ps-4 space-y-4">
Expand All @@ -11,27 +24,47 @@ export default function Flexibility() {
</ul>
</div>
<div className="pt-6 md:pt-0 pe-10 md:pe-20">
<Image
src="/buttons/mark-as-paid.png"
alt="Mark as paid button"
width={150}
height={50}
className="rotate-6"
/>
<Image
src="/buttons/save-as-draft.png"
alt="Save as draft button"
width={150}
height={50}
className="dark:hidden -rotate-3 translate-x-10"
/>
<Image
src="/buttons/save-as-draft-dark.png"
alt="Save as draft button"
width={150}
height={50}
className="hidden dark:block -rotate-3 translate-x-10"
/>
<motion.div
style={{ rotate: rotateMarkAsPaid, scale: scaleMarkAsPaid }}
>
<Image
src="/buttons/mark-as-paid.png"
alt="Mark as paid button"
width={150}
height={50}
className="rotate-6"
/>
</motion.div>
<motion.div
style={{
rotate: rotateSaveAsDraft,
x: translateXSaveAsDraft,
scale: scaleSaveAsDraft,
}}
>
<Image
src="/buttons/save-as-draft.png"
alt="Save as draft button"
width={150}
height={50}
className="dark:hidden -rotate-3 translate-x-10"
/>
</motion.div>
<motion.div
style={{
rotate: rotateSaveAsDraft,
x: translateXSaveAsDraft,
scale: scaleSaveAsDraft,
}}
>
<Image
src="/buttons/save-as-draft-dark.png"
alt="Save as draft button"
width={150}
height={50}
className="hidden dark:block -rotate-3 translate-x-10"
/>
</motion.div>
</div>
</div>
);
Expand Down
72 changes: 44 additions & 28 deletions src/components/Home/InvoiceStatus.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,53 @@
import { motion, useScroll, useTransform } from "framer-motion";
import Image from "next/image";

export default function InvoiceStatus() {
const { scrollYProgress } = useScroll();

const rotatePaid = useTransform(scrollYProgress, [0, 1], [-8, 8]);
const translateXPaid = useTransform(scrollYProgress, [0, 1], [-20, 20]);
const rotatePending = useTransform(scrollYProgress, [0, 1], [8, -8]);
const translateXPending = useTransform(scrollYProgress, [0, 1], [50, -50]);
const rotateDraft = useTransform(scrollYProgress, [0, 1], [-6, 6]);
const translateXDraft = useTransform(scrollYProgress, [0, 1], [-10, 30]);

return (
<div className="flex flex-col-reverse md:flex-row items-center justify-between gap-8 md:gap-20 bg-white rounded-lg p-8 shadow-item dark:bg-dark-light">
<div className="md:ps-8">
<Image
src="/status/status-paid.png"
alt="Status Paid"
width={150}
height={30}
className="-rotate-6"
/>
<Image
src="/status/status-pending.png"
alt="Status Pending"
width={150}
height={30}
className="rotate-6 translate-x-8"
/>
<Image
src="/status/status-draft.png"
alt="Status Draft"
width={150}
height={30}
className="dark:hidden -rotate-3"
/>
<Image
src="/status/status-draft-dark.png"
alt="Status Draft"
width={150}
height={30}
className="hidden dark:block -rotate-3"
/>
<motion.div style={{ rotate: rotatePaid, x: translateXPaid }}>
<Image
src="/status/status-paid.png"
alt="Status Paid"
width={150}
height={30}
/>
</motion.div>
<motion.div style={{ rotate: rotatePending, x: translateXPending }}>
<Image
src="/status/status-pending.png"
alt="Status Pending"
width={150}
height={30}
/>
</motion.div>
<motion.div style={{ rotate: rotateDraft, x: translateXDraft }}>
<Image
src="/status/status-draft.png"
alt="Status Draft"
width={150}
height={30}
className="dark:hidden"
/>
</motion.div>
<motion.div style={{ rotate: rotateDraft, x: translateXDraft }}>
<Image
src="/status/status-draft-dark.png"
alt="Status Draft"
width={150}
height={30}
className="hidden dark:block"
/>
</motion.div>
</div>

<div className="flex flex-col gap-4 pe-4">
Expand Down
27 changes: 21 additions & 6 deletions src/components/Home/PersonalizeWorkspace.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { motion, useScroll, useTransform } from "framer-motion";
import Image from "next/image";

export default function PersonalizeWorkspace() {
const { scrollYProgress } = useScroll();

const rotateX = useTransform(scrollYProgress, [0, 0.75], [135, 0]);
const scale = useTransform(scrollYProgress, [0, 0.5], [1.5, 1]);

return (
<div className="flex flex-col items-center gap-6 bg-white rounded-lg p-8 shadow-item dark:bg-dark-light">
<div className="space-y-4">
Expand All @@ -10,12 +16,21 @@ export default function PersonalizeWorkspace() {
</p>
</div>

<Image
src="/mockups/mockup-3.png"
alt="Theme Toggle Macbook"
width={666}
height={444}
/>
<div style={{ perspective: "1000px" }}>
<motion.div
style={{
rotateX: rotateX,
scale: scale,
}}
>
<Image
src="/mockups/mockup-3.png"
alt="Theme Toggle Macbook"
width={666}
height={444}
/>
</motion.div>
</div>
</div>
);
}

0 comments on commit 5ef3ccb

Please sign in to comment.