Header: implement new snazzy Header
The new Header component uses framer-motion to animate transitions between illustrations and x-ray views showing the icons used in their construction.
This commit is contained in:
@@ -10,6 +10,50 @@ header {
|
|||||||
justify-content: center; */
|
justify-content: center; */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.intro {
|
||||||
|
width: 660px;
|
||||||
|
position: absolute;
|
||||||
|
transform: translate(143px, 392px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro h2 {
|
||||||
|
font-size: 40px;
|
||||||
|
line-height: 50px;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.links {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
margin: 56px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.links a:not(:first-child) {
|
||||||
|
margin-left: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.nav-link {
|
||||||
|
text-decoration: none;
|
||||||
|
position: relative;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.nav-link:after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: -2px;
|
||||||
|
left: 0;
|
||||||
|
width: 0%;
|
||||||
|
border-bottom: 1px solid black;
|
||||||
|
transition: 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.nav-link:hover:after {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.image-container {
|
.image-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 1366px;
|
width: 1366px;
|
||||||
@@ -17,6 +61,10 @@ header {
|
|||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inspectable {
|
||||||
|
cursor: cell;
|
||||||
|
}
|
||||||
|
|
||||||
#marker-purple {
|
#marker-purple {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
transform: translate(143px, -158px);
|
transform: translate(143px, -158px);
|
||||||
|
|||||||
@@ -1,43 +1,253 @@
|
|||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
import { motion } from "framer-motion";
|
import { motion, AnimatePresence } from "framer-motion";
|
||||||
|
|
||||||
import markerPurple from "../../assets/marker-purple.svg";
|
import markerPurple from "../../assets/marker-purple.svg";
|
||||||
import tablet from "../../assets/tablet.svg";
|
|
||||||
import billiardBall from "../../assets/billiard-ball.svg";
|
|
||||||
import warning from "../../assets/warning.svg";
|
|
||||||
import paperclips from "../../assets/paperclips.svg";
|
import paperclips from "../../assets/paperclips.svg";
|
||||||
|
import tablet from "../../assets/tablet.svg";
|
||||||
|
import tabletSpec from "../../assets/tablet-spec.svg";
|
||||||
|
import billiardBall from "../../assets/billiard-ball.svg";
|
||||||
|
import billiardBallSpec from "../../assets/billiard-ball-spec.svg";
|
||||||
|
import warning from "../../assets/warning.svg";
|
||||||
|
import warningSpec from "../../assets/warning-spec.svg";
|
||||||
import cuttingMat from "../../assets/cutting-mat.svg";
|
import cuttingMat from "../../assets/cutting-mat.svg";
|
||||||
|
import cuttingMatSpec from "../../assets/cutting-mat-spec.svg";
|
||||||
import receipt from "../../assets/receipt.svg";
|
import receipt from "../../assets/receipt.svg";
|
||||||
|
import receiptSpec from "../../assets/receipt-spec.svg";
|
||||||
import calculator from "../../assets/calculator.svg";
|
import calculator from "../../assets/calculator.svg";
|
||||||
|
import calculatorSpec from "../../assets/calculator-spec.svg";
|
||||||
import "./Header.css";
|
import "./Header.css";
|
||||||
|
|
||||||
type HeaderProps = {};
|
type HeaderProps = {};
|
||||||
|
|
||||||
const variants = {
|
const variants = {
|
||||||
hidden: { opacity: 0, y: 100 },
|
hidden: { opacity: 0, transition: { duration: 0.2 } },
|
||||||
visible: { opacity: 1, y: 0 },
|
visible: { opacity: 1, transition: { duration: 0.2 } },
|
||||||
};
|
};
|
||||||
|
|
||||||
const Header: React.FC<HeaderProps> = () => {
|
const Header: React.FC<HeaderProps> = () => {
|
||||||
|
const [hovered, setHovered] = useState<string | false>(false);
|
||||||
|
const clearHover = () => setHovered(false);
|
||||||
|
// const handleScrollToIcons = () => {};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header>
|
<header>
|
||||||
<motion.div
|
<motion.div
|
||||||
className="image-container"
|
className="image-container"
|
||||||
variants={variants}
|
variants={variants}
|
||||||
initial="hidden"
|
initial="visible"
|
||||||
animate="visible"
|
// animate="visible"
|
||||||
transition={{ duration: 2 }}
|
transition={{ duration: 2 }}
|
||||||
>
|
>
|
||||||
{/* <MarkerPurple id="marker-purple" /> */}
|
|
||||||
{/* <Tablet id="tablet" /> */}
|
|
||||||
<img src={tablet} id="tablet" />
|
|
||||||
<img src={markerPurple} id="marker-purple" />
|
<img src={markerPurple} id="marker-purple" />
|
||||||
<img src={billiardBall} id="billiard-ball" />
|
|
||||||
<img src={warning} id="warning" />
|
|
||||||
<img src={paperclips} id="paperclips" />
|
<img src={paperclips} id="paperclips" />
|
||||||
<img src={cuttingMat} id="cutting-mat" />
|
<AnimatePresence>
|
||||||
<img src={receipt} id="receipt" />
|
{hovered === "tablet" ? (
|
||||||
<img src={calculator} id="calculator" />
|
<motion.img
|
||||||
|
id="tablet"
|
||||||
|
key="tablet-spec"
|
||||||
|
className="inspectable"
|
||||||
|
initial="hidden"
|
||||||
|
animate="visible"
|
||||||
|
exit="hidden"
|
||||||
|
variants={variants}
|
||||||
|
// onHoverStart={() => setHovered("tablet")}
|
||||||
|
onHoverEnd={clearHover}
|
||||||
|
src={tabletSpec}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<motion.img
|
||||||
|
id="tablet"
|
||||||
|
key="tablet"
|
||||||
|
className="inspectable"
|
||||||
|
initial="hidden"
|
||||||
|
animate="visible"
|
||||||
|
exit="hidden"
|
||||||
|
variants={variants}
|
||||||
|
onHoverStart={() => setHovered("tablet")}
|
||||||
|
// onHoverEnd={clearHover}
|
||||||
|
src={tablet}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{hovered === "billiard-ball" ? (
|
||||||
|
<motion.img
|
||||||
|
id="billiard-ball"
|
||||||
|
key="billiard-ball-spec"
|
||||||
|
className="inspectable"
|
||||||
|
initial="hidden"
|
||||||
|
animate="visible"
|
||||||
|
exit="hidden"
|
||||||
|
variants={variants}
|
||||||
|
// onHoverStart={() => setHovered("billiard-ball")}
|
||||||
|
onHoverEnd={clearHover}
|
||||||
|
src={billiardBallSpec}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<motion.img
|
||||||
|
id="billiard-ball"
|
||||||
|
key="billiard-ball"
|
||||||
|
className="inspectable"
|
||||||
|
initial="hidden"
|
||||||
|
animate="visible"
|
||||||
|
exit="hidden"
|
||||||
|
variants={variants}
|
||||||
|
onHoverStart={() => setHovered("billiard-ball")}
|
||||||
|
// onHoverEnd={clearHover}
|
||||||
|
src={billiardBall}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{hovered === "warning" ? (
|
||||||
|
<motion.img
|
||||||
|
id="warning"
|
||||||
|
key="warning-spec"
|
||||||
|
className="inspectable"
|
||||||
|
initial="hidden"
|
||||||
|
animate="visible"
|
||||||
|
exit="hidden"
|
||||||
|
variants={variants}
|
||||||
|
// onHoverStart={() => setHovered("warning")}
|
||||||
|
onHoverEnd={clearHover}
|
||||||
|
src={warningSpec}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<motion.img
|
||||||
|
id="warning"
|
||||||
|
key="warning"
|
||||||
|
className="inspectable"
|
||||||
|
initial="hidden"
|
||||||
|
animate="visible"
|
||||||
|
exit="hidden"
|
||||||
|
variants={variants}
|
||||||
|
onHoverStart={() => setHovered("warning")}
|
||||||
|
// onHoverEnd={clearHover}
|
||||||
|
src={warning}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{hovered === "cutting-mat" ? (
|
||||||
|
<motion.img
|
||||||
|
id="cutting-mat"
|
||||||
|
key="cutting-mat-spec"
|
||||||
|
className="inspectable"
|
||||||
|
initial="hidden"
|
||||||
|
animate="visible"
|
||||||
|
exit="hidden"
|
||||||
|
variants={variants}
|
||||||
|
// onHoverStart={() => setHovered("cutting-mat")}
|
||||||
|
onHoverEnd={clearHover}
|
||||||
|
src={cuttingMatSpec}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<motion.img
|
||||||
|
id="cutting-mat"
|
||||||
|
key="cutting-mat"
|
||||||
|
className="inspectable"
|
||||||
|
initial="hidden"
|
||||||
|
animate="visible"
|
||||||
|
exit="hidden"
|
||||||
|
variants={variants}
|
||||||
|
onHoverStart={() => setHovered("cutting-mat")}
|
||||||
|
// onHoverEnd={clearHover}
|
||||||
|
src={cuttingMat}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{hovered === "receipt" ? (
|
||||||
|
<motion.img
|
||||||
|
id="receipt"
|
||||||
|
key="receipt-spec"
|
||||||
|
className="inspectable"
|
||||||
|
initial="hidden"
|
||||||
|
animate="visible"
|
||||||
|
exit="hidden"
|
||||||
|
variants={variants}
|
||||||
|
// onHoverStart={() => setHovered("receipt")}
|
||||||
|
onHoverEnd={clearHover}
|
||||||
|
src={receiptSpec}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<motion.img
|
||||||
|
id="receipt"
|
||||||
|
key="receipt"
|
||||||
|
className="inspectable"
|
||||||
|
initial="visible"
|
||||||
|
variants={variants}
|
||||||
|
onHoverStart={() => setHovered("receipt")}
|
||||||
|
// onHoverEnd={clearHover}
|
||||||
|
src={receipt}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{hovered === "calculator" ? (
|
||||||
|
<motion.img
|
||||||
|
id="calculator"
|
||||||
|
key="calculator-spec"
|
||||||
|
className="inspectable"
|
||||||
|
initial="hidden"
|
||||||
|
animate="visible"
|
||||||
|
exit="hidden"
|
||||||
|
variants={variants}
|
||||||
|
// onHoverStart={() => setHovered("calculator")}
|
||||||
|
onHoverEnd={clearHover}
|
||||||
|
src={calculatorSpec}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<motion.img
|
||||||
|
id="calculator"
|
||||||
|
key="calculator"
|
||||||
|
className="inspectable"
|
||||||
|
initial="hidden"
|
||||||
|
animate="visible"
|
||||||
|
exit="hidden"
|
||||||
|
variants={variants}
|
||||||
|
onHoverStart={() => setHovered("calculator")}
|
||||||
|
// onHoverEnd={clearHover}
|
||||||
|
src={calculator}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</AnimatePresence>
|
||||||
|
<div className="intro">
|
||||||
|
<h2>
|
||||||
|
Phosphor Icons is a flexible icon family for interfaces, diagrams,
|
||||||
|
presentations – whatever really.
|
||||||
|
</h2>
|
||||||
|
<div style={{ display: "flex" }}>
|
||||||
|
<button className="main-button">Get started</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
className="main-button"
|
||||||
|
onClick={() => {
|
||||||
|
document
|
||||||
|
.getElementById("toolbar")
|
||||||
|
?.scrollIntoView({ behavior: "smooth", block: "start" });
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Explore icons
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="links">
|
||||||
|
<a
|
||||||
|
className="nav-link"
|
||||||
|
href="https://github.com/rektdeckard/phosphor-web#phosphor-icons"
|
||||||
|
>
|
||||||
|
Docs
|
||||||
|
</a>
|
||||||
|
<a className="nav-link" href="#">
|
||||||
|
Download
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
className="nav-link"
|
||||||
|
href="https://github.com/rektdeckard/phosphor-web/issues"
|
||||||
|
>
|
||||||
|
Request
|
||||||
|
</a>
|
||||||
|
<a className="nav-link" href="#">
|
||||||
|
Donate
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
className="nav-link"
|
||||||
|
href="https://github.com/rektdeckard/phosphor-web"
|
||||||
|
>
|
||||||
|
Github
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</header>
|
</header>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user