created animation + hoverAnimation helperFunction. Also Hero + Techstack (prev) styled and animated.

This commit is contained in:
yousifpa98
2024-12-20 01:12:49 +01:00
parent 1ff58ea7cc
commit 54df568dc6
24 changed files with 715 additions and 135 deletions

View File

@@ -4,4 +4,5 @@ main {
display: flex;
align-items: center;
justify-content: center;
padding: 2rem;
}

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc. --><path d="M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"/></svg>

After

Width:  |  Height:  |  Size: 715 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc. --><path d="M448 96c0-35.3-28.7-64-64-64H64C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96zM265.8 407.7c0-1.8 0-6 .1-11.6c.1-11.4 .1-28.8 .1-43.7c0-15.6-5.2-25.5-11.3-30.7c37-4.1 76-9.2 76-73.1c0-18.2-6.5-27.3-17.1-39c1.7-4.3 7.4-22-1.7-45c-13.9-4.3-45.7 17.9-45.7 17.9c-13.2-3.7-27.5-5.6-41.6-5.6s-28.4 1.9-41.6 5.6c0 0-31.8-22.2-45.7-17.9c-9.1 22.9-3.5 40.6-1.7 45c-10.6 11.7-15.6 20.8-15.6 39c0 63.6 37.3 69 74.3 73.1c-4.8 4.3-9.1 11.7-10.6 22.3c-9.5 4.3-33.8 11.7-48.3-13.9c-9.1-15.8-25.5-17.1-25.5-17.1c-16.2-.2-1.1 10.2-1.1 10.2c10.8 5 18.4 24.2 18.4 24.2c9.7 29.7 56.1 19.7 56.1 19.7c0 9 .1 21.7 .1 30.6c0 4.8 .1 8.6 .1 10c0 4.3-3 9.5-11.5 8C106 393.6 59.8 330.8 59.8 257.4c0-91.8 70.2-161.5 162-161.5s166.2 69.7 166.2 161.5c.1 73.4-44.7 136.3-110.7 158.3c-8.4 1.5-11.5-3.7-11.5-8zm-90.5-54.8c-.2-1.5 1.1-2.8 3-3.2c1.9-.2 3.7 .6 3.9 1.9c.3 1.3-1 2.6-3 3c-1.9 .4-3.7-.4-3.9-1.7zm-9.1 3.2c-2.2 .2-3.7-.9-3.7-2.4c0-1.3 1.5-2.4 3.5-2.4c1.9-.2 3.7 .9 3.7 2.4c0 1.3-1.5 2.4-3.5 2.4zm-14.3-2.2c-1.9-.4-3.2-1.9-2.8-3.2s2.4-1.9 4.1-1.5c2 .6 3.3 2.1 2.8 3.4c-.4 1.3-2.4 1.9-4.1 1.3zm-12.5-7.3c-1.5-1.3-1.9-3.2-.9-4.1c.9-1.1 2.8-.9 4.3 .6c1.3 1.3 1.8 3.3 .9 4.1c-.9 1.1-2.8 .9-4.3-.6zm-8.5-10c-1.1-1.5-1.1-3.2 0-3.9c1.1-.9 2.8-.2 3.7 1.3c1.1 1.5 1.1 3.3 0 4.1c-.9 .6-2.6 0-3.7-1.5zm-6.3-8.8c-1.1-1.3-1.3-2.8-.4-3.5c.9-.9 2.4-.4 3.5 .6c1.1 1.3 1.3 2.8 .4 3.5c-.9 .9-2.4 .4-3.5-.6zm-6-6.4c-1.3-.6-1.9-1.7-1.5-2.6c.4-.6 1.5-.9 2.8-.4c1.3 .7 1.9 1.8 1.5 2.6c-.4 .9-1.7 1.1-2.8 .4z"/></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

24
src/components/Hero.jsx Normal file
View File

@@ -0,0 +1,24 @@
import React, { useState } from "react";
import "../css/Hero.css";
import "animate.css";
const Hero = ({ initialAnimation, onMouseEnter, onAnimationEnd }) => {
const [animation, setAnimation] = useState(initialAnimation);
return (
<div
className={`hero container animate__animated ${animation}`}
onMouseEnter={() => onMouseEnter(setAnimation)}
onAnimationEnd={() => onAnimationEnd(setAnimation)}
>
<p>
<span>
Hi, I'm Yousif. <br />
</span>{" "}
I'm a Full-Stack Developer from Germany.
</p>
</div>
);
};
export default Hero;

