created animation + hoverAnimation helperFunction. Also Hero + Techstack (prev) styled and animated.
This commit is contained in:
@@ -4,4 +4,5 @@ main {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
1
src/assets/icons/socials/linkedin.svg
Normal file
1
src/assets/icons/socials/linkedin.svg
Normal 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 |
1
src/assets/icons/socials/square-github.svg
Normal file
1
src/assets/icons/socials/square-github.svg
Normal 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
24
src/components/Hero.jsx
Normal 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;
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
8
src/components/LangSelect.jsx
Normal file
8
src/components/LangSelect.jsx
Normal 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;
|
||||
8
src/components/Location.jsx
Normal file
8
src/components/Location.jsx
Normal 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
8
src/components/Mail.jsx
Normal 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;
|
||||
8
src/components/Navigation.jsx
Normal file
8
src/components/Navigation.jsx
Normal 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;
|
||||
8
src/components/Switch.jsx
Normal file
8
src/components/Switch.jsx
Normal 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;
|
||||
68
src/components/TechStack.jsx
Normal file
68
src/components/TechStack.jsx
Normal 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;
|
||||
@@ -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;
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
3
src/css/LangSelect.css
Normal file
@@ -0,0 +1,3 @@
|
||||
.langSelect {
|
||||
grid-area: 8 / 1 / 9 / 4;
|
||||
}
|
||||
3
src/css/Location.css
Normal file
3
src/css/Location.css
Normal file
@@ -0,0 +1,3 @@
|
||||
.location {
|
||||
grid-area: 9 / 9 / 10 / 12;
|
||||
}
|
||||
3
src/css/Mail.css
Normal file
3
src/css/Mail.css
Normal file
@@ -0,0 +1,3 @@
|
||||
.eMail {
|
||||
grid-area: 9 / 1 / 10 / 4;
|
||||
}
|
||||
3
src/css/Navigation.css
Normal file
3
src/css/Navigation.css
Normal file
@@ -0,0 +1,3 @@
|
||||
.navigation {
|
||||
grid-area: 1 / 9 / 9 / 12;
|
||||
}
|
||||
3
src/css/Switch.css
Normal file
3
src/css/Switch.css
Normal file
@@ -0,0 +1,3 @@
|
||||
.switch {
|
||||
grid-area: 8 / 4 / 10 / 5;
|
||||
}
|
||||
53
src/css/TechStack.css
Normal file
53
src/css/TechStack.css
Normal 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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user