Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Implement PaperScroll card component with unrolling animation #67

Merged
merged 2 commits into from
Oct 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/app/containers/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { default as NumbersGroup } from "./numbers-group/NumbersGroup";
export { default as FAQCollapse } from "./faq-collapse/FAQCollapse";
export { default as ExternalLink } from "./external-link/ExternalLink";
export { default as PaperScroll } from "./paper-scroll/PaperScroll";
18 changes: 18 additions & 0 deletions src/app/containers/paper-scroll/PaperScroll.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from "react";
import Reveal from "react-reveal/Reveal";

import "./PaperScroll.scss";

function PaperScroll({ children }) {
return (
<Reveal effect="unroll-scroll" duration={2000} delay={100}>
<div className="paper-scroll-card">
<div className="scroll-edge-start" />
<div className="card-body">{children}</div>
<div className="scroll-edge-end" />
</div>
</Reveal>
);
}

export default PaperScroll;
166 changes: 166 additions & 0 deletions src/app/containers/paper-scroll/PaperScroll.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
@use "globals/bootstrap";
@import "globals/zothacks-styles";

.paper-scroll-card {
position: relative; // critical in absolutely positioning scroll edges
opacity: 1; // override React Reveal initial hidden

.scroll-edge-start,
.card-body,
.scroll-edge-end {
// inherit animation properties from React Reveal
animation-duration: inherit;
animation-delay: inherit;
animation-iteration-count: inherit;
// Since animation class isn't included on load, initial configurations must be specified
// but final state should be maintained after animation
animation-fill-mode: forwards;
}

.scroll-edge-start,
.scroll-edge-end {
position: absolute;
background-size: contain;
background-repeat: no-repeat;
z-index: 1;
}

.scroll-edge-start {
background-image: url("/assets/graphics/scroll_light_left.png");
background-position: 100% center;
}

.scroll-edge-end {
background-image: url("/assets/graphics/scroll_light_right.png");
background-position: 0% center;
}

// vertical scroll design on narrower views
@include bootstrap.media-breakpoint-down(md) {
.scroll-edge-start,
.scroll-edge-end {
transform: rotate(90deg);
padding: 50%;
right: 0;
}
.scroll-edge-start {
bottom: 100%;
}
.scroll-edge-end {
top: 0%; // initially rolled up at the top
}
}

// horizontal scroll design on wider views
@include bootstrap.media-breakpoint-up(md) {
width: 85%; // decrease container width to account for scroll edges

.scroll-edge-start,
.scroll-edge-end {
// can be any sufficiently large width, may need to be increased for tall cards
width: 20%;
height: 100%;
top: 0;
}
.scroll-edge-start {
right: 50%; // initially rolled into center
}
.scroll-edge-end {
left: 50%; // initial rolled into center
}
}

.card-body {
padding: 5rem 1rem;
border: solid hsl(21, 66%, 24%);
@include bootstrap.media-breakpoint-down(md) {
border-width: 0 calc(0.8px + 0.4vw);
margin-left: 1.25rem;
}
@include bootstrap.media-breakpoint-up(md) {
border-width: 3.5px 0;
margin-bottom: 1.25rem;
}

background-image: url("/assets/graphics/scroll_light_texture.jpg");
background-position: center;
background-repeat: no-repeat;
background-size: 100% 100%;

// Masks are used to provide the unrolling animation
// The content inside the scroll edges is visible while the outside is hidden
mask-repeat: no-repeat;

@include bootstrap.media-breakpoint-up(md) {
mask-position: center;
mask-image: linear-gradient(
to right,
transparent 20%,
black 25%,
black 75%,
transparent 80%
);
mask-size: 0% 100%; // initial size before animation
}

@include bootstrap.media-breakpoint-down(md) {
mask-position: center 0; // expand from top to bottom
mask-image: linear-gradient(to bottom, black 50%, transparent 55%);
mask-size: 100% 0%; // initial size before animation
}
}
}

// React Reveal adds this className when the PaperScroll component becomes visible
.unroll-scroll {
.card-body {
animation-name: unroll-scroll-horizontal;
@include bootstrap.media-breakpoint-down(md) {
animation-name: unroll-scroll-vertical;
}
}

.scroll-edge-start {
@include bootstrap.media-breakpoint-up(md) {
animation-name: unroll-scroll-left;
}
}

.scroll-edge-end {
animation-name: unroll-scroll-down;
@include bootstrap.media-breakpoint-up(md) {
animation-name: unroll-scroll-right;
}
}
}