View File

@@ -1,11 +1,50 @@
import React from "react";
import Hero from "./subComponents/Hero";
import Hero from "./Hero";
import "../css/Home.css";
import TechStack from "./TechStack";
import LangSelect from "./LangSelect";
import Mail from "./Mail";
import Switch from "./Switch";
import Navigation from "./Navigation";
import LinkedInIcon from "../assets/icons/socials/linkedin.svg?react";
import GitHubIcon from "../assets/icons/socials/square-github.svg?react";
import Location from "./Location";
import "animate.css";
import { useState } from "react";
const Home = () => {
const [hoverAnimation, setHoverAnimation] = useState("animate__headShake");
const handleMouseEnter = (setAnimation) => {
setAnimation(hoverAnimation); // Trigger hover animation
};
const handleAnimationEnd = (setAnimation) => {
setAnimation(""); // Clear animation to prevent re-triggering
};
return (
<div className="gridContainer">
<Hero />
<Hero
initialAnimation="animate__flipInX"
onMouseEnter={handleMouseEnter}
onAnimationEnd={handleAnimationEnd}
/>
<TechStack
initialAnimation="animate__backInLeft"
onMouseEnter={handleMouseEnter}
onAnimationEnd={handleAnimationEnd}
/>
<LangSelect />
<Mail />
<Switch />
<Navigation />
<div className="linkedIn container">
<LinkedInIcon className="linkedInIcon" />
</div>
<div className="github container">
<GitHubIcon className="githubIcon" />
</div>
<Location />
</div>
);
};

View File

@@ -0,0 +1,8 @@
import React from "react";
import "../css/LangSelect.css";
const LangSelect = () => {
return <div className="langSelect container">LangSelect</div>;
};
export default LangSelect;

View File

@@ -0,0 +1,8 @@
import React from "react";
import "../css/Location.css";
const Location = () => {
return <div className="location container">Location</div>;
};
export default Location;

8
src/components/Mail.jsx Normal file
View File

@@ -0,0 +1,8 @@
import React from "react";
import "../css/Mail.css";
const Mail = () => {
return <div className="eMail container">Mail</div>;
};
export default Mail;

View File

@@ -0,0 +1,8 @@
import React from "react";
import "../css/Navigation.css";
const Navigation = () => {
return <div className="navigation container">Nav</div>;
};
export default Navigation;

View File

@@ -0,0 +1,8 @@
import React from "react";
import "../css/Switch.css";
const Switch = () => {
return <div className="switch container">Switch</div>;
};
export default Switch;

View File

@@ -0,0 +1,68 @@
import React, { useState } from "react";
import ReactIcon from "../assets/icons/skill-icons/icons/React-Dark.svg?react";
import NodeIcon from "../assets/icons/skill-icons/icons/NodeJS-Dark.svg?react";
import MongoIcon from "../assets/icons/skill-icons/icons/MongoDB.svg?react";
import RailsIcon from "../assets/icons/skill-icons/icons/Rails.svg?react";
import NextJsIcon from "../assets/icons/skill-icons/icons/NextJS-Dark.svg?react";
import DockerIcon from "../assets/icons/skill-icons/icons/Docker.svg?react";
import TypeScriptIcon from "../assets/icons/skill-icons/icons/TypeScript.svg?react";
import ExpressIcon from "../assets/icons/skill-icons/icons/ExpressJS-Dark.svg?react";
import "../css/TechStack.css";
import { Link } from "react-router-dom";
import "animate.css";
const TechStack = ({ initialAnimation, onMouseEnter, onAnimationEnd }) => {
const techStack = [
{ name: "React", component: ReactIcon, className: "reactIcon", id: 1 },
{ name: "Node.js", component: NodeIcon, className: "nodeIcon", id: 2 },
{ name: "MongoDB", component: MongoIcon, className: "mongoIcon", id: 3 },
{
name: "Ruby on Rails",
component: RailsIcon,
className: "railsIcon",
id: 4,
},
{ name: "Next.js", component: NextJsIcon, className: "nextJsIcon", id: 5 },
{ name: "Docker", component: DockerIcon, className: "dockerIcon", id: 6 },
{
name: "TypeScript",
component: TypeScriptIcon,
className: "typescriptIcon",
id: 7,
},
{
name: "Express.js",
component: ExpressIcon,
className: "expressIcon",
id: 8,
},
];
/* Animations */
const [animation, setAnimation] = useState(initialAnimation);
return (
<div
className={`techStackContainer container animate__animated ${animation}`}
onMouseEnter={() => onMouseEnter(setAnimation)}
onAnimationEnd={() => onAnimationEnd(setAnimation)}
>
<h2>Tech Stack</h2>
<div className="techStack">
{techStack.map((tech) => {
const IconComponent = tech.component;
return (
<div key={tech.id} className="techStackItem">
<IconComponent className={`techIcon ${tech.className}`} />
</div>
);
})}
</div>
<Link to={"/"} className="techStackShowMore">
Show More
</Link>
</div>
);
};
export default TechStack;

