From 4a46913564b46a4f4b4e96a9186fc9b4f9d23ae8 Mon Sep 17 00:00:00 2001 From: Luca Conte Date: Mon, 17 Feb 2025 01:54:35 +0100 Subject: [PATCH] lots of stuff honestly - basic baseline --- Box.js | 97 ++++++++++++++++++++++++++++++++++++++++++++ Camera.js | 4 ++ Connector.js | 42 +++++++++++++++++++ icons/background.svg | 63 ++++++++++++++++++++++++++++ icons/x.svg | 14 +++++++ index.html | 2 + input-controller.js | 63 ++++++++++++++++++++++++++++ style.css | 46 +++++++++++++++++---- 8 files changed, 322 insertions(+), 9 deletions(-) create mode 100644 Camera.js create mode 100644 Connector.js create mode 100644 icons/background.svg create mode 100644 icons/x.svg create mode 100644 input-controller.js diff --git a/Box.js b/Box.js index e69de29..e80ea43 100644 --- a/Box.js +++ b/Box.js @@ -0,0 +1,97 @@ +class Box { + title; + + inputs = []; + outputs = []; + + x; + y; + + element; + + static instances = []; + + static updateAllPositions() { + for (let box of Box.instances) { + box.updatePosition(); + } + } + + constructor(title = "") { + Box.instances.push(this); + + this.title = title; + this.x = Camera.x + 100; + this.y = Camera.y + 200; + this.buildElement(); + this.updatePosition(); + } + + buildElement() { + this.element = document.createElement("div"); + this.element.classList.add("box"); + + let topBar = document.createElement("div"); + topBar.classList.add("boxTopBar"); + this.element.appendChild(topBar); + + + let deleteButton = document.createElement("span"); + deleteButton.classList.add("boxDeleteButton"); + deleteButton.addEventListener("click", () => { this.deleteBox() }); + topBar.appendChild(deleteButton); + + let content = document.createElement("div"); + content.classList.add("boxContent"); + this.element.appendChild(content); + + let title = document.createElement("span"); + title.classList.add("boxTitle"); + title.innerText = this.title; + content.appendChild(title); + + let connectorContainer = document.createElement("div"); + connectorContainer.classList.add("boxConnectorContainer"); + + let inputConnectorContainer = document.createElement("div"); + inputConnectorContainer.classList.add("inputConnectorContainer"); + inputConnectorContainer.classList.add("connectorContainer"); + + let outputConnectorContainer = document.createElement("div"); + outputConnectorContainer.classList.add("outputConnectorContainer"); + inputConnectorContainer.classList.add("connectorContainer"); + + connectorContainer.appendChild(inputConnectorContainer); + connectorContainer.appendChild(outputConnectorContainer); + + content.appendChild(connectorContainer); + + for (connector of this.inputs) { + inputConnectorContainer.appendChild(connector.element); + } + for (connector of this.outputs) { + outputConnectorContainer.appendChild(connector.element); + } + } + + updatePosition() { + this.element.style.left = (this.x - Camera.x) + "px"; + this.element.style.top = (this.y - Camera.y) + "px"; + } + + deleteBox() { + this.element.parentNode.removeChild(this.element); + for (let i = 0; i < Box.instances.length; i++) { + if (Box.instances[i] == this) { + Box.instances.splice(i, 1); + break; + } + } + } +} + +function addElement(type) { + let box = new Box("test"); + + document.getElementById("playground").appendChild(box.element); +} \ No newline at end of file diff --git a/Camera.js b/Camera.js new file mode 100644 index 0000000..f730c10 --- /dev/null +++ b/Camera.js @@ -0,0 +1,4 @@ +class Camera { + static x = 0; + static y = 0; +} \ No newline at end of file diff --git a/Connector.js b/Connector.js new file mode 100644 index 0000000..e5af0a9 --- /dev/null +++ b/Connector.js @@ -0,0 +1,42 @@ +class Connector { + static INPUT = 0; + static OUTPUT = 1; + + type; + + element; + + constructor(type, label = "") { + this.type = type; + this.element = ""; + this.label = label; + if (this.label == "") { + switch (this.type) { + case Connector.INPUT: + this.label = "Input"; + case Connector.OUTPUT: + this.label = "Output"; + } + } + + this.buildElement(); + } + + buildElement() { + this.element = document.createElement("div"); + this.element.classList.add("connector"); + + if (this.type == Connector.INPUT) { + this.element.classList.add("connectorInput"); + } + if (this.type == Connector.OUTPUT) { + this.element.classList.add("connectorOutput"); + } + + let circle = document.createElement("span"); + circle.classList.add("connectorCircle"); + + let label = document.createElement("span"); + label.classList.add("connectorLabel"); + } +} \ No newline at end of file diff --git a/icons/background.svg b/icons/background.svg new file mode 100644 index 0000000..65a1725 --- /dev/null +++ b/icons/background.svg @@ -0,0 +1,63 @@ + + + + + + + + + + + + diff --git a/icons/x.svg b/icons/x.svg new file mode 100644 index 0000000..bf9e3e4 --- /dev/null +++ b/icons/x.svg @@ -0,0 +1,14 @@ + + + + \ No newline at end of file diff --git a/index.html b/index.html index 758cb9b..dde95cd 100644 --- a/index.html +++ b/index.html @@ -3,8 +3,10 @@ DataTools + + diff --git a/input-controller.js b/input-controller.js new file mode 100644 index 0000000..f6a9aae --- /dev/null +++ b/input-controller.js @@ -0,0 +1,63 @@ +let draggingBox = null; +let draggingCamera = false; +let lastMousePos = {x: 0, y: 0}; + +document.addEventListener("mousedown", (e) => { + let x = e.clientX; + let y = e.clientY; + + if (e.button == 0) { + if (e.target.classList.contains("boxDeleteButton")) return; + for (let box of Box.instances) { + let topBarRect = box.element.getElementsByClassName("boxTopBar")[0].getBoundingClientRect(); + box.element.classList.remove("dragging"); + + if (isPointInRect(x, y, topBarRect.x, topBarRect.y, topBarRect.width, topBarRect.height)) { + draggingBox = box; + box.element.classList.add("dragging"); + break; + } + } + } + if (e.button == 1 || e.button == 2) { + draggingCamera = true; + e.preventDefault(); + } +}); + +document.addEventListener("mouseup", (e) => { + if (e.button == 0 && draggingBox != null) { + draggingBox.element.classList.remove("dragging"); + draggingBox = null; + } + if (e.button == 1 || e.button == 2) { + draggingCamera = false; + } +}) + +document.addEventListener("mousemove", (e) => { + + let delta = {x : e.clientX - lastMousePos.x, y : e.clientY - lastMousePos.y}; + + if (draggingBox != null) { + draggingBox.x += delta.x; + draggingBox.y += delta.y; + draggingBox.updatePosition(); + } + + if (draggingCamera) { + Camera.x -= delta.x; + Camera.y -= delta.y; + + Box.updateAllPositions(); + + document.getElementById("canvas").style.backgroundPosition = (-Camera.x) + "px " + (-Camera.y) + "px"; + + } + + lastMousePos = {x: e.clientX, y: e.clientY}; +}) + +function isPointInRect(px, py, rx, ry, rw, rh) { + return px >= rx && px <= rx + rw && py >= ry && py <= ry + rh; +} \ No newline at end of file diff --git a/style.css b/style.css index 7285599..bb4491a 100644 --- a/style.css +++ b/style.css @@ -34,9 +34,7 @@ body { height: 100%; top: 0; left: 0; - background-color: #111; - background-image: repeating-linear-gradient(45deg, #222 25%, transparent 25%, transparent 75%, #222 75%, #222), repeating-linear-gradient(45deg, #222 25%, #111 25%, #111 75%, #222 75%, #222); - background-position: 0 0, 40px 40px; + background-image: url("icons/background.svg"); background-size: 80px 80px; z-index: 0; } @@ -48,28 +46,57 @@ body { left: 0px; width: 100%; height: 100%; + overflow: none; } .box { position: absolute; - display: inline-flex; + display: flex; flex-direction: column; - gap: 20px; - padding: 10px; + gap: 0px; + padding: 0px; border: solid 1px #111; - border-top: solid 20px #111; box-shadow: 0px 0px 20px 0px black; background-color: #2227; backdrop-filter: blur(4px); + --topBarHeight: 20px; +} - top: 200px; - left: 200px; +.boxTopBar { + background-color: var(--bg); + width: 100%; + height: var(--topBarHeight); + cursor: grab; +} + +.boxDeleteButton { + display: block; + float: right; + cursor: pointer; + width: var(--topBarHeight); + height: var(--topBarHeight); + border-radius: var(--topBarHeight); + background-image: url("icons/x.svg"); + background-size: contain; + background-repeat: no-repeat; + background-position: 50% 50%; +} + +.boxContent { + display: flex; + flex-direction: column; + gap: 20px; + padding: 10px; } .box.dragging { box-shadow: 0px 0px 20px 0px rgba(255,255,255,0.3); + cursor: grabbing; +} +.box.dragging .boxTopBar { + cursor: grabbing; } .boxTitle { @@ -77,6 +104,7 @@ body { font-weight: bold; } + input, textarea, select, button { background-color: #25252577; padding: 5px;