// animation keyframes specify ending states since initial states are specified in styles
@keyframes unroll-scroll-left {
100% {
right: 100%;
}
}

@keyframes unroll-scroll-right {
100% {
left: 100%;
}
}

@keyframes unroll-scroll-down {
100% {
top: 100%;
}
}

@keyframes unroll-scroll-horizontal {
100% {
mask-size: 200% 100%;
}
}

@keyframes unroll-scroll-vertical {
100% {
mask-size: 100% 200%;
}
}
10 changes: 3 additions & 7 deletions src/app/views/home/Home.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import Fade from "react-reveal/Fade";
// import Fade from "react-reveal/Fade";
import ReactTooltip from "react-tooltip";

import { Footer } from "app/components";
Expand All @@ -18,12 +18,8 @@ function Home() {
<ReactTooltip />

<Landing />
<Fade duration={1000}>
<Intro />
</Fade>
<Fade duration={1000}>
<Mentors />
</Fade>
<Intro />
<Mentors />
{/* <Fade duration={1000}>
<Sponsors />
</Fade> */}
Expand Down
33 changes: 7 additions & 26 deletions src/app/views/home/Home.scss
Original file line number Diff line number Diff line change
Expand Up @@ -36,45 +36,26 @@
}
}

.card {
color: $black;
width: 60vw;
// temporary color for scroll design
background-color: rgb(227, 192, 147);
padding: 3rem;
border-radius: 1rem;
// box-shadow: 0 30px 40px rgba(222, 194, 141, 0.54);
z-index: 1;
h2 {
text-align: center;
font-size: 3rem;

@media screen and (max-width: $break-small) {
width: 80vw;
text-align: center;
padding: 1.7rem;
padding-top: 2rem;
}

h2 {
text-align: center;
font-size: 3rem;
// width: 80vw;

@media screen and (max-width: $break-small) {
font-size: 25px;
}
font-size: 25px;
}
}

.card-text {
.card-body p {
text-align: left;
color: $brown;
}

@media screen and (max-width: $break-medium) {
.card p {
.card-body p {
text-align: center;
font-size: 1rem;
}
.card h2 {
.card-body h2 {
font-size: 2rem;
}
}
Expand Down
7 changes: 4 additions & 3 deletions src/app/views/home/sections/Intro.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import React from "react";

import { PaperScroll } from "app/containers";
import zothacksLogo from "assets/icons/zothacks-logo.svg";

import "./Intro.scss";

function Intro() {
return (
<section className="intro">
<div className="card">
<section className="container intro">
<PaperScroll>
<img className="zothacks-logo" src={zothacksLogo} alt="ZotHacks Logo" />
<h2>What is ZotHacks?</h2>
<p className="card-text">
Expand All @@ -17,7 +18,7 @@ function Intro() {
hackathons and web development by providing technical workshops,
strong mentorship, and free food!
</p>
</div>
</PaperScroll>
</section>
);
}
Expand Down
6 changes: 2 additions & 4 deletions src/app/views/home/sections/Intro.scss
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
.home {
.intro {
margin: auto;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
position: relative;
align-items: center;

.zothacks-logo {
width: 100px;
margin: 0 auto 2rem auto;
filter: brightness(0.2);
}
}
Expand Down
7 changes: 4 additions & 3 deletions src/app/views/home/sections/Mentors.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from "react";

import { PaperScroll } from "app/containers";
import mentorship from "assets/images/mentorship.png";

import "./Mentors.scss";
Expand All @@ -8,8 +9,8 @@ const MENTOR_APPLICATION_URL = "https://airtable.com/shr5B94rQ66KWH3Iw";

function Mentors() {
return (
<section className="mentors">
<div className="card">
<section className="container mentors">
<PaperScroll>
<img
src={mentorship}
alt="A mentor at a hackathon helping a participant with coding"
Expand All @@ -31,7 +32,7 @@ function Mentors() {
Apply to be a Mentor
</a>
</div>
</div>
</PaperScroll>
</section>
);
}
Expand Down
Binary file added src/assets/graphics/scroll_light_left.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/graphics/scroll_light_right.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/graphics/scroll_light_texture.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.