From 535a4584aab06dc39372554aa221e9731b97cc34 Mon Sep 17 00:00:00 2001 From: Ayabusa Date: Fri, 27 Mar 2026 20:44:27 +0100 Subject: [PATCH] Started working on arrows --- projects/index.html | 42 +++++++++++++++----- projects/script.js | 97 +++++++++++++++++++++++++++++++++++++++++++++ projects/style.css | 20 ++++++++++ 3 files changed, 148 insertions(+), 11 deletions(-) create mode 100644 projects/script.js diff --git a/projects/index.html b/projects/index.html index f3f5a82..f15eaad 100644 --- a/projects/index.html +++ b/projects/index.html @@ -4,25 +4,24 @@ Ayabusa club - Projects - - +
-
+

loc_projects:

- During my dev journey, I had the opportunity to create some cool projects.

+ During my dev journey, I have the opportunity to create some cool projects.

I've collected here those that might pick your interest.

-
+
@@ -37,7 +36,7 @@ I develloped it with Golang for the backend and svelte for the frontend, and it has worked pretty well for me :D

-
+
@@ -71,15 +70,15 @@
-
+

loc_a_la_carte:

- During my dev journey, I had the opportunity to create some cool projects.

- I've collected here those that might pick your interest. + À la carte is a game I built for the Numworks, in the context of a TI Planet contest. + It's built in python and optimized for it to run smoothly on the target calculator.

@@ -91,10 +90,31 @@

loc_minecraft_mods:

- During my dev journey, I had the opportunity to create some cool projects.

- I've collected here those that might pick your interest. + During some of my (too) many Minecraft two weeks phases, I develloped some minecraft mods. Mainly in Fabric, + I even did a tutorial to get + started and be introduced to the wonderfull world of Mixins xD.

+ No more spire: I did this mod for the server that I was playing back then OriginRealms. + Everyone was spamming about the spire update in chat, so I decided to do some cleanup and free the chat from this pollution.

+ Modern chunk detector: This mod was made for the server 9b9t that my friend and I were playing. It highlights the chunk that were + generated in modern version of MC. Great to track bases trails ;)

+ + + + + + + + + + + + diff --git a/projects/script.js b/projects/script.js new file mode 100644 index 0000000..3f961f4 --- /dev/null +++ b/projects/script.js @@ -0,0 +1,97 @@ +// ─── Configuration ──────────────────────────────────────────── +// Each pair is [sourceId, targetId]. +// Arrows go from the bottom-center of the source +// to the top-center of the target. +const CONNECTIONS = [ + ['n0', 'n1'], + ['n1', 'n2'], + ['n2', 'n3'], +]; + +// ─── Setup ──────────────────────────────────────────────────── +const scene = document.getElementById('body'); +const svg = document.getElementById('arrows'); + +// Create one SVG per connection +const pathEls = CONNECTIONS.map(() => { + const p = document.createElementNS('http://www.w3.org/2000/svg', 'path'); + p.setAttribute('class', 'arrow-path'); + p.setAttribute('marker-end', 'url(#head)'); + svg.appendChild(p); + return p; +}); + +// ─── Core: Manhattan path between two elements ──────────────── +// r1 = bounding rect of source, r2 = bounding rect of target +// Both rects are relative to the scene container. +function manhattanPath(r1, r2) { + const x1 = r1.left + r1.width / 2; // bottom-center of source + const y1 = r1.top + r1.height + 10; + const x2 = r2.left + r2.width / 2; // top-center of target + const y2 = r2.top + 5; // stop 8px above target (arrowhead gap) + + const ymid = y1 + (y2 - y1) / 2; // elbow halfway between the two + + // M: move to source bottom + // L: go straight down to mid-y + // L: go horizontally to target x + // L: go straight down to target top + return `M ${x1} ${y1} + L ${x1} ${ymid} + L ${x2} ${ymid} + L ${x2} ${y2}`; +} + +// ─── Redraw all arrows ──────────────────────────────────────── +function redraw() { + const sceneRect = scene.getBoundingClientRect(); + + CONNECTIONS.forEach(([srcId, tgtId], i) => { + const src = document.getElementById(srcId).getBoundingClientRect(); + const tgt = document.getElementById(tgtId).getBoundingClientRect(); + + // Convert from viewport coords → scene-local coords + const r1 = { + left: src.left - sceneRect.left, + top: src.top - sceneRect.top, + width: src.width, + height: src.height, + }; + const r2 = { + left: tgt.left - sceneRect.left, + top: tgt.top - sceneRect.top, + width: tgt.width, + height: tgt.height, + }; + + pathEls[i].setAttribute('d', manhattanPath(r1, r2)); + }); +} + +// ─── Drag logic ─────────────────────────────────────────────── +document.querySelectorAll('.node').forEach(node => { + node.addEventListener('mousedown', e => { + e.preventDefault(); + const startX = e.clientX; + const startY = e.clientY; + const originL = parseInt(node.style.left); + const originT = parseInt(node.style.top); + + const onMove = e => { + node.style.left = Math.max(0, originL + e.clientX - startX) + 'px'; + node.style.top = Math.max(0, originT + e.clientY - startY) + 'px'; + redraw(); + }; + const onUp = () => { + window.removeEventListener('mousemove', onMove); + window.removeEventListener('mouseup', onUp); + }; + + window.addEventListener('mousemove', onMove); + window.addEventListener('mouseup', onUp); + }); +}); + +// ─── Initial draw ───────────────────────────────────────────── +// Wait two frames so the browser has laid out the divs +requestAnimationFrame(() => requestAnimationFrame(redraw)); diff --git a/projects/style.css b/projects/style.css index eb704b3..5e7cba8 100644 --- a/projects/style.css +++ b/projects/style.css @@ -51,6 +51,26 @@ a { margin-bottom: -3px; } +/* ─── SVG overlay ────────────────────────────────────────── */ +#arrows { + position: absolute; + inset: 0; /* fill the scene */ + width: 100%; + height: 100%; + pointer-events: none; /* clicks pass through to divs */ + overflow: visible; /* arrows can leave the box if needed */ +} + + +/* Arrow path style */ +.arrow-path { + fill: none; + stroke: #aaa9a2; + stroke-width: 1.5; + stroke-linecap: round; + stroke-linejoin: round; +} + /* Win32 classic scrollbar */ ::-webkit-scrollbar { width: 17px;