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);
|
animateForeground(false, navbar_title);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div class="navbar-title content">
|
<div class="navbar-title navbar-content">
|
||||||
<h1 class="title">Etheryo</h1>
|
<h1 class="title">Etheryo</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -94,7 +94,7 @@
|
||||||
animateForeground(false, navbar_category);
|
animateForeground(false, navbar_category);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div class="content navbar-categories">
|
<div class="navbar-content navbar-categories">
|
||||||
<div>
|
<div>
|
||||||
<a class={isActive("/", pageUrl)} href="/">{mainjson.tab.hub}</a>
|
<a class={isActive("/", pageUrl)} href="/">{mainjson.tab.hub}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,11 +2,13 @@
|
||||||
import "$lib/css/person.css";
|
import "$lib/css/person.css";
|
||||||
import Button from "$lib/components/button.svelte";
|
import Button from "$lib/components/button.svelte";
|
||||||
|
|
||||||
|
import hubjson from "$lib/json/hub.json";
|
||||||
|
|
||||||
export let picture;
|
export let picture;
|
||||||
export let name = "John Doe";
|
export let name = "John Doe";
|
||||||
export let pronouns = "";
|
export let pronouns = "";
|
||||||
export let description = "Normal human being I swear";
|
export let description = "Normal human being I swear";
|
||||||
export let url = "https://github.com"
|
export let url = "https://github.com";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex center">
|
<div class="flex center">
|
||||||
|
@ -23,7 +25,12 @@
|
||||||
</div>
|
</div>
|
||||||
<p>{description}</p>
|
<p>{description}</p>
|
||||||
<div class="flex-row flex-end">
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
import anime from "animejs";
|
import anime from "animejs";
|
||||||
|
|
||||||
export let cover =
|
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 title = "Title";
|
||||||
export let date = "01/01/1997";
|
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;
|
--border-max: 2rem;
|
||||||
--profile-content-width-max: 40rem;
|
--profile-content-width-max: 40rem;
|
||||||
--profile-content-width-min: 36rem;
|
--profile-content-width-min: 36rem;
|
||||||
|
--content-width: 50rem;
|
||||||
|
--content-height: 50rem;
|
||||||
|
|
||||||
--width-min-desktop: 1275px;
|
--width-min-desktop: 1275px;
|
||||||
--width-mobile: 875px;
|
--width-mobile: 875px;
|
||||||
|
@ -102,6 +104,10 @@ h2 {
|
||||||
margin: 2rem;
|
margin: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
width: var(--content-width);
|
||||||
|
}
|
||||||
|
|
||||||
.flex-row {
|
.flex-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -125,6 +131,10 @@ h2 {
|
||||||
box-shadow: #41354340 0px 8px 18px -1px;
|
box-shadow: #41354340 0px 8px 18px -1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.w-100 {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.h-100 {
|
.h-100 {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
@ -180,6 +190,10 @@ h2 {
|
||||||
margin-left: 0.5rem;
|
margin-left: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.margin-bot-force {
|
||||||
|
margin-top: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.padding-left-3 {
|
.padding-left-3 {
|
||||||
padding-left: 3rem;
|
padding-left: 3rem;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ a {
|
||||||
outline: var(--navbar-outline)
|
outline: var(--navbar-outline)
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.navbar-content {
|
||||||
grid-area: overlay;
|
grid-area: overlay;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
width: inherit;
|
width: inherit;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.person-container {
|
.person-container {
|
||||||
width: 50rem;
|
width: 100%;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,16 +21,6 @@
|
||||||
margin-right: 1rem !important;
|
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 {
|
.pill-profile {
|
||||||
transition: all .4s ease 0s;
|
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;
|
margin-top: auto !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-min-pill span {
|
|
||||||
font-size: 0.8rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.post-min-pill svg {
|
.post-min-pill svg {
|
||||||
|
border-radius: 100% !important;
|
||||||
width: 1.2rem !important;
|
width: 1.2rem !important;
|
||||||
height: 1.2rem !important;
|
height: 1.2rem !important;
|
||||||
padding: calc((2rem - 1.2rem)/2);
|
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": {
|
"person": {
|
||||||
"name": "Yohan Boujon",
|
"name": "Yohan Boujon",
|
||||||
"pronouns": "il/lui",
|
"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 CoverImg from "$lib/components/cover-img.svelte";
|
||||||
import Person from "$lib/components/person.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";
|
import hubjson from "$lib/json/hub.json";
|
||||||
|
|
||||||
let hub_cover =
|
let hub_cover =
|
||||||
|
@ -23,14 +27,30 @@
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<h1>{hubjson.who}</h1>
|
<h1>{hubjson.who}</h1>
|
||||||
</div>
|
</div>
|
||||||
<Person
|
<div class="flex w-100 justify-center">
|
||||||
picture={profile_pic}
|
<div class="content">
|
||||||
name={hubjson.person.name}
|
<Person
|
||||||
pronouns={hubjson.person.pronouns}
|
picture={profile_pic}
|
||||||
description={hubjson.person.description}
|
name={hubjson.person.name}
|
||||||
url="/about"
|
pronouns={hubjson.person.pronouns}
|
||||||
/>
|
description={hubjson.person.description}
|
||||||
|
url="/about"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="section">
|
<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>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Add table
Reference in a new issue