Compare commits
3 commits
7dcbf90ed0
...
b7abea2326
Author | SHA1 | Date | |
---|---|---|---|
b7abea2326 | |||
90951f2318 | |||
5ff81dba3b |
7 changed files with 179 additions and 24 deletions
|
@ -5,14 +5,20 @@
|
|||
|
||||
import { mdiBookmark, mdiHistory, mdiDatabase } from "@mdi/js";
|
||||
import SvgIcon from "@jamescoyle/svelte-icon";
|
||||
|
||||
// TS Scripts
|
||||
import { load_api, getCommitCount } from "$lib/ts/load.ts";
|
||||
import { get_size } from "$lib/ts/size.ts";
|
||||
import { LoadingSkeleton, Loading } from "$lib/ts/loading.ts";
|
||||
import viewport from "$lib/ts/viewport.ts";
|
||||
|
||||
import { onMount } from "svelte";
|
||||
import map from "language-map";
|
||||
import anime from "animejs";
|
||||
import { redirect } from "@sveltejs/kit";
|
||||
|
||||
// Exported values/ Internal values
|
||||
export let repo = "Etheryo/blog";
|
||||
let loading = true;
|
||||
let title = repo.split("/")[1];
|
||||
let commitNum = 0;
|
||||
let repoSize = 0;
|
||||
|
@ -23,17 +29,22 @@
|
|||
repoSize: 0,
|
||||
};
|
||||
|
||||
let overlay_div;
|
||||
let cursorX = 0;
|
||||
let cursorY = 0;
|
||||
let updateX = true;
|
||||
// Loading logic
|
||||
let finishLoading = new Loading();
|
||||
let finishLoadingStatus = false;
|
||||
|
||||
// Mouse animation
|
||||
let overlayDiv;
|
||||
let cursorX = 0;
|
||||
let cursorY = 0;
|
||||
let updateX = true;
|
||||
function update_gradient(event, div) {
|
||||
const rect = div.getBoundingClientRect();
|
||||
if (updateX) {
|
||||
cursorX = event.clientX - rect.left;
|
||||
}
|
||||
cursorY = event.clientY - rect.top;
|
||||
overlay_div.style.backgroundImage = `radial-gradient(circle farthest-corner at ${Math.floor(cursorX)}px ${Math.floor(cursorY)}px, var(--color-background) 0%, #958a98 100%)`;
|
||||
overlayDiv.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) {
|
||||
|
@ -47,7 +58,15 @@
|
|||
});
|
||||
}
|
||||
|
||||
// Loading animation
|
||||
let divLoading;
|
||||
let skeleton;
|
||||
let countersSet = false;
|
||||
|
||||
onMount(async () => {
|
||||
skeleton = new LoadingSkeleton(divLoading);
|
||||
skeleton.start();
|
||||
|
||||
// Gathering commit number
|
||||
let response = await getCommitCount(repo);
|
||||
if (response.error === null) commitNum = response.count;
|
||||
|
@ -79,9 +98,13 @@
|
|||
(repoColors[i].lang_percentage / lang_total) * 1000,
|
||||
) / 10;
|
||||
}
|
||||
loading = false;
|
||||
await skeleton.stop();
|
||||
finishLoadingStatus = finishLoading.setStatus(true);
|
||||
}
|
||||
});
|
||||
|
||||
async function animateCounters() {
|
||||
await finishLoading.getPromise();
|
||||
// Animation for counters
|
||||
anime({
|
||||
targets: { num: 0 },
|
||||
|
@ -107,7 +130,8 @@
|
|||
);
|
||||
},
|
||||
});
|
||||
});
|
||||
countersSet = true;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
|
@ -115,13 +139,13 @@
|
|||
role="button"
|
||||
tabindex="0"
|
||||
on:mousemove={(event) => {
|
||||
update_gradient(event, overlay_div);
|
||||
update_gradient(event, overlayDiv);
|
||||
}}
|
||||
on:mouseenter={() => {
|
||||
animateForeground(true, overlay_div);
|
||||
animateForeground(true, overlayDiv);
|
||||
}}
|
||||
on:mouseleave={() => {
|
||||
animateForeground(false, overlay_div);
|
||||
animateForeground(false, overlayDiv);
|
||||
}}
|
||||
on:click={() => {
|
||||
window.location.href = `https://git.etheryo.fr/${repo}`;
|
||||
|
@ -129,9 +153,13 @@
|
|||
on:keypress={() => {
|
||||
window.location.href = `https://git.etheryo.fr/${repo}`;
|
||||
}}
|
||||
use:viewport
|
||||
on:enterViewport={() => {
|
||||
if (!countersSet) animateCounters();
|
||||
}}
|
||||
>
|
||||
<div class="git-container overlay">
|
||||
{#if !loading}
|
||||
{#if finishLoadingStatus}
|
||||
<div class="flex-row">
|
||||
<SvgIcon type="mdi" path={mdiBookmark}></SvgIcon>
|
||||
<div class="git-commit flex-row">
|
||||
|
@ -156,9 +184,9 @@
|
|||
{/each}
|
||||
</div>
|
||||
{:else}
|
||||
<p>Loading...</p>
|
||||
<div class="git-loading w-100 h-100" bind:this={divLoading}></div>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="overlay-front"></div>
|
||||
<div class="overlay-back" bind:this={overlay_div}></div>
|
||||
<div class="overlay-back" bind:this={overlayDiv}></div>
|
||||
</div>
|
||||
|
|
|
@ -84,11 +84,10 @@ h2 {
|
|||
margin: 0;
|
||||
}
|
||||
|
||||
.section::after {
|
||||
.section h1::after {
|
||||
width: 50%;
|
||||
height: 2px;
|
||||
left: 2rem;
|
||||
bottom: 0.75rem;
|
||||
bottom: -0.5rem;
|
||||
content: "";
|
||||
position: relative;
|
||||
display: block;
|
||||
|
@ -104,6 +103,15 @@ h2 {
|
|||
margin: 2rem;
|
||||
}
|
||||
|
||||
.section p {
|
||||
color: var(--color-subtext);
|
||||
font-family: "JetBrains Mono";
|
||||
font-weight: 500;
|
||||
font-size: 1rem;
|
||||
margin: 2rem;
|
||||
width: var(--content-width);
|
||||
}
|
||||
|
||||
.content {
|
||||
width: var(--content-width);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,11 @@
|
|||
margin-top: 0;
|
||||
}
|
||||
|
||||
.git-loading {
|
||||
background: linear-gradient(90deg, rgba(248, 241, 241, 1) 0%, rgba(15, 11, 17, 0.31) 50%, rgba(248, 241, 241, 1) 100%);
|
||||
background-size: 200% 100%;
|
||||
}
|
||||
|
||||
.git-commit {
|
||||
margin-left: auto;
|
||||
border-radius: 1rem;
|
||||
|
@ -69,8 +74,8 @@
|
|||
background-color: red;
|
||||
}
|
||||
|
||||
.git-color > div {
|
||||
height: 100%;
|
||||
.git-color>div {
|
||||
height: 100%;
|
||||
transition: var(--transition);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
|
|
@ -8,7 +8,10 @@
|
|||
"description": "Informatics and electronics engineer",
|
||||
"knowme": "Me Connaître"
|
||||
},
|
||||
"project":"Mes projets",
|
||||
"project": {
|
||||
"title": "Mes projets",
|
||||
"description": "Mes projets principaux, scolaires ou personnels. J'essaie de faire en sorte qu'ils soient les plus aboutis possible."
|
||||
},
|
||||
"projects": [
|
||||
{
|
||||
"cover": "https://share.etheryo.fr/project/visual/wal_min.png",
|
||||
|
@ -32,10 +35,17 @@
|
|||
"topic": "videogame"
|
||||
}
|
||||
],
|
||||
"lab": "Le laboratoire",
|
||||
"lab": {
|
||||
"title": "Le laboratoire",
|
||||
"description": "Le laboratoire présente des mini-projets qui me servent à apprendre certaines logiques, langages, bibliothèques logicielles, et microcontrôleurs. Ceci est une simple galerie montrant mes trois derniers projets du moment. Rien de transcendant, simplement des idées/concepts."
|
||||
},
|
||||
"repos": [
|
||||
"Training/yoyo_card",
|
||||
"INSA/reoc",
|
||||
"Training/rust_training"
|
||||
]
|
||||
],
|
||||
"photo": {
|
||||
"title": "Photographie",
|
||||
"description": "Je ne suis pas un professionnel, mais il faut avouer que prendre des photos, faire du montage dessus, ou simplement régler la colorimétrie fait partie de mes passions. Cette petite galerie montre mes dernières photos, souvent liées à une émotion actuelle."
|
||||
}
|
||||
}
|
72
src/lib/ts/loading.ts
Normal file
72
src/lib/ts/loading.ts
Normal file
|
@ -0,0 +1,72 @@
|
|||
import anime from 'animejs';
|
||||
|
||||
export class LoadingSkeleton {
|
||||
private _div: HTMLElement;
|
||||
private _animation!: any;
|
||||
|
||||
constructor(div: HTMLElement) {
|
||||
this._div = div;
|
||||
}
|
||||
|
||||
public start(): void {
|
||||
this._animation = anime({
|
||||
targets: this._div,
|
||||
backgroundPosition: [0, 200],
|
||||
duration: 1500,
|
||||
easing: 'linear',
|
||||
loop: true,
|
||||
});
|
||||
}
|
||||
|
||||
public async stop(): Promise<void> {
|
||||
this._animation?.pause();
|
||||
const stopAnimation = anime({
|
||||
targets: this._div,
|
||||
opacity: [1, 0],
|
||||
duration: 400,
|
||||
easing: 'easeInOutQuad',
|
||||
});
|
||||
|
||||
await stopAnimation.finished; // use `.finished` instead of `.promise`
|
||||
}
|
||||
}
|
||||
|
||||
export class Loading {
|
||||
private _status: boolean;
|
||||
private _promise: Promise<void>;
|
||||
private _resolver: (() => void);
|
||||
|
||||
constructor() {
|
||||
this._status = false;
|
||||
this._resolver = (() => (null));
|
||||
this._promise = new Promise<void>((resolve) => {
|
||||
this._resolver = resolve;
|
||||
});
|
||||
}
|
||||
|
||||
public getStatus(): boolean {
|
||||
return this._status;
|
||||
}
|
||||
|
||||
public setStatus(value: boolean): boolean {
|
||||
this._status = value;
|
||||
|
||||
if (value) this._resolver();
|
||||
// Create a new promise when the status is set to false again
|
||||
else {
|
||||
this._promise = new Promise<void>((resolve) => {
|
||||
this._resolver = resolve;
|
||||
});
|
||||
}
|
||||
return this._status;
|
||||
}
|
||||
|
||||
public getPromise(): Promise<void> {
|
||||
if (this._status)
|
||||
return Promise.resolve();
|
||||
else {
|
||||
return this._promise;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
26
src/lib/ts/viewport.ts
Normal file
26
src/lib/ts/viewport.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
let observer: IntersectionObserver;
|
||||
|
||||
function checkViewportObserver() {
|
||||
if (observer) return;
|
||||
|
||||
// When scrolling so that intersection observer detects the viewport
|
||||
observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
entries.forEach(entry => {
|
||||
const eventName = entry.isIntersecting ? 'enterViewport' : 'exitViewport';
|
||||
entry.target.dispatchEvent(new CustomEvent(eventName));
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export default function viewport(element: HTMLElement) {
|
||||
checkViewportObserver();
|
||||
observer.observe(element);
|
||||
|
||||
return {
|
||||
destroy() {
|
||||
observer.unobserve(element);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -40,7 +40,8 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h1>{hubjson.project}</h1>
|
||||
<h1>{hubjson.project.title}</h1>
|
||||
<p>{hubjson.project.description}</p>
|
||||
</div>
|
||||
<div class="flex w-100 justify-center">
|
||||
<div class="content flex-row center">
|
||||
|
@ -56,11 +57,16 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h1>{hubjson.lab}</h1>
|
||||
<h1>{hubjson.lab.title}</h1>
|
||||
<p>{hubjson.lab.description}</p>
|
||||
</div>
|
||||
<div class="flex w-100 justify-center">
|
||||
{#each hubjson.repos as repo}
|
||||
<Git {repo} />
|
||||
{/each}
|
||||
</div>
|
||||
<div class="section">
|
||||
<h1>{hubjson.photo.title}</h1>
|
||||
<p>{hubjson.photo.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Reference in a new issue