Skip to content

Commit 5cddac8

Browse files
authored
Made the terminal resizable, move let and const to top of the script … (#350)
* Made the terminal resizable, move let and const to top of the script file * clean * run pre-commit
1 parent 2daa16c commit 5cddac8

File tree

2 files changed

+116
-32
lines changed

2 files changed

+116
-32
lines changed

src/_includes/system-log.njk

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,29 @@
11
<button id="reopen-console-btn" onclick="reopenConsole()" class="fixed bottom-6 right-6 p-3 bg-black/80 border border-green-500/30 rounded-full text-green-500 hover:scale-110 transition-all z-[999]" title="Open System Log">
22
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 17 10 11 4 5"></polyline><line x1="12" y1="19" x2="20" y2="19"></line></svg>
33
</button>
4-
<div id="matrix-console-container" class="fixed bottom-6 right-6 w-80 z-[1000] transition-all duration-300 ease-in-out hidden"
5-
style="opacity: 0; transform: translateY(20px);">
4+
<div id="matrix-console-container" class="fixed bottom-6 right-6 w-80 z-[1000] transition-all duration-300 ease-in-out hidden" style="opacity: 0; transform: translateY(20px);">
65
<div class="bg-black/90 backdrop-blur-xl border border-green-500/30 rounded-t-lg overflow-hidden shadow-2xl">
7-
86
<div class="bg-green-500/10 border-b border-green-500/30 px-3 py-2 flex justify-between items-center cursor-grab select-none">
97
<div class="flex items-center gap-2">
108
<span class="text-[10px] font-mono text-green-500 uppercase tracking-widest opacity-70">System_Log</span>
119
</div>
12-
1310
<div class="flex gap-2">
1411
<button onclick="minimizeConsole()" class="w-3 h-3 rounded-full bg-yellow-500/20 border border-yellow-500/50 hover:bg-yellow-500/50 transition-colors" title="Minimize"></button>
1512
<button onclick="maximizeConsole()" class="w-3 h-3 rounded-full bg-green-500/20 border border-green-500/50 hover:bg-green-500/50 transition-colors" title="Maximize"></button>
1613
<button onclick="closeConsole()" class="w-3 h-3 rounded-full bg-red-500/20 border border-red-500/50 hover:bg-red-500/50 transition-colors" title="Close"></button>
1714
</div>
1815
</div>
19-
2016
<div id="matrix-console-output" class="h-48 p-3 overflow-y-auto font-mono text-[11px] leading-tight">
2117
<p class="text-green-500/40">// Terminal link established...</p>
2218
</div>
2319
</div>
20+
21+
<div class="resize-handle resize-handle-n" style="position:absolute;top:-3px;left:8px;right:8px;height:6px;cursor:n-resize;z-index:1;"></div>
22+
<div class="resize-handle resize-handle-s" style="position:absolute;bottom:-3px;left:8px;right:8px;height:6px;cursor:s-resize;z-index:1;"></div>
23+
<div class="resize-handle resize-handle-e" style="position:absolute;right:-3px;top:8px;bottom:8px;width:6px;cursor:e-resize;z-index:1;"></div>
24+
<div class="resize-handle resize-handle-w" style="position:absolute;left:-3px;top:8px;bottom:8px;width:6px;cursor:w-resize;z-index:1;"></div>
25+
<div class="resize-handle resize-handle-ne" style="position:absolute;top:-4px;right:-4px;width:10px;height:10px;cursor:ne-resize;z-index:2;"></div>
26+
<div class="resize-handle resize-handle-nw" style="position:absolute;top:-4px;left:-4px;width:10px;height:10px;cursor:nw-resize;z-index:2;"></div>
27+
<div class="resize-handle resize-handle-se" style="position:absolute;bottom:-4px;right:-4px;width:10px;height:10px;cursor:se-resize;z-index:2;"></div>
28+
<div class="resize-handle resize-handle-sw" style="position:absolute;bottom:-4px;left:-4px;width:10px;height:10px;cursor:sw-resize;z-index:2;"></div>
2429
</div>

src/assets/js/script.js

Lines changed: 106 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,34 @@
1+
// Variables
2+
let isResizing = false;
3+
let resizeDirection = "";
4+
let resizeStartX = 0;
5+
let resizeStartY = 0;
6+
let resizeStartWidth = 0;
7+
let resizeStartOutputHeight = 0;
8+
let resizeStartLeft = 0;
9+
let resizeStartTop = 0;
10+
// Load saved level or start at 0
11+
let currentLevel = Number(localStorage.getItem("userLevel")) || 0;
12+
13+
// Load saved XP or start at 0
14+
let currentXP = parseInt(localStorage.getItem("userXP")) || 0;
15+
16+
let isSurging = false;
17+
18+
let audioCtx;
19+
20+
let unlockedEggs = JSON.parse(localStorage.getItem("unlockedEggs")) || [];
21+
let surpriseClickCount = 0;
22+
let matrixActive = false;
23+
let destructInterval;
24+
25+
let isDragging = false;
26+
let offsetLeft = 0;
27+
let offsetTop = 0;
28+
29+
// Const Variables
30+
const MIN_CONSOLE_WIDTH = 200;
31+
const MIN_OUTPUT_HEIGHT = 50;
132
const XP_PER_LEVEL = 45;
233

334
// XP rewards for events and secrets
@@ -13,13 +44,6 @@ const XP_FOOTER_SURGE = 1000; // Footer surge secret
1344
const XP_BADGE_CLICK = 45; // Badge click reward
1445

1546
const NUM_LEVELS = LEVELS.length;
16-
// Load saved level or start at 0
17-
let currentLevel = Number(localStorage.getItem("userLevel")) || 0;
18-
19-
// Load saved XP or start at 0
20-
let currentXP = parseInt(localStorage.getItem("userXP")) || 0;
21-
22-
let isSurging = false;
2347

2448
function getContrastYIQ(hexcolor) {
2549
hexcolor = hexcolor.replace("#", "");
@@ -29,11 +53,10 @@ function getContrastYIQ(hexcolor) {
2953
var yiq = (r * 299 + g * 587 + b * 114) / 1000;
3054
return yiq >= 128 ? "black" : "white";
3155
}
56+
3257
/**
3358
* 1. RETRO SOUND ENGINE
3459
*/
35-
let audioCtx;
36-
3760
function initAudio() {
3861
try {
3962
if (!audioCtx) {
@@ -104,11 +127,6 @@ function playSound(type) {
104127
}
105128
}
106129

107-
let unlockedEggs = JSON.parse(localStorage.getItem("unlockedEggs")) || [];
108-
let surpriseClickCount = 0;
109-
let matrixActive = false;
110-
let destructInterval;
111-
112130
function getRank(lvl) {
113131
const numericLevel = Number(lvl) || 0;
114132

@@ -132,10 +150,6 @@ const consoleOutput = document.getElementById("matrix-console-output");
132150
const dragContainer = document.getElementById("matrix-console-container");
133151
const dragHeader = dragContainer.querySelector(".bg-green-500\\/10"); // Selects the header bar
134152

135-
let isDragging = false;
136-
let offsetLeft = 0;
137-
let offsetTop = 0;
138-
139153
dragHeader.addEventListener("mousedown", (e) => {
140154
// Prevent dragging when clicking the minimize/close buttons
141155
if (e.target.tagName === "BUTTON") return;
@@ -154,15 +168,12 @@ dragHeader.addEventListener("mousedown", (e) => {
154168
document.addEventListener("mousemove", (e) => {
155169
if (!isDragging) return;
156170

157-
// Calculate new position
158171
let x = e.clientX - offsetLeft;
159172
let y = e.clientY - offsetTop;
160173

161-
// Boundary Check (Optional: keeps it inside the screen)
162174
x = Math.max(0, Math.min(x, window.innerWidth - dragContainer.offsetWidth));
163175
y = Math.max(0, Math.min(y, window.innerHeight - dragContainer.offsetHeight));
164176

165-
// Apply position and remove Tailwind's 'bottom' and 'right' so they don't fight the 'top'/'left'
166177
dragContainer.style.bottom = "auto";
167178
dragContainer.style.right = "auto";
168179
dragContainer.style.left = `${x}px`;
@@ -174,8 +185,81 @@ document.addEventListener("mouseup", () => {
174185
dragHeader.style.cursor = "grab";
175186
});
176187

188+
dragContainer.querySelectorAll(".resize-handle").forEach((handle) => {
189+
handle.addEventListener("mousedown", (e) => {
190+
e.preventDefault();
191+
e.stopPropagation();
192+
193+
isResizing = true;
194+
195+
resizeDirection =
196+
[...handle.classList]
197+
.find((c) => c.startsWith("resize-handle-") && c !== "resize-handle")
198+
?.replace("resize-handle-", "") || "se";
199+
200+
const rect = dragContainer.getBoundingClientRect();
201+
resizeStartX = e.clientX;
202+
resizeStartY = e.clientY;
203+
resizeStartWidth = rect.width;
204+
resizeStartLeft = rect.left;
205+
resizeStartTop = rect.top;
206+
resizeStartOutputHeight = consoleOutput.offsetHeight;
207+
208+
dragContainer.style.bottom = "auto";
209+
dragContainer.style.right = "auto";
210+
dragContainer.style.left = `${rect.left}px`;
211+
dragContainer.style.top = `${rect.top}px`;
212+
213+
dragContainer.classList.remove(
214+
"transition-all",
215+
"duration-300",
216+
"ease-in-out",
217+
);
218+
document.body.style.userSelect = "none";
219+
document.body.style.cursor = handle.style.cursor;
220+
});
221+
});
222+
223+
document.addEventListener("mousemove", (e) => {
224+
if (!isResizing) return;
225+
226+
const dx = e.clientX - resizeStartX;
227+
const dy = e.clientY - resizeStartY;
228+
const dir = resizeDirection;
229+
230+
if (dir.includes("e")) {
231+
dragContainer.style.width = `${Math.max(MIN_CONSOLE_WIDTH, resizeStartWidth + dx)}px`;
232+
}
233+
if (dir.includes("w")) {
234+
const newW = resizeStartWidth - dx;
235+
if (newW >= MIN_CONSOLE_WIDTH) {
236+
dragContainer.style.width = `${newW}px`;
237+
dragContainer.style.left = `${resizeStartLeft + dx}px`;
238+
}
239+
}
240+
241+
if (dir.includes("s")) {
242+
consoleOutput.style.height = `${Math.max(MIN_OUTPUT_HEIGHT, resizeStartOutputHeight + dy)}px`;
243+
}
244+
if (dir.includes("n")) {
245+
const newH = resizeStartOutputHeight - dy;
246+
if (newH >= MIN_OUTPUT_HEIGHT) {
247+
consoleOutput.style.height = `${newH}px`;
248+
dragContainer.style.top = `${resizeStartTop + dy}px`;
249+
}
250+
}
251+
});
252+
253+
document.addEventListener("mouseup", () => {
254+
if (!isResizing) return;
255+
isResizing = false;
256+
resizeDirection = "";
257+
document.body.style.userSelect = "";
258+
document.body.style.cursor = "";
259+
dragContainer.classList.add("transition-all", "duration-300", "ease-in-out");
260+
});
261+
177262
function minimizeConsole() {
178-
// Toggles the height of the output area
179263
if (consoleOutput.style.display === "none") {
180264
consoleOutput.style.display = "block";
181265
consoleContainer.style.width = "20rem"; // w-80
@@ -186,10 +270,8 @@ function minimizeConsole() {
186270
}
187271

188272
function maximizeConsole() {
189-
// Toggles a full-screen-ish mode
190273
consoleContainer.classList.toggle("console-maximized");
191274

192-
// Adjust height when maximized
193275
if (consoleContainer.classList.contains("console-maximized")) {
194276
consoleOutput.style.height = "70vh";
195277
consoleOutput.style.display = "block";
@@ -217,16 +299,13 @@ function reopenConsole() {
217299
const container = document.getElementById("matrix-console-container");
218300
const reopenBtn = document.getElementById("reopen-console-btn");
219301

220-
// Show the console
221302
container.classList.remove("hidden");
222303

223-
// Trigger reflow for animation
224304
void container.offsetWidth;
225305

226306
container.style.opacity = "1";
227307
container.style.transform = "translateY(0)";
228308

229-
// Hide the reopen button
230309
if (reopenBtn) reopenBtn.classList.add("hidden");
231310
}
232311

0 commit comments

Comments
 (0)