Not finished | Start at: Mar 6, 2023
This is a landing page for a Design Portfolio website designed to showcase a mock project for a design agency with a focus on people and their unique experiences, The goal of this project is to create a visually appealing and responsive landing page that highlights the concept of a modern portfolio. The page includes interactive elements and modern UI/UX design principles.
- live site link
- Elvina Prasad – Portfolio - Inspired by it.
- CSS Single Element Goey Spinner - website loader.
- Unsplash (website images)
- jordy_munoz
- chi_lok_tsang
- amritansh_dubey
- rafael_hoyos_weht
- HTML
- CSS
- JS
- Sass - CSS extension language.
- React - JS library.
- Vite - JS bundling tool.
- Gsap - JS animation tool.
- lenis - smooth scrolling.
- react-hot-toast - React notifications.
- blurhash - image blur.
Open Graph Meta Tags
<meta name="twitter:card" content="" />
<meta name="twitter:title" content="" />
<meta name="twitter:description" content="" />
<meta name="twitter:image" content="" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://ymhaah.github.io/NPFF-Agency/" />
<meta property="og:title" content="" />
<meta property="og:image" content="" />
<meta property="og:description" content="" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
HTML <noscript>
Tag
<noscript>
<div class="no-script">
<p>Please enable JavaScript to view this website.</p>
</div>
</noscript>
HTML nomodule
attribute for script elements
<script nomodule="">
var div = document.createElement("div");
var p = document.createElement("P");
div.classList.add("old-script");
p.textContent =
"Please update your browser to modern version to view this website.";
div.appendChild(p);
document.body.appendChild(div);
</script>
jsconfig file
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"allowSyntheticDefaultImports": true,
"baseUrl": "./",
"paths": {
"@ui/*": ["./src/components/uiComponents/*"],
"@comp/*": ["./src/components/*"]
}
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}
Self-hosting fonts with @font-face
@font-face {
font-family: "Mosk";
font-weight: 200;
font-style: normal;
font-display: swap;
src: url("./assets/fonts/Mosk/Extra-Light_200.woff2") format("woff2"), url("./assets/fonts/Mosk/Extra-Light_200.woff")
format("woff"),
url("./assets/fonts/Mosk/Extra-Light_200.ttf") format("truetype");
}
mix-blend-mode
h1 {
mix-blend-mode: difference;
}
text-wrap
:where(h1, h2, h3, h4) {
text-wrap: balance;
}
Make elements follow rounded corners with CSS cos() & sin()
.circle {
--circle-size: ;
--sons-size: ;
--circle-radius: calc(calc(var(--circle-size) - var(--sons-size)) / 2);
--son-deg: calc(360deg / #{$son-num});
width: var(--circle-size);
height: var(--circle-size);
position: relative;
@for $inti from 1 to $son-num + 1 {
& :nth-child(#{$inti}) {
--deg: calc(var(--son-deg) * #{$inti});
}
}
span {
--X: calc(
var(--circle-radius) + (var(--circle-radius) * cos(var(--deg)))
);
--Y: calc(
var(--circle-radius) + (var(--circle-radius) * sin(var(--deg)))
);
width: var(--sons-size);
height: var(--sons-size);
position: absolute;
top: var(--Y);
left: var(--X);
margin: 0;
}
}
useMousePosition react hook to get mouse position
export default function useMousePosition(handleMouseFun, isUsingGsap = true) {
const [mousePos, setMousePos] = useState({ x: 0, y: 0 });
if (isUsingGsap) {
import("gsap");
}
useEffect(() => {
const handleMouseMove = (event) => {
setMousePos({ x: event.clientX, y: event.clientY });
};
window.addEventListener("mousemove", handleMouseMove);
handleMouseFun(mousePos.x, mousePos.y);
return () => {
window.removeEventListener("mousemove", handleMouseMove);
};
}, [mousePos]);
useDebugValue(mousePos);
return mousePos;
}
useGsap to use gsap with the gsap.context
in react
export default function useGsap(animation, father) {
useLayoutEffect(() => {
let ctx = gsap.context(() => {
animation();
}, father);
return () => ctx.revert();
}, []);
}
react image component for image with blurhash
function Image({
className = "",
src,
webp,
hash,
id = null,
loaded,
alt = "",
}) {
const [imgLoaded, setImgLoaded] = useState(false);
let image = useRef(null);
return (
<div className={`image ${className}`}>
{hash && (
<div
className="blur"
style={{
display: !imgLoaded ? "inline" : "none",
}}
aria-hidden={imgLoaded}
>
<Blurhash hash={hash} />
</div>
)}
<picture>
{webp && <source type="image/webp" srcSet={webp} />}
<img
ref={image}
src={src}
onLoad={() => {
setImgLoaded(true);
loaded && loaded(true);
}}
style={{
display: imgLoaded ? "block" : "none",
}}
alt={alt}
aria-label={alt}
id={id}
role="img"
/>
</picture>
</div>
);
}
- more gsap & scrollTrigger
Check out my latest previous articles:
- Top 5 websites to sharpen your front-end skills.
- How To Build An Advanced Light/Dark Theme Website!
- 30-Day React Learning Journey!
- professional links:
- Hire me:
- Blog: