Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/sticky note animation #114

Merged
merged 15 commits into from
Nov 4, 2023
Merged
17 changes: 14 additions & 3 deletions apps/site/src/app/(home)/sections/Intro/Intro.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

.intro {
@include bootstrap.padding(10rem 0.5rem);
margin-left: 10px;
margin-right: 10px;

background-image: url("~src/assets/images/index-card-mobile.svg");
background-size: cover;
Expand All @@ -27,10 +29,19 @@

.pin {
position: absolute;
top: 0;
left: 50%;
transform: translate(-75%, -50%);
top: -12%;
left: 45%;
width: auto;

@include bootstrap.media-breakpoint-down(xl) {
left: 45%;
}
@include bootstrap.media-breakpoint-down(lg) {
left: 40%;
}
@include bootstrap.media-breakpoint-down(md) {
left: 35%;
}
}

.hackDoodle {
Expand Down
20 changes: 18 additions & 2 deletions apps/site/src/app/(home)/sections/Intro/Intro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import Image from "next/image";
import Container from "react-bootstrap/Container";

import { motion, cubicBezier } from "framer-motion";
import pin from "@/assets/images/index-card-pin.svg";
import hackDoodle from "@/assets/images/hack-doodle.png";

Expand All @@ -12,9 +13,24 @@ const Intro = () => {
return (
<Container as="section">
<div className={styles.intro}>
<Image
<motion.img
initial={{
opacity: 0,
y: -10,
x: -10,
}}
viewport={{ once: true }}
whileInView={{
opacity: 1,
y: 0,
x: 0,
transition: {
duration: 0.65,
ease: cubicBezier(0.64, 0, 0.78, 0),
},
}}
className={styles.pin}
src={pin}
src={pin.src}
width="100"
height="100"
alt="Index card pin"
Expand Down
2 changes: 1 addition & 1 deletion apps/site/src/app/(home)/sections/Landing/ApplyButton.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Button from "react-bootstrap/Button";
import StickerPosition from "@/components/Sticker/StickerPosition";
import { HackSticker, HeartSticker } from "@/components/Sticker/Stickers";
import { HeartSticker } from "@/components/Sticker/Stickers";

import styles from "./ApplyButton.module.scss";

Expand Down
60 changes: 46 additions & 14 deletions apps/site/src/app/(home)/sections/Mentor/Mentor.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"use client";

import { motion, cubicBezier, Variants } from "framer-motion";
import Image from "next/image";
import Col from "react-bootstrap/Col";
import Container from "react-bootstrap/Container";
Expand All @@ -11,6 +11,26 @@ import styles from "./Mentor.module.scss";

const MENTOR_APP_URL = "/mentor";

const variant: Variants = {
initial: {
scale: 1.1,
opacity: 0,
rotateX: 20,
translateY: 30,
},
animate: {
scale: 1,
rotateX: 0,
opacity: 1,
translateY: 0,
transition: {
duration: 0.85,
staggerChildren: 0.1,
ease: cubicBezier(0.33, 1, 0.68, 1),
},
},
};

const Mentor = () => {
const mentorHeader = (
<h2 className="mb-3 text-start">Interested in becoming a mentor?</h2>
Expand All @@ -35,20 +55,32 @@ const Mentor = () => {

return (
<Container as="section">
<div className="position-relative my-5">
<Col lg={5} className={styles.applySticky}>
<Image src={tape} alt="post-it tape" className={styles.tape} />
<div className={styles.applyStickyContent}>
{mentorHeader}
<motion.div
variants={variant}
initial="initial"
whileInView="animate"
className="position-relative my-5"
>
<motion.div variants={variant}>
<Col lg={5} className={styles.applySticky}>
<motion.img
variants={variant}
src={tape.src}
alt="post-it tape"
className={styles.tape}
/>
<div className={styles.applyStickyContent}>
{mentorHeader}
{mentorDescription}
</div>
{applyLink}
</Col>
<Col className={styles.descSticky + " text-center"}>
{mentorDescription}
</div>
{applyLink}
</Col>
<Col className={styles.descSticky + " text-center"}>
{mentorDescription}
{applyLink}
</Col>
</div>
{applyLink}
</Col>
</motion.div>
</motion.div>
</Container>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ const HackSticker: React.FC<StickerProps> = (props) => (
<BaseSticker
imageSrc={HackLogo.src}
alt="Hack at UCI sticker"
height={200}
width={200}
height={150}
width={150}
{...lightShake}
{...props}
/>
Expand Down
2 changes: 0 additions & 2 deletions apps/site/src/components/Sticker/Stickers/index.ts

This file was deleted.

30 changes: 30 additions & 0 deletions apps/site/src/components/Sticker/Stickers/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type React from "react";
import type { StickerProps } from "./stickerProps";
import HackLogo from "@/assets/icons/hack.png";
import HeartEmoji from "@/assets/images/heart_emoji.png";
import BaseSticker from "../BaseSticker";
import { fastShake, lightShake } from "@/components/animation";

export const HackSticker: React.FC<StickerProps> = (props) => {
return (
<BaseSticker
imageSrc={HackLogo.src}
alt="Hack at UCI sticker"
height={150}
width={150}
{...lightShake}
{...props}
/>
);
};

export const HeartSticker: React.FC<StickerProps> = (props) => (
<BaseSticker
imageSrc={HeartEmoji.src}
alt="heart emoji sticker"
height={150}
width={150}
{...fastShake}
{...props}
/>
);
2 changes: 2 additions & 0 deletions apps/site/src/lib/styles/globals.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ $container-padding: 8rem;
.background {
background-image: url("~@/assets/background/anteater-head-tiling.gif");
background-size: 464px; // half size for 2x scaling
overflow-x: hidden;
max-width: 100%;
}

.accordion {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,22 @@
position: relative;
padding: 1rem 0;
box-shadow: 0 6px 5px -2px rgba(gray, 0.5);
@media screen and (max-width: 400px) {
width: 300px;
}
}

.tape {
background-image: url("~@/assets/images/tape.svg");
width: 238px;
samderanova marked this conversation as resolved.
Show resolved Hide resolved
height: 60px;
position: absolute;
top: -12.5%;
top: 3%;
left: 15%;
z-index: 10;
@media screen and (max-width: 400px) {
left: 10%;
}
}

.container {
Expand Down
123 changes: 91 additions & 32 deletions apps/site/src/views/Resources/components/ResourceCard/ResourceCard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use client";
import Image from "next/image";

import { Variants, motion, AnimatePresence, cubicBezier } from "framer-motion";
import openNewWindow from "@/assets/icons/open-new-window.svg";
import styles from "./ResourceCard.module.scss";

Expand All @@ -16,6 +17,27 @@ interface ResourceCardProps {
stickyNoteColor: string;
}

const variant: Variants = {
initial: {
scale: 1.1,
opacity: 0,
rotateX: 20,
translateY: 30,
},
animate: {
scale: 1,
rotateX: 0,
opacity: 1,
translateY: 0,
transition: {
duration: 0.85,
staggerChildren: 0.1,
staggerDirection: -1,
ease: cubicBezier(0.33, 1, 0.68, 1),
},
},
};

export default function ResourceCard({
title,
description,
Expand All @@ -24,38 +46,75 @@ export default function ResourceCard({
stickyNoteColor,
}: ResourceCardProps) {
return (
<div
className={styles.group}
style={{
backgroundColor: `${stickyNoteColor}`,
}}
>
<div className={styles.container + " text-center px-3"}>
<div className={styles.tape}></div>
{stickerSrc && <img src={stickerSrc} alt="Resource logo" width="100" />}
<h3>{title}</h3>
{description}
</div>

{links.map(({ text, link }) => (
<a
key={link}
href={link}
target="_blank"
rel="noopener noreferrer"
className={styles.tag}
<AnimatePresence mode="wait">
<motion.div style={{ position: "relative" }}>
<motion.div
initial={{
scale: 1.1,
opacity: 0,
rotateX: 15,
}}
viewport={{ once: true }}
whileInView={{
scale: 1,
rotateX: 0,
opacity: 1,
transition: {
delay: 0.1,
duration: 0.65,
ease: cubicBezier(0.64, 0, 0.78, 0),
},
}}
className={styles.tape}
></motion.div>
<motion.div
variants={variant}
initial="initial"
whileInView="animate"
viewport={{ once: true }}
className={styles.group}
style={{
backgroundColor: `${stickyNoteColor}`,
}}
>
{text}
<div className="d-inline ms-1 vertical-align-middle">
<Image
src={openNewWindow}
width="20"
height="20"
alt="Open link in new window"
/>
<div className={styles.container + " text-center px-3"}>
{stickerSrc && (
<motion.img
src={stickerSrc}
alt="Resource logo"
width="100"
variants={variant}
/>
)}
<h3>{title}</h3>
{description}
</div>
</a>
))}
</div>

{links.map(({ text, link }) => (
<motion.a
key={link}
href={link}
target="_blank"
rel="noopener noreferrer"
className={styles.tag}
variants={variant}
>
{text}
<motion.div
className="d-inline ms-1 vertical-align-middle"
variants={variant}
>
<Image
src={openNewWindow}
width="20"
height="20"
alt="Open link in new window"
/>
</motion.div>
</motion.a>
))}
</motion.div>
</motion.div>
</AnimatePresence>
);
}
Loading