about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--js/README.md1
-rw-r--r--js/app.js0
-rw-r--r--js/index.html0
-rw-r--r--js/notes/README.md1
-rw-r--r--js/notes/app.js108
-rw-r--r--js/notes/index.html22
6 files changed, 131 insertions, 1 deletions
diff --git a/js/README.md b/js/README.md
deleted file mode 100644
index c606933..0000000
--- a/js/README.md
+++ /dev/null
@@ -1 +0,0 @@
-Eli: I would like to make a note-taking application using HTML canvas and JavaScript. The user will be able to drag their mouse to define rectangles that they can then type in. Many rectangles can exist on the canvas at once, and can be dragged to be moved. All the data will be stored locally using localStorage, and I hope to use no dependencies. How would you suggest I create this application?
\ No newline at end of file
diff --git a/js/app.js b/js/app.js
deleted file mode 100644
index e69de29..0000000
--- a/js/app.js
+++ /dev/null
diff --git a/js/index.html b/js/index.html
deleted file mode 100644
index e69de29..0000000
--- a/js/index.html
+++ /dev/null
diff --git a/js/notes/README.md b/js/notes/README.md
new file mode 100644
index 0000000..f92fc7f
--- /dev/null
+++ b/js/notes/README.md
@@ -0,0 +1 @@
+# really bad note taking surface
\ No newline at end of file
diff --git a/js/notes/app.js b/js/notes/app.js
new file mode 100644
index 0000000..b4f9bf6
--- /dev/null
+++ b/js/notes/app.js
@@ -0,0 +1,108 @@
+const canvas = document.getElementById('canvas');
+canvas.width = window.innerWidth;
+canvas.height = window.innerHeight;
+const ctx = canvas.getContext('2d');
+const input = document.getElementById('input');
+let rectangles = JSON.parse(localStorage.getItem('rectangles')) || [];
+let currentRectangle = null;
+let dragging = false;
+
+const createRectangle = (x, y, width, height, text) => ({ x, y, width, height, text });
+const isPointInsideRectangle = (point, rectangle) => (
+    point.x >= rectangle.x &&
+    point.x <= rectangle.x + rectangle.width &&
+    point.y >= rectangle.y &&
+    point.y <= rectangle.y + rectangle.height
+);
+
+const handleMouseDown = (e) => {
+    currentRectangle = createRectangle(e.clientX, e.clientY, 0, 0, '');
+    dragging = true;
+};
+
+const handleMouseMove = (e) => {
+    if (dragging && currentRectangle) {
+        currentRectangle.width = e.clientX - currentRectangle.x;
+        currentRectangle.height = e.clientY - currentRectangle.y;
+        render();
+    }
+};
+
+const handleMouseUp = (e) => {
+    if (dragging && currentRectangle) {
+        rectangles.push(currentRectangle);
+        localStorage.setItem('rectangles', JSON.stringify(rectangles));
+        currentRectangle = null;
+        dragging = false;
+    }
+};
+
+const handleDoubleClick = (e) => {
+    const rectangle = rectangles.find((r) => isPointInsideRectangle({ x: e.clientX, y: e.clientY }, r));
+    if (rectangle) {
+        input.style.left = `${rectangle.x}px`;
+        input.style.top = `${rectangle.y}px`;
+        input.value = rectangle.text;
+        input.focus();
+        currentRectangle = rectangle;
+    }
+};
+
+const handleContextMenu = (e) => {
+    e.preventDefault();
+    const rectangle = rectangles.find((r) => isPointInsideRectangle({ x: e.clientX, y: e.clientY }, r));
+    if (rectangle) {
+        if (confirm('Are you sure you want to remove this rectangle?')) {
+            rectangles = rectangles.filter((r) => r !== rectangle);
+            localStorage.setItem('rectangles', JSON.stringify(rectangles));
+            render();
+        }
+    }
+};
+
+const handleInputBlur = (e) => {
+    if (currentRectangle) {
+        currentRectangle.text = input.value;
+        localStorage.setItem('rectangles', JSON.stringify(rectangles));
+        input.value = '';
+        render();
+    }
+};
+
+const handleClick = (e) => {
+    rectangles.forEach((r) => (r.focus = false));
+    const rectangle = rectangles.find((r) => isPointInsideRectangle({ x: e.clientX, y: e.clientY }, r));
+    if (rectangle) {
+        rectangle.focus = true;
+        render();
+    }
+};
+
+canvas.addEventListener('mousedown', handleMouseDown);
+canvas.addEventListener('mousemove', handleMouseMove);
+canvas.addEventListener('mouseup', handleMouseUp);
+canvas.addEventListener('dblclick', handleDoubleClick);
+canvas.addEventListener('contextmenu', handleContextMenu);
+input.addEventListener('blur', handleInputBlur);
+canvas.addEventListener('click', handleClick);
+
+const render = () => {
+    ctx.clearRect(0, 0, canvas.width, canvas.height);
+    rectangles.forEach((r) => {
+        ctx.fillStyle = 'white';
+        ctx.fillRect(r.x, r.y, r.width, r.height);
+        ctx.lineWidth = r.focus ? 3 : 1;
+        ctx.strokeRect(r.x, r.y, r.width, r.height);
+        ctx.fillStyle = 'black';
+        ctx.fillText(r.text, r.x, r.y + r.height);
+    });
+    if (currentRectangle) {
+        ctx.fillStyle = 'white';
+        ctx.fillRect(currentRectangle.x, currentRectangle.y, currentRectangle.width, currentRectangle.height);
+        ctx.lineWidth = 1;
+        ctx.strokeRect(currentRectangle.x, currentRectangle.y, currentRectangle.width, currentRectangle.height);
+    }
+    ctx.lineWidth = 1;
+};
+
+render();
\ No newline at end of file
diff --git a/js/notes/index.html b/js/notes/index.html
new file mode 100644
index 0000000..79749b9
--- /dev/null
+++ b/js/notes/index.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>notes</title>
+    <style>
+        body, html {
+            margin: 0;
+            padding: 0;
+            overflow: hidden;
+        }
+        #canvas {
+            background-color: grey;
+        }
+    </style>
+</head>
+<body>
+    <canvas id="canvas"></canvas>
+    <script src="app.js"></script>
+</body>
+</html>
\ No newline at end of file