View File

@@ -1,17 +0,0 @@
import React from "react";
import "../../css/Hero.css";
const Hero = () => {
return (
<div className="hero">
<p>
<span>
Hi, I'm Yousif. <br />
</span>{" "}
I'm a Full-Stack Developer from Germany.
</p>
</div>
);
};
export default Hero;

View File

@@ -1,9 +1,10 @@
.hero {
grid-area: 1 / 1 / 5 / 5;
background-color: #28272a;
padding: 2rem;
border-radius: 1rem;
border: 0.5px solid rgb(73, 73, 73);
grid-area: 1 / 1 / 4 / 5;
animation-duration: 1.5s;
}
.hero:hover {
animation-duration: .5s;
}
.hero p span {

View File

@@ -1,8 +1,56 @@
.gridContainer {
display: grid;
grid-template-columns: repeat(9, 1fr);
grid-template-columns: repeat(11, 1fr);
grid-template-rows: repeat(9, 1fr);
gap: 10px;
width: 50%;
height: 80%;
}
.container {
background-color: #28272a;
padding: 2rem;
border-radius: 1rem;
border: 0.5px solid rgb(73, 73, 73);
}
.container:hover {
cursor: pointer;
}
h2 {
color: white;
}
.linkedIn {
grid-area: 8 / 5 / 10 / 7;
background-color: #001d2c;
border: 1px solid #0072b1;
}
.linkedInIcon {
fill: #0072b1;
}
.githubIcon {
fill: black;
}
.github {
grid-area: 8 / 7 / 10 / 9;
background-color: #333;
}
.linkedIn,
.github {
display: flex;
justify-content: center;
align-items: center;
}
.langSelect,
.eMail,
.switch {
animation: zoomIn;
animation-duration: 1s;
}

3
src/css/LangSelect.css Normal file
View File

@@ -0,0 +1,3 @@
.langSelect {
grid-area: 8 / 1 / 9 / 4;
}

3
src/css/Location.css Normal file
View File

@@ -0,0 +1,3 @@
.location {
grid-area: 9 / 9 / 10 / 12;
}

3
src/css/Mail.css Normal file
View File

@@ -0,0 +1,3 @@
.eMail {
grid-area: 9 / 1 / 10 / 4;
}

3
src/css/Navigation.css Normal file
View File

@@ -0,0 +1,3 @@
.navigation {
grid-area: 1 / 9 / 9 / 12;
}

3
src/css/Switch.css Normal file
View File

@@ -0,0 +1,3 @@
.switch {
grid-area: 8 / 4 / 10 / 5;
}

53
src/css/TechStack.css Normal file
View File

@@ -0,0 +1,53 @@
.techStackContainer {
grid-area: 4 / 1 / 8 / 5;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
animation-duration: 1s;
}
.techStackContainer:hover {
animation-duration: 0.5s;
}
.techStackContainer h2 {
margin-bottom: 10px;
align-self: flex-start;
}
.techIcon {
width: 4rem;
height: 4rem;
filter: grayscale(0.7);
transition: transform 0.3s ease, filter 0.3s ease;
}
.techIcon:hover {
filter: none;
animation: tada 1s;
cursor: pointer;
}
.techStack {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
gap: 10px;
margin-bottom: 1rem;
}
.techStackShowMore {
font-size: 1.2rem;
color: rgb(151, 151, 151);
text-decoration: none;
border-bottom: 1px solid rgb(151, 151, 151);
/* align-self: flex-start; */
}
@keyframes techIconHover {
10% {
transform: scale();
}
}