lots of stuff honestly - basic baseline

This commit is contained in:
Luca Conte 2025-02-17 01:54:35 +01:00
parent 5f4027f7c5
commit 4a46913564
8 changed files with 322 additions and 9 deletions

97
Box.js
View File

@ -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);
}

4
Camera.js Normal file
View File

@ -0,0 +1,4 @@
class Camera {
static x = 0;
static y = 0;
}

42
Connector.js Normal file
View File

@ -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");
}
}

63
icons/background.svg Normal file
View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="200"
height="200"
viewBox="0 0 52.916665 52.916666"
version="1.1"
id="svg1"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
sodipodi:docname="background.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:document-units="mm"
inkscape:zoom="4.2725309"
inkscape:cx="95.844831"
inkscape:cy="77.588673"
inkscape:window-width="2560"
inkscape:window-height="1377"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:#222222;fill-opacity:1;stroke:none;stroke-width:0.584999"
id="rect3"
width="52.916664"
height="52.916664"
x="0"
y="0" />
<rect
style="fill:#111111;fill-opacity:1;stroke:none;stroke-width:0.584999"
id="rect1"
width="26.458334"
height="26.458334"
x="0"
y="0" />
<rect
style="fill:#111111;fill-opacity:1;stroke:none;stroke-width:0.584999"
id="rect2"
width="26.458332"
height="26.458332"
x="26.458332"
y="26.458332" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

14
icons/x.svg Normal file
View File

@ -0,0 +1,14 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="#666666"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M18 6l-12 12" />
<path d="M6 6l12 12" />
</svg>

After

Width:  |  Height:  |  Size: 256 B

View File

@ -3,8 +3,10 @@
<head> <head>
<title>DataTools</title> <title>DataTools</title>
<link rel="stylesheet" type="text/css" href="style.css"> <link rel="stylesheet" type="text/css" href="style.css">
<script src="Camera.js"></script>
<script src="Box.js"></script> <script src="Box.js"></script>
<script src="menu.js"></script> <script src="menu.js"></script>
<script src="input-controller.js"></script>
</head> </head>
<body> <body>
<canvas id="canvas"></canvas> <canvas id="canvas"></canvas>

63
input-controller.js Normal file
View File

@ -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;
}

View File

@ -34,9 +34,7 @@ body {
height: 100%; height: 100%;
top: 0; top: 0;
left: 0; left: 0;
background-color: #111; background-image: url("icons/background.svg");
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-size: 80px 80px; background-size: 80px 80px;
z-index: 0; z-index: 0;
} }
@ -48,28 +46,57 @@ body {
left: 0px; left: 0px;
width: 100%; width: 100%;
height: 100%; height: 100%;
overflow: none;
} }
.box { .box {
position: absolute; position: absolute;
display: inline-flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 20px; gap: 0px;
padding: 10px; padding: 0px;
border: solid 1px #111; border: solid 1px #111;
border-top: solid 20px #111;
box-shadow: 0px 0px 20px 0px black; box-shadow: 0px 0px 20px 0px black;
background-color: #2227; background-color: #2227;
backdrop-filter: blur(4px); backdrop-filter: blur(4px);
--topBarHeight: 20px;
}
top: 200px; .boxTopBar {
left: 200px; 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.dragging {
box-shadow: 0px 0px 20px 0px rgba(255,255,255,0.3); box-shadow: 0px 0px 20px 0px rgba(255,255,255,0.3);
cursor: grabbing;
}
.box.dragging .boxTopBar {
cursor: grabbing;
} }
.boxTitle { .boxTitle {
@ -77,6 +104,7 @@ body {
font-weight: bold; font-weight: bold;
} }
input, textarea, select, button { input, textarea, select, button {
background-color: #25252577; background-color: #25252577;
padding: 5px; padding: 5px;