Added Project element with its underlying topics. Reworked some elements on post-min and pill.
This commit is contained in:
parent
3ac5290cbe
commit
03fdee90c9
13 changed files with 333 additions and 32 deletions
|
@ -76,7 +76,7 @@
|
|||
animateForeground(false, navbar_title);
|
||||
}}
|
||||
>
|
||||
<div class="navbar-title content">
|
||||
<div class="navbar-title navbar-content">
|
||||
<h1 class="title">Etheryo</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -94,7 +94,7 @@
|
|||
animateForeground(false, navbar_category);
|
||||
}}
|
||||
>
|
||||
<div class="content navbar-categories">
|
||||
<div class="navbar-content navbar-categories">
|
||||
<div>
|
||||
<a class={isActive("/", pageUrl)} href="/">{mainjson.tab.hub}</a>
|
||||
</div>
|
||||
|
|
|
@ -2,11 +2,13 @@
|
|||
import "$lib/css/person.css";
|
||||
import Button from "$lib/components/button.svelte";
|
||||
|
||||
import hubjson from "$lib/json/hub.json";
|
||||
|
||||
export let picture;
|
||||
export let name = "John Doe";
|
||||
export let pronouns = "";
|
||||
export let description = "Normal human being I swear";
|
||||
export let url = "https://github.com"
|
||||
export let url = "https://github.com";
|
||||
</script>
|
||||
|
||||
<div class="flex center">
|
||||
|
@ -23,7 +25,12 @@
|
|||
</div>
|
||||
<p>{description}</p>
|
||||
<div class="flex-row flex-end">
|
||||
<Button label="Me connaître" action={() => {window.location.href = url;}} />
|
||||
<Button
|
||||
label={hubjson.person.knowme}
|
||||
action={() => {
|
||||
window.location.href = url;
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import anime from "animejs";
|
||||
|
||||
export let cover =
|
||||
"https://share.etheryo.fr/Rando-01.11.2023/Alix%20Mange%20Lac%20Rouge%20Bleu%20Orange%20Midi.jpg";
|
||||
"https://share.etheryo.fr/rando/2024.07.28/IMG20240728142327.jpg";
|
||||
export let title = "Title";
|
||||
export let date = "01/01/1997";
|
||||
|
||||
|
|
105
src/lib/components/project.svelte
Normal file
105
src/lib/components/project.svelte
Normal file
|
@ -0,0 +1,105 @@
|
|||
<script>
|
||||
import "$lib/css/base.css";
|
||||
import "$lib/css/pill.css";
|
||||
import "$lib/css/project.css";
|
||||
import "$lib/css/post-min.css";
|
||||
|
||||
import topics from "$lib/ts/topic.ts";
|
||||
|
||||
import SvgIcon from "@jamescoyle/svelte-icon";
|
||||
import { mdiChevronRight } from "@mdi/js";
|
||||
import anime from "animejs";
|
||||
|
||||
export let cover =
|
||||
"https://share.etheryo.fr/rando/2024.07.28/IMG20240728142327.jpg";
|
||||
export let title = "Title";
|
||||
export let description =
|
||||
"This is a description, you can add some explaination to your project in here! It can always be interesting to talk about some subtext before going into the subject!";
|
||||
export let topic = topics.embedded;
|
||||
|
||||
let post_div;
|
||||
let chevron_div;
|
||||
let title_h1;
|
||||
let cursorX = 0;
|
||||
let cursorY = 0;
|
||||
let updateY = true;
|
||||
|
||||
function update_gradient(event, div) {
|
||||
const rect = div.getBoundingClientRect();
|
||||
if (updateY) {
|
||||
cursorY = event.clientY - rect.top;
|
||||
}
|
||||
cursorX = event.clientX - rect.left;
|
||||
post_div.style.backgroundImage = `radial-gradient(circle farthest-corner at ${Math.floor(cursorX)}px ${Math.floor(cursorY)}px, var(--color-background) 0%, #958a98 100%)`;
|
||||
}
|
||||
|
||||
function animateForeground(isEntering, div_back) {
|
||||
const targetOpacity = isEntering ? 1 : 0;
|
||||
|
||||
anime({
|
||||
targets: div_back,
|
||||
opacity: [1 - targetOpacity, targetOpacity],
|
||||
duration: 400,
|
||||
easing: "easeInOutQuad",
|
||||
});
|
||||
}
|
||||
|
||||
function animateChevron(isEntering) {
|
||||
let opacity = [0, 1];
|
||||
let translateX = [-20, 0];
|
||||
|
||||
if (!isEntering) {
|
||||
opacity.reverse();
|
||||
translateX.reverse();
|
||||
}
|
||||
|
||||
anime({
|
||||
targets: chevron_div,
|
||||
opacity: opacity,
|
||||
translateX: translateX,
|
||||
duration: 300,
|
||||
easing: "easeOutQuad",
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
role="button"
|
||||
tabindex="0"
|
||||
class="project-container"
|
||||
on:mousemove={(event) => {
|
||||
update_gradient(event, post_div);
|
||||
}}
|
||||
on:mouseenter={() => {
|
||||
animateForeground(true, post_div);
|
||||
animateChevron(true);
|
||||
title_h1.style.textDecoration = "underline 2px";
|
||||
}}
|
||||
on:mouseleave={() => {
|
||||
animateForeground(false, post_div);
|
||||
animateChevron(false);
|
||||
title_h1.style.textDecoration = "";
|
||||
}}
|
||||
>
|
||||
<div class="project text-justify">
|
||||
<img
|
||||
alt="imgcool"
|
||||
src={cover}
|
||||
on:mouseenter={() => (updateY = false)}
|
||||
on:mouseleave={() => (updateY = true)}
|
||||
/>
|
||||
<h1 bind:this={title_h1}>{title}</h1>
|
||||
<p>{description}</p>
|
||||
<div class="flex-row text-justify margin-bot-force">
|
||||
<div class="pill project-pill">
|
||||
<SvgIcon type="mdi" path={topic[1]}></SvgIcon>
|
||||
<span>{topic[0]}</span>
|
||||
</div>
|
||||
<div class="flex-end project-next" bind:this={chevron_div}>
|
||||
<SvgIcon type="mdi" path={mdiChevronRight} size={35}></SvgIcon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="post-min-overlay-front"></div>
|
||||
<div class="post-min-overlay-back" bind:this={post_div}></div>
|
||||
</div>
|
|
@ -53,6 +53,8 @@ h2 {
|
|||
--border-max: 2rem;
|
||||
--profile-content-width-max: 40rem;
|
||||
--profile-content-width-min: 36rem;
|
||||
--content-width: 50rem;
|
||||
--content-height: 50rem;
|
||||
|
||||
--width-min-desktop: 1275px;
|
||||
--width-mobile: 875px;
|
||||
|
@ -102,6 +104,10 @@ h2 {
|
|||
margin: 2rem;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: var(--content-width);
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
@ -125,6 +131,10 @@ h2 {
|
|||
box-shadow: #41354340 0px 8px 18px -1px;
|
||||
}
|
||||
|
||||
.w-100 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.h-100 {
|
||||
height: 100%;
|
||||
}
|
||||
|
@ -180,6 +190,10 @@ h2 {
|
|||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.margin-bot-force {
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
.padding-left-3 {
|
||||
padding-left: 3rem;
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ a {
|
|||
outline: var(--navbar-outline)
|
||||
}
|
||||
|
||||
.content {
|
||||
.navbar-content {
|
||||
grid-area: overlay;
|
||||
z-index: 1;
|
||||
width: inherit;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
}
|
||||
|
||||
.person-container {
|
||||
width: 50rem;
|
||||
width: 100%;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,16 +21,6 @@
|
|||
margin-right: 1rem !important;
|
||||
}
|
||||
|
||||
.pill svg {
|
||||
border-radius: 100% !important;
|
||||
width: 1.8rem !important;
|
||||
height: 1.8rem !important;
|
||||
padding: calc((3rem - 1.8rem)/2);
|
||||
color: var(--color-background);
|
||||
background: linear-gradient(180deg, rgb(52, 42, 58), rgb(38, 28, 44));
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.pill-profile {
|
||||
transition: all .4s ease 0s;
|
||||
}
|
||||
|
|
12
src/lib/css/post-min.css
vendored
12
src/lib/css/post-min.css
vendored
|
@ -90,12 +90,16 @@
|
|||
margin-top: auto !important;
|
||||
}
|
||||
|
||||
.post-min-pill span {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.post-min-pill svg {
|
||||
border-radius: 100% !important;
|
||||
width: 1.2rem !important;
|
||||
height: 1.2rem !important;
|
||||
padding: calc((2rem - 1.2rem)/2);
|
||||
color: var(--color-background);
|
||||
background: linear-gradient(180deg, rgb(52, 42, 58), rgb(38, 28, 44));
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.post-min-pill span {
|
||||
font-size: 0.8rem;
|
||||
}
|
127
src/lib/css/project.css
Normal file
127
src/lib/css/project.css
Normal file
|
@ -0,0 +1,127 @@
|
|||
|
||||
|
||||
@media screen and (max-width: 1275px) {
|
||||
.project-container {
|
||||
height: calc(var(--content-height)/2);
|
||||
width: calc((var(--content-width) + 6rem - 4rem)/3);
|
||||
}
|
||||
|
||||
.project {
|
||||
height: calc(var(--content-height)/2);
|
||||
}
|
||||
|
||||
.project img {
|
||||
height: calc(var(--content-height)/5);
|
||||
width: calc(var(--content-width)/4);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1276px) {
|
||||
.project-container {
|
||||
height: calc(var(--content-height)/2);
|
||||
width: calc((var(--content-width) + 6rem - 4rem)/3);
|
||||
}
|
||||
|
||||
.project {
|
||||
height: calc(var(--content-height)/2);
|
||||
}
|
||||
|
||||
.project img {
|
||||
height: calc(var(--content-height)/5);
|
||||
width: calc(var(--content-width)/4);
|
||||
}
|
||||
}
|
||||
|
||||
.project-container {
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"post-min-overlay-back"
|
||||
"post-min-overlay-front"
|
||||
"project";
|
||||
margin-left: 1rem;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.project {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
grid-area: overlay;
|
||||
z-index: var(--z-index-front);
|
||||
}
|
||||
|
||||
.project img {
|
||||
width: auto;
|
||||
width: 100%;
|
||||
object-fit: cover;
|
||||
border-top-left-radius: 1rem;
|
||||
border-top-right-radius: 1rem;
|
||||
border-bottom-left-radius: 0.6rem;
|
||||
border-bottom-right-radius: 0.6rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.project h1 {
|
||||
font-family: 'JetBrains Mono';
|
||||
font-weight: 800;
|
||||
font-size: 1.1rem;
|
||||
margin-left: 1rem;
|
||||
margin-right: 1rem;
|
||||
margin-bottom: 0;
|
||||
user-select: none;
|
||||
/* Overflow */
|
||||
overflow: hidden;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
text-overflow: ellipsis;
|
||||
-webkit-line-clamp: 2;
|
||||
line-clamp: 2;
|
||||
}
|
||||
|
||||
.project p {
|
||||
font-family: 'JetBrains Mono';
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
font-size: 0.9rem;
|
||||
margin-left: 1rem;
|
||||
margin-right: 1rem;
|
||||
/* Overflow */
|
||||
overflow: hidden;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
text-overflow: ellipsis;
|
||||
-webkit-line-clamp: 4;
|
||||
line-clamp: 4;
|
||||
}
|
||||
|
||||
.project span {
|
||||
font-family: 'JetBrains Mono';
|
||||
color: var(--color-background);
|
||||
margin: 0.7rem;
|
||||
padding: 0;
|
||||
|
||||
}
|
||||
|
||||
.project-pill {
|
||||
background-color: var(--color-text);
|
||||
margin-bottom: 0.5rem;
|
||||
width: fit-content;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.project-pill svg {
|
||||
border-radius: 100% !important;
|
||||
padding: calc((2rem - 1.2rem)/2);
|
||||
padding-right: 0;
|
||||
color: var(--color-background);
|
||||
}
|
||||
|
||||
.project-next {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.project-next svg {
|
||||
color: var(--color-text);
|
||||
margin-right: 0.5rem;
|
||||
|
||||
}
|
|
@ -5,7 +5,28 @@
|
|||
"person": {
|
||||
"name": "Yohan Boujon",
|
||||
"pronouns": "il/lui",
|
||||
"description": "Informatics and electronics engineer"
|
||||
"description": "Informatics and electronics engineer",
|
||||
"knowme": "Me Connaître"
|
||||
},
|
||||
"projects":"Mes projets"
|
||||
"project":"Mes projets",
|
||||
"projects": [
|
||||
{
|
||||
"cover": "https://share.etheryo.fr/INSA/wal/wal.png",
|
||||
"title": "What A Leak!",
|
||||
"description": "Water leak detection project with INSA Toulouse in 5th year.",
|
||||
"topic": "embedded"
|
||||
},
|
||||
{
|
||||
"cover": "https://share.etheryo.fr/projects/shared-memory/config.png",
|
||||
"title": "Shared memory cache on multiple kernels",
|
||||
"description": "Using NFS, programmed a kernel driver that can read/write data onto a shared ram.",
|
||||
"topic": "kernel"
|
||||
},
|
||||
{
|
||||
"cover": "https://share.etheryo.fr/projects/yoyo_tetris/yoyotetris.png",
|
||||
"title": "yoyoTetris",
|
||||
"description": "A simple game in C++ using Raylib.",
|
||||
"topic": "videogame"
|
||||
}
|
||||
]
|
||||
}
|
13
src/lib/ts/topic.ts
Normal file
13
src/lib/ts/topic.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
import { mdiMemory, mdiPenguin, mdiGamepadVariant } from "@mdi/js";
|
||||
|
||||
type TopicKey = "embedded" | "kernel" | "videogame";
|
||||
|
||||
type Topic = [string, string];
|
||||
|
||||
const topics: Record<TopicKey, Topic> = {
|
||||
embedded: ["Embedded", mdiMemory],
|
||||
kernel: ["Kernel Dev", mdiPenguin],
|
||||
videogame: ["Video Game", mdiGamepadVariant],
|
||||
};
|
||||
|
||||
export default topics;
|
|
@ -4,6 +4,10 @@
|
|||
|
||||
import CoverImg from "$lib/components/cover-img.svelte";
|
||||
import Person from "$lib/components/person.svelte";
|
||||
import Project from "$lib/components/project.svelte";
|
||||
|
||||
import topics from "$lib/ts/topic.ts";
|
||||
|
||||
import hubjson from "$lib/json/hub.json";
|
||||
|
||||
let hub_cover =
|
||||
|
@ -23,14 +27,30 @@
|
|||
<div class="section">
|
||||
<h1>{hubjson.who}</h1>
|
||||
</div>
|
||||
<Person
|
||||
picture={profile_pic}
|
||||
name={hubjson.person.name}
|
||||
pronouns={hubjson.person.pronouns}
|
||||
description={hubjson.person.description}
|
||||
url="/about"
|
||||
/>
|
||||
<div class="flex w-100 justify-center">
|
||||
<div class="content">
|
||||
<Person
|
||||
picture={profile_pic}
|
||||
name={hubjson.person.name}
|
||||
pronouns={hubjson.person.pronouns}
|
||||
description={hubjson.person.description}
|
||||
url="/about"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h1>{hubjson.projects}</h1>
|
||||
<h1>{hubjson.project}</h1>
|
||||
</div>
|
||||
<div class="flex w-100 justify-center">
|
||||
<div class="content flex-row center">
|
||||
{#each hubjson.projects as project, index}
|
||||
<Project
|
||||
cover={hubjson.projects[index].cover}
|
||||
title={hubjson.projects[index].title}
|
||||
description={hubjson.projects[index].description}
|
||||
topic={topics[hubjson.projects[index].topic]}
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Reference in a new issue