Add animated menu cards
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
|
||||
<link rel="stylesheet" href="./styles/style.css">
|
||||
<link rel="stylesheet" href="./styles/introduction.css">
|
||||
<link rel="stylesheet" href="./styles/projects.css">
|
||||
<link rel="stylesheet" href="styles/projects.css">
|
||||
|
||||
<title>Naaturel</title>
|
||||
|
||||
@@ -32,7 +32,34 @@
|
||||
</section>
|
||||
|
||||
<section id="projects">
|
||||
<div class="content">
|
||||
<div class="card-list">
|
||||
<a>
|
||||
<div class="card">
|
||||
<h2>My <span class="accentuated">projects</span></h2>
|
||||
<hr/>
|
||||
<p>Get a look at what I've worked on</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a>
|
||||
<div class="card">
|
||||
<h2><span class="accentuated">About</span> me</h2>
|
||||
<hr/>
|
||||
<p>Learn more about my skills and background</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a>
|
||||
<div class="card">
|
||||
<h2><span class="accentuated">Contacts</span></h2>
|
||||
<hr/>
|
||||
<p>Get in touch with me</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
<!--<div class="content">
|
||||
<div >
|
||||
<h1>Live projects</h1>
|
||||
<hr/>
|
||||
@@ -54,7 +81,7 @@
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>-->
|
||||
</section>
|
||||
|
||||
</main>
|
||||
@@ -71,4 +98,14 @@
|
||||
typer.start();
|
||||
</script>
|
||||
|
||||
|
||||
<script type="module">
|
||||
import {CardTilter} from "./scripts/CardTilter.js";
|
||||
|
||||
const cards = document.querySelectorAll('.card');
|
||||
|
||||
cards.forEach(card => { new CardTilter({card : card, tilt : 15, perspective : 650}) })
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
||||
10
html/projects.html
Normal file
10
html/projects.html
Normal file
@@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
48
html/scripts/CardTilter.js
Normal file
48
html/scripts/CardTilter.js
Normal file
@@ -0,0 +1,48 @@
|
||||
export class CardTilter {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param card Card to be moved
|
||||
* @param tilt max tilting angle in degree
|
||||
* @param perspective perspective in pixels
|
||||
*/
|
||||
constructor({card : card, tilt : tilt, perspective : perspective}) {
|
||||
this.card = card;
|
||||
this.tilt = tilt;
|
||||
this.perspective = perspective;
|
||||
this.watch()
|
||||
}
|
||||
|
||||
watch(){
|
||||
this.card.addEventListener('mousemove', (e) => {
|
||||
const rotations = this.calculatePositions(e.clientX, e.clientY);
|
||||
this.transform(rotations.x, rotations.y);
|
||||
});
|
||||
|
||||
this.card.addEventListener('mouseleave', () => {
|
||||
this.reset();
|
||||
});
|
||||
}
|
||||
|
||||
calculatePositions(cursorX, cursorY) {
|
||||
const rect = this.card.getBoundingClientRect();
|
||||
const x = cursorX - rect.left;
|
||||
const y = cursorY - rect.top;
|
||||
|
||||
const percentX = (x / rect.width) - 0.5;
|
||||
const percentY = (y / rect.height) - 0.5;
|
||||
|
||||
const rotateX = -percentY * this.tilt;
|
||||
const rotateY = percentX * this.tilt;
|
||||
|
||||
return {x : rotateX, y : rotateY};
|
||||
};
|
||||
|
||||
transform(rotationX, rotationY) {
|
||||
this.card.style.transform = `translateY(-10px) perspective(${this.perspective}px) rotateX(${rotationX}deg) rotateY(${rotationY}deg) scale(1.05)`;
|
||||
}
|
||||
|
||||
reset(){
|
||||
this.card.style.transform = `rotateX(0deg) rotateY(0deg) scale(1)`;
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,47 @@ hr {
|
||||
animation: blink 800ms infinite;
|
||||
}
|
||||
|
||||
.card-list
|
||||
{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: start;
|
||||
gap: 15px;
|
||||
min-width: 375px;
|
||||
height: 75%;
|
||||
overflow: scroll;
|
||||
padding: 0 20px 0 20px;
|
||||
}
|
||||
|
||||
.card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: start;
|
||||
align-items: center;
|
||||
|
||||
height: 350px;
|
||||
width: 275px;
|
||||
|
||||
background: white;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
|
||||
|
||||
padding: 15px;
|
||||
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.card p
|
||||
{
|
||||
opacity: 0.65;
|
||||
}
|
||||
|
||||
|
||||
@keyframes blink {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
|
||||
@@ -1,75 +1,9 @@
|
||||
#projects .content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-around;
|
||||
align-items: start;
|
||||
width: 75%;
|
||||
}
|
||||
#projects .content div hr {
|
||||
margin : 25px 0 25px 0;
|
||||
}
|
||||
|
||||
|
||||
.project-list, .links {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap : 1rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.project-list img {
|
||||
width: 215px;
|
||||
border : solid 1px black;
|
||||
border-radius: 15px;
|
||||
transition: transform 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.project-list img:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
|
||||
.links {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
||||
.links ul {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 40px;
|
||||
padding : 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.links ul li {
|
||||
#projects {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
padding: 0.5rem 1rem;
|
||||
border-radius: 10px;
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
.links ul li:hover {
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
|
||||
.links ul li::before {
|
||||
content: ">";
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.links ul li:hover::before {
|
||||
animation: blink 1s step-start infinite;
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
50% {
|
||||
opacity: 0;
|
||||
}
|
||||
justify-content: center;
|
||||
width: 95%;
|
||||
height: 95%;
|
||||
}
|
||||
|
||||
|
||||
76
html/styles/projects.css.bak
Normal file
76
html/styles/projects.css.bak
Normal file
@@ -0,0 +1,76 @@
|
||||
#projects .content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-around;
|
||||
align-items: start;
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
#projects .content div hr {
|
||||
margin : 25px 0 25px 0;
|
||||
}
|
||||
|
||||
|
||||
.project-list, .links {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap : 1rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.project-list img {
|
||||
width: 215px;
|
||||
border : solid 1px black;
|
||||
border-radius: 15px;
|
||||
transition: transform 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.project-list img:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
|
||||
.links {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
||||
.links ul {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 40px;
|
||||
padding : 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.links ul li {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
padding: 0.5rem 1rem;
|
||||
border-radius: 10px;
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
.links ul li:hover {
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
|
||||
.links ul li::before {
|
||||
content: ">";
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.links ul li:hover::before {
|
||||
animation: blink 1s step-start infinite;
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
50% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
:root {
|
||||
|
||||
--primary-color: #3dae15;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
@@ -13,8 +13,8 @@
|
||||
}
|
||||
|
||||
html, body {
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
height: 100dvh;
|
||||
width: 100dvw;
|
||||
}
|
||||
|
||||
html, body, main, section, section div, footer {
|
||||
@@ -58,3 +58,7 @@ ul li{
|
||||
ul li a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.accentuated {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
Reference in New Issue
Block a user