Started working on arrows
This commit is contained in:
@@ -4,25 +4,24 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Ayabusa club - Projects</title>
|
<title>Ayabusa club - Projects</title>
|
||||||
<link rel="stylesheet" href="./style.css">
|
<link rel="stylesheet" href="./style.css">
|
||||||
<!--<script src="script.js"></script> -->
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body id="body">
|
||||||
<div style="display: flex; direction: row; justify-content: center; margin-bottom: 50px;">
|
<div style="display: flex; direction: row; justify-content: center; margin-bottom: 50px;">
|
||||||
<div class="disbox">
|
<div class="disbox node" id="n0">
|
||||||
<div class="disboxh">
|
<div class="disboxh">
|
||||||
<img class="ico" src="../assets/gitico.png"></img>
|
<img class="ico" src="../assets/gitico.png"></img>
|
||||||
<img class="ico" src="../assets/blogico.png"></img>
|
<img class="ico" src="../assets/blogico.png"></img>
|
||||||
</div>
|
</div>
|
||||||
<p class="disboxp">
|
<p class="disboxp">
|
||||||
loc_projects:<br><br>
|
loc_projects:<br><br>
|
||||||
During my <b>dev journey</b>, I had the opportunity to create some cool projects.<br><br>
|
During my <b>dev journey</b>, I have the opportunity to create some cool projects.<br><br>
|
||||||
I've collected here those that might <b>pick your interest</b>.
|
I've collected here those that might <b>pick your interest</b>.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex; direction: row; justify-content: center; margin-bottom: 50px;">
|
<div style="display: flex; direction: row; justify-content: center; margin-bottom: 50px;">
|
||||||
<div>
|
<div>
|
||||||
<div class="disbox" style="margin-bottom: 50px;">
|
<div class="disbox node" id="n1" style="margin-bottom: 50px;">
|
||||||
<div class="disboxh">
|
<div class="disboxh">
|
||||||
<img class="ico" src="../assets/gitico.png"></img>
|
<img class="ico" src="../assets/gitico.png"></img>
|
||||||
<img class="ico" src="../assets/blogico.png"></img>
|
<img class="ico" src="../assets/blogico.png"></img>
|
||||||
@@ -37,7 +36,7 @@
|
|||||||
I develloped it with <b>Golang</b> for the backend and <b>svelte</b> for the frontend, and it has worked pretty well for me :D
|
I develloped it with <b>Golang</b> for the backend and <b>svelte</b> for the frontend, and it has worked pretty well for me :D
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="disbox">
|
<div class="disbox node" id="n2">
|
||||||
<div class="disboxh">
|
<div class="disboxh">
|
||||||
<img class="ico" src="../assets/gitico.png"></img>
|
<img class="ico" src="../assets/gitico.png"></img>
|
||||||
<img class="ico" src="../assets/blogico.png"></img>
|
<img class="ico" src="../assets/blogico.png"></img>
|
||||||
@@ -71,15 +70,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex; direction: row; justify-content: center; margin-bottom: 50px;">
|
<div style="display: flex; direction: row; justify-content: center; margin-bottom: 50px;">
|
||||||
<div class="disbox">
|
<div class="disbox node" id="n3">
|
||||||
<div class="disboxh">
|
<div class="disboxh">
|
||||||
<img class="ico" src="../assets/gitico.png"></img>
|
<img class="ico" src="../assets/gitico.png"></img>
|
||||||
<img class="ico" src="../assets/blogico.png"></img>
|
<img class="ico" src="../assets/blogico.png"></img>
|
||||||
</div>
|
</div>
|
||||||
<p class="disboxp">
|
<p class="disboxp">
|
||||||
loc_a_la_carte:<br><br>
|
loc_a_la_carte:<br><br>
|
||||||
During my <b>dev journey</b>, I had the opportunity to create some cool projects.<br><br>
|
<b>À la carte</b> is a <b>game</b> I built for the <b>Numworks</b>, in the context of a <a href="https://tiplanet.org/">TI Planet</a> contest.
|
||||||
I've collected here those that might <b>pick your interest</b>.
|
It's built in <b>python</b> and optimized for it to <b>run smoothly</b> on the target <b>calculator</b>.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -91,10 +90,31 @@
|
|||||||
</div>
|
</div>
|
||||||
<p class="disboxp">
|
<p class="disboxp">
|
||||||
loc_minecraft_mods:<br><br>
|
loc_minecraft_mods:<br><br>
|
||||||
During my <b>dev journey</b>, I had the opportunity to create some cool projects.<br><br>
|
During some of my (too) many <b>Minecraft two weeks phases</b>, I develloped some <b>minecraft mods</b>. Mainly in <b>Fabric</b>,
|
||||||
I've collected here those that might <b>pick your interest</b>.
|
I even did a <a href="https://blog.ayabusa.dev/2023/10/30/how-minecraft-mods-works-for-dummies/">tutorial to get
|
||||||
|
started</a> and be introduced to the wonderfull world of <b>Mixins</b> xD.<br/><br/>
|
||||||
|
<a href="https://modrinth.com/mod/no-more-spire">No more spire</a>: I did this mod for the server that I was playing back then <b>OriginRealms</b>.
|
||||||
|
Everyone was spamming about the <b>spire update</b> in chat, so I decided to do some <b>cleanup</b> and free the chat from this <b>pollution</b>.<br/><br/>
|
||||||
|
<a href="https://modrinth.com/mod/modern-chunk-detector">Modern chunk detector</a>: This mod was made for the server <b>9b9t</b> that my friend and I were playing. It <b>highlights</b> the chunk that were
|
||||||
|
generated in <b>modern version of MC</b>. Great to track bases trails ;)
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<svg id="arrows">
|
||||||
|
<defs>
|
||||||
|
<!-- Arrowhead marker — inherits line color via context-stroke -->
|
||||||
|
<marker id="head"
|
||||||
|
viewBox="0 0 10 10" refX="8" refY="5"
|
||||||
|
markerWidth="6" markerHeight="6"
|
||||||
|
orient="auto-start-reverse">
|
||||||
|
<path d="M1 1L9 5L1 9Z"
|
||||||
|
fill="context-stroke" stroke="none"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<!-- One <path> per connection (added by JS below) -->
|
||||||
|
</svg>
|
||||||
|
<script src="script.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
97
projects/script.js
Normal file
97
projects/script.js
Normal file
@@ -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 <path> 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));
|
||||||
@@ -51,6 +51,26 @@ a {
|
|||||||
margin-bottom: -3px;
|
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 */
|
/* Win32 classic scrollbar */
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
width: 17px;
|
width: 17px;
|
||||||
|
|||||||
Reference in New Issue
Block a user