madansa7 commited on
Commit
cf37b31
·
verified ·
1 Parent(s): fd1bc16

Add 3 files

Browse files
Files changed (3) hide show
  1. README.md +7 -5
  2. index.html +669 -19
  3. prompts.txt +2 -0
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Board
3
- emoji: 🚀
4
- colorFrom: blue
5
- colorTo: green
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: board
3
+ emoji: 🐳
4
+ colorFrom: gray
5
+ colorTo: yellow
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,669 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>CollabBoard - Online Whiteboard</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ #whiteboard {
11
+ touch-action: none;
12
+ background-image: linear-gradient(#e5e7eb 1px, transparent 1px), linear-gradient(90deg, #e5e7eb 1px, transparent 1px);
13
+ background-size: 20px 20px;
14
+ cursor: crosshair;
15
+ }
16
+
17
+ .tool-btn.active {
18
+ @apply bg-blue-100 border-blue-500;
19
+ }
20
+
21
+ .color-option {
22
+ width: 24px;
23
+ height: 24px;
24
+ border-radius: 50%;
25
+ cursor: pointer;
26
+ transition: transform 0.2s;
27
+ }
28
+
29
+ .color-option:hover {
30
+ transform: scale(1.2);
31
+ }
32
+
33
+ .color-option.selected {
34
+ transform: scale(1.3);
35
+ box-shadow: 0 0 0 2px white, 0 0 0 3px #3b82f6;
36
+ }
37
+
38
+ .sticky-note {
39
+ min-width: 150px;
40
+ min-height: 150px;
41
+ resize: both;
42
+ overflow: hidden;
43
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
44
+ }
45
+
46
+ .sticky-note textarea {
47
+ background: transparent;
48
+ resize: none;
49
+ outline: none;
50
+ }
51
+
52
+ .shape-preview {
53
+ position: absolute;
54
+ pointer-events: none;
55
+ opacity: 0.7;
56
+ }
57
+
58
+ .board-thumbnail {
59
+ transition: transform 0.2s, box-shadow 0.2s;
60
+ }
61
+
62
+ .board-thumbnail:hover {
63
+ transform: translateY(-2px);
64
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
65
+ }
66
+
67
+ /* Custom scrollbar */
68
+ ::-webkit-scrollbar {
69
+ width: 8px;
70
+ height: 8px;
71
+ }
72
+
73
+ ::-webkit-scrollbar-track {
74
+ background: #f1f1f1;
75
+ }
76
+
77
+ ::-webkit-scrollbar-thumb {
78
+ background: #c1c1c1;
79
+ border-radius: 4px;
80
+ }
81
+
82
+ ::-webkit-scrollbar-thumb:hover {
83
+ background: #a8a8a8;
84
+ }
85
+ </style>
86
+ </head>
87
+ <body class="bg-gray-50 h-screen flex flex-col">
88
+ <!-- Header -->
89
+ <header class="bg-white shadow-sm py-3 px-4 flex items-center justify-between">
90
+ <div class="flex items-center space-x-2">
91
+ <div class="bg-blue-600 text-white p-2 rounded-lg">
92
+ <i class="fas fa-chalkboard text-xl"></i>
93
+ </div>
94
+ <h1 class="text-xl font-bold text-gray-800">CollabBoard</h1>
95
+ </div>
96
+
97
+ <div class="flex items-center space-x-4">
98
+ <button id="presentation-btn" class="flex items-center space-x-1 bg-blue-50 hover:bg-blue-100 text-blue-700 px-3 py-1.5 rounded-lg text-sm font-medium">
99
+ <i class="fas fa-expand"></i>
100
+ <span>Presentation</span>
101
+ </button>
102
+
103
+ <button id="share-btn" class="flex items-center space-x-1 bg-green-50 hover:bg-green-100 text-green-700 px-3 py-1.5 rounded-lg text-sm font-medium">
104
+ <i class="fas fa-share-alt"></i>
105
+ <span>Share</span>
106
+ </button>
107
+
108
+ <div class="relative">
109
+ <button id="user-menu-btn" class="flex items-center space-x-1 bg-gray-100 hover:bg-gray-200 px-3 py-1.5 rounded-lg text-sm font-medium">
110
+ <i class="fas fa-user-circle text-gray-700"></i>
111
+ <span>User</span>
112
+ </button>
113
+ <div id="user-menu" class="hidden absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg py-1 z-50">
114
+ <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Account Settings</a>
115
+ <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Sign Out</a>
116
+ </div>
117
+ </div>
118
+ </div>
119
+ </header>
120
+
121
+ <div class="flex flex-1 overflow-hidden">
122
+ <!-- Sidebar -->
123
+ <div id="sidebar" class="w-64 bg-white border-r border-gray-200 flex flex-col">
124
+ <div class="p-4 border-b border-gray-200">
125
+ <button id="new-board-btn" class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded-lg font-medium flex items-center justify-center space-x-2">
126
+ <i class="fas fa-plus"></i>
127
+ <span>New Board</span>
128
+ </button>
129
+ </div>
130
+
131
+ <div class="p-4 border-b border-gray-200">
132
+ <div class="flex items-center justify-between mb-2">
133
+ <h3 class="font-medium text-gray-700">Your Boards</h3>
134
+ </div>
135
+
136
+ <div class="space-y-2" id="boards-list">
137
+ <!-- Boards will be added here dynamically -->
138
+ </div>
139
+ </div>
140
+
141
+ <div class="p-4 border-b border-gray-200">
142
+ <h3 class="font-medium text-gray-700 mb-2">Tags</h3>
143
+ <div class="space-y-1">
144
+ <div class="flex items-center space-x-2 p-1.5 rounded hover:bg-gray-100 cursor-pointer">
145
+ <div class="w-3 h-3 rounded-full bg-red-500"></div>
146
+ <span class="text-sm">Urgent</span>
147
+ </div>
148
+ <div class="flex items-center space-x-2 p-1.5 rounded hover:bg-gray-100 cursor-pointer">
149
+ <div class="w-3 h-3 rounded-full bg-yellow-500"></div>
150
+ <span class="text-sm">Ideas</span>
151
+ </div>
152
+ <div class="flex items-center space-x-2 p-1.5 rounded hover:bg-gray-100 cursor-pointer">
153
+ <div class="w-3 h-3 rounded-full bg-green-500"></div>
154
+ <span class="text-sm">Completed</span>
155
+ </div>
156
+ </div>
157
+ </div>
158
+
159
+ <div class="p-4">
160
+ <h3 class="font-medium text-gray-700 mb-2">Collaborators</h3>
161
+ <div class="space-y-2">
162
+ <div class="flex items-center space-x-2">
163
+ <div class="w-8 h-8 rounded-full bg-blue-100 flex items-center justify-center text-blue-600">
164
+ <i class="fas fa-user"></i>
165
+ </div>
166
+ <span class="text-sm">You</span>
167
+ </div>
168
+ </div>
169
+ </div>
170
+ </div>
171
+
172
+ <!-- Main Content -->
173
+ <div class="flex-1 flex flex-col overflow-hidden">
174
+ <!-- Toolbar -->
175
+ <div class="bg-white border-b border-gray-200 p-2 flex items-center justify-between">
176
+ <div class="flex items-center space-x-2 overflow-x-auto py-1">
177
+ <!-- Undo/Redo -->
178
+ <div class="flex items-center space-x-1 border-r border-gray-200 pr-2">
179
+ <button id="undo-btn" class="p-2 border rounded hover:bg-gray-100" title="Undo (Ctrl+Z)">
180
+ <i class="fas fa-undo"></i>
181
+ </button>
182
+ <button id="redo-btn" class="p-2 border rounded hover:bg-gray-100" title="Redo (Ctrl+Y)">
183
+ <i class="fas fa-redo"></i>
184
+ </button>
185
+ </div>
186
+
187
+ <!-- Drawing Tools -->
188
+ <div class="flex items-center space-x-1 border-r border-gray-200 pr-2">
189
+ <button id="select-tool" class="tool-btn p-2 border rounded hover:bg-gray-100 active" title="Select (V)">
190
+ <i class="fas fa-mouse-pointer"></i>
191
+ </button>
192
+ <button id="pen-tool" class="tool-btn p-2 border rounded hover:bg-gray-100" title="Pen (P)">
193
+ <i class="fas fa-pen"></i>
194
+ </button>
195
+ <button id="highlighter-tool" class="tool-btn p-2 border rounded hover:bg-gray-100" title="Highlighter (H)">
196
+ <i class="fas fa-highlighter"></i>
197
+ </button>
198
+ <button id="eraser-tool" class="tool-btn p-2 border rounded hover:bg-gray-100" title="Eraser (E)">
199
+ <i class="fas fa-eraser"></i>
200
+ </button>
201
+ <button id="text-tool" class="tool-btn p-2 border rounded hover:bg-gray-100" title="Text (T)">
202
+ <i class="fas fa-font"></i>
203
+ </button>
204
+ <button id="shape-tool" class="tool-btn p-2 border rounded hover:bg-gray-100" title="Shapes (S)">
205
+ <i class="fas fa-shapes"></i>
206
+ </button>
207
+ <button id="sticky-tool" class="tool-btn p-2 border rounded hover:bg-gray-100" title="Sticky Note (N)">
208
+ <i class="fas fa-sticky-note"></i>
209
+ </button>
210
+ <button id="laser-tool" class="tool-btn p-2 border rounded hover:bg-gray-100" title="Laser Pointer (L)">
211
+ <i class="fas fa-location-arrow"></i>
212
+ </button>
213
+ </div>
214
+
215
+ <!-- Brush Size -->
216
+ <div class="flex items-center space-x-1 border-r border-gray-200 pr-2">
217
+ <span class="text-sm text-gray-600">Size:</span>
218
+ <input id="brush-size" type="range" min="1" max="30" value="3" class="w-20">
219
+ <span id="brush-size-value" class="text-xs text-gray-600 w-6 text-center">3</span>
220
+ </div>
221
+
222
+ <!-- Colors -->
223
+ <div class="flex items-center space-x-1 border-r border-gray-200 pr-2">
224
+ <div class="color-option bg-black selected" data-color="#000000"></div>
225
+ <div class="color-option bg-red-500" data-color="#ef4444"></div>
226
+ <div class="color-option bg-yellow-500" data-color="#eab308"></div>
227
+ <div class="color-option bg-green-500" data-color="#22c55e"></div>
228
+ <div class="color-option bg-blue-500" data-color="#3b82f6"></div>
229
+ <div class="color-option bg-purple-500" data-color="#a855f7"></div>
230
+ <div class="color-option bg-pink-500" data-color="#ec4899"></div>
231
+ <div class="color-option bg-white border border-gray-300" data-color="#ffffff"></div>
232
+ </div>
233
+
234
+ <!-- Custom Color -->
235
+ <div class="flex items-center space-x-1">
236
+ <input type="color" id="custom-color" value="#000000" class="w-6 h-6 border border-gray-300 rounded cursor-pointer">
237
+ <span class="text-sm text-gray-600">Custom</span>
238
+ </div>
239
+ </div>
240
+
241
+ <div class="flex items-center space-x-2">
242
+ <button id="clear-btn" class="p-2 border rounded hover:bg-gray-100 text-red-500" title="Clear Board">
243
+ <i class="fas fa-trash-alt"></i>
244
+ </button>
245
+ <button id="save-btn" class="p-2 border rounded hover:bg-gray-100 text-green-500" title="Save Board">
246
+ <i class="fas fa-save"></i>
247
+ </button>
248
+ </div>
249
+ </div>
250
+
251
+ <!-- Whiteboard Canvas -->
252
+ <div class="flex-1 overflow-auto relative">
253
+ <canvas id="whiteboard" class="absolute top-0 left-0"></canvas>
254
+ </div>
255
+
256
+ <!-- Zoom Controls -->
257
+ <div class="bg-white border-t border-gray-200 p-2 flex items-center justify-between">
258
+ <div class="flex items-center space-x-2">
259
+ <button id="zoom-out" class="p-1.5 border rounded hover:bg-gray-100">
260
+ <i class="fas fa-search-minus"></i>
261
+ </button>
262
+ <span id="zoom-level" class="text-sm font-medium">100%</span>
263
+ <button id="zoom-in" class="p-1.5 border rounded hover:bg-gray-100">
264
+ <i class="fas fa-search-plus"></i>
265
+ </button>
266
+ <button id="zoom-fit" class="p-1.5 border rounded hover:bg-gray-100 text-sm ml-2">
267
+ Fit to Screen
268
+ </button>
269
+ </div>
270
+ <div class="text-sm text-gray-500">
271
+ <span id="cursor-position">0, 0</span>
272
+ </div>
273
+ </div>
274
+ </div>
275
+ </div>
276
+
277
+ <script>
278
+ document.addEventListener('DOMContentLoaded', function() {
279
+ // Canvas setup
280
+ const canvas = document.getElementById('whiteboard');
281
+ const ctx = canvas.getContext('2d');
282
+ let isDrawing = false;
283
+ let currentTool = 'pen';
284
+ let currentColor = '#000000';
285
+ let brushSize = 3;
286
+ let zoomLevel = 1;
287
+ let offsetX = 0;
288
+ let offsetY = 0;
289
+ let startX, startY;
290
+ let actionHistory = [];
291
+ let historyIndex = -1;
292
+ let boards = [];
293
+ let currentBoardIndex = -1;
294
+
295
+ // Initialize canvas size
296
+ function initCanvas() {
297
+ const container = canvas.parentElement;
298
+ canvas.width = container.clientWidth;
299
+ canvas.height = container.clientHeight;
300
+ redrawCanvas();
301
+ }
302
+
303
+ // Redraw everything on the canvas
304
+ function redrawCanvas() {
305
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
306
+
307
+ // Draw grid
308
+ ctx.fillStyle = '#e5e7eb';
309
+ const gridSize = 20 * zoomLevel;
310
+ for (let x = 0; x < canvas.width; x += gridSize) {
311
+ ctx.fillRect(x - offsetX % gridSize, 0, 1, canvas.height);
312
+ }
313
+ for (let y = 0; y < canvas.height; y += gridSize) {
314
+ ctx.fillRect(0, y - offsetY % gridSize, canvas.width, 1);
315
+ }
316
+
317
+ // Draw all actions
318
+ if (currentBoardIndex >= 0 && boards[currentBoardIndex]) {
319
+ const board = boards[currentBoardIndex];
320
+ for (let i = 0; i <= historyIndex; i++) {
321
+ drawAction(board.actions[i]);
322
+ }
323
+ }
324
+ }
325
+
326
+ // Draw a single action
327
+ function drawAction(action) {
328
+ if (!action) return;
329
+
330
+ ctx.strokeStyle = action.color || currentColor;
331
+ ctx.fillStyle = action.color || currentColor;
332
+ ctx.lineWidth = action.size || brushSize;
333
+ ctx.lineCap = 'round';
334
+ ctx.lineJoin = 'round';
335
+
336
+ switch (action.type) {
337
+ case 'freehand':
338
+ ctx.beginPath();
339
+ ctx.moveTo(action.points[0].x, action.points[0].y);
340
+ for (let i = 1; i < action.points.length; i++) {
341
+ ctx.lineTo(action.points[i].x, action.points[i].y);
342
+ }
343
+ ctx.stroke();
344
+ break;
345
+ case 'erase':
346
+ ctx.globalCompositeOperation = 'destination-out';
347
+ ctx.beginPath();
348
+ ctx.moveTo(action.points[0].x, action.points[0].y);
349
+ for (let i = 1; i < action.points.length; i++) {
350
+ ctx.lineTo(action.points[i].x, action.points[i].y);
351
+ }
352
+ ctx.stroke();
353
+ ctx.globalCompositeOperation = 'source-over';
354
+ break;
355
+ // Add cases for other action types (text, shapes, etc.)
356
+ }
357
+ }
358
+
359
+ // Save current state to history
360
+ function saveToHistory(action) {
361
+ if (currentBoardIndex >= 0) {
362
+ // If we're not at the end of history, remove future actions
363
+ if (historyIndex < boards[currentBoardIndex].actions.length - 1) {
364
+ boards[currentBoardIndex].actions = boards[currentBoardIndex].actions.slice(0, historyIndex + 1);
365
+ }
366
+
367
+ boards[currentBoardIndex].actions.push(action);
368
+ historyIndex++;
369
+ updateUndoRedoButtons();
370
+ }
371
+ }
372
+
373
+ // Undo last action
374
+ function undo() {
375
+ if (historyIndex >= 0) {
376
+ historyIndex--;
377
+ redrawCanvas();
378
+ updateUndoRedoButtons();
379
+ }
380
+ }
381
+
382
+ // Redo last undone action
383
+ function redo() {
384
+ if (currentBoardIndex >= 0 && historyIndex < boards[currentBoardIndex].actions.length - 1) {
385
+ historyIndex++;
386
+ drawAction(boards[currentBoardIndex].actions[historyIndex]);
387
+ updateUndoRedoButtons();
388
+ }
389
+ }
390
+
391
+ // Update undo/redo button states
392
+ function updateUndoRedoButtons() {
393
+ document.getElementById('undo-btn').disabled = historyIndex < 0;
394
+ document.getElementById('redo-btn').disabled =
395
+ currentBoardIndex < 0 || historyIndex >= boards[currentBoardIndex].actions.length - 1;
396
+ }
397
+
398
+ // Create a new board
399
+ function createNewBoard() {
400
+ const newBoard = {
401
+ id: Date.now(),
402
+ title: `Board ${boards.length + 1}`,
403
+ actions: [],
404
+ createdAt: new Date()
405
+ };
406
+
407
+ boards.push(newBoard);
408
+ currentBoardIndex = boards.length - 1;
409
+ historyIndex = -1;
410
+
411
+ // Add to sidebar
412
+ addBoardToSidebar(newBoard);
413
+
414
+ // Clear canvas
415
+ redrawCanvas();
416
+ updateUndoRedoButtons();
417
+ }
418
+
419
+ // Add board to sidebar
420
+ function addBoardToSidebar(board) {
421
+ const boardElement = document.createElement('div');
422
+ boardElement.className = 'board-thumbnail bg-white p-2 rounded-lg border border-gray-200 cursor-pointer';
423
+ boardElement.innerHTML = `
424
+ <div class="bg-gray-100 h-24 rounded-md mb-2 flex items-center justify-center">
425
+ <i class="fas fa-chalkboard text-gray-400 text-2xl"></i>
426
+ </div>
427
+ <h4 class="font-medium text-sm truncate">${board.title}</h4>
428
+ <p class="text-xs text-gray-500">Just now</p>
429
+ `;
430
+
431
+ boardElement.addEventListener('click', () => {
432
+ // Switch to this board
433
+ const index = boards.findIndex(b => b.id === board.id);
434
+ if (index >= 0) {
435
+ currentBoardIndex = index;
436
+ historyIndex = boards[currentBoardIndex].actions.length - 1;
437
+ redrawCanvas();
438
+ updateUndoRedoButtons();
439
+ }
440
+ });
441
+
442
+ document.getElementById('boards-list').prepend(boardElement);
443
+ }
444
+
445
+ // Event listeners for drawing
446
+ canvas.addEventListener('mousedown', startDrawing);
447
+ canvas.addEventListener('mousemove', draw);
448
+ canvas.addEventListener('mouseup', stopDrawing);
449
+ canvas.addEventListener('mouseout', stopDrawing);
450
+
451
+ // Touch events for mobile
452
+ canvas.addEventListener('touchstart', handleTouchStart);
453
+ canvas.addEventListener('touchmove', handleTouchMove);
454
+ canvas.addEventListener('touchend', handleTouchEnd);
455
+
456
+ function startDrawing(e) {
457
+ isDrawing = true;
458
+
459
+ const rect = canvas.getBoundingClientRect();
460
+ startX = (e.clientX - rect.left - offsetX) / zoomLevel;
461
+ startY = (e.clientY - rect.top - offsetY) / zoomLevel;
462
+
463
+ if (currentTool === 'pen' || currentTool === 'highlighter' || currentTool === 'eraser') {
464
+ const action = {
465
+ type: currentTool === 'eraser' ? 'erase' : 'freehand',
466
+ color: currentTool === 'highlighter' ? currentColor + '80' : currentColor,
467
+ size: brushSize,
468
+ points: [{ x: startX, y: startY }]
469
+ };
470
+
471
+ if (currentBoardIndex >= 0) {
472
+ boards[currentBoardIndex].actions.push(action);
473
+ historyIndex = boards[currentBoardIndex].actions.length - 1;
474
+ }
475
+ }
476
+
477
+ draw(e);
478
+ }
479
+
480
+ function draw(e) {
481
+ if (!isDrawing) return;
482
+
483
+ const rect = canvas.getBoundingClientRect();
484
+ const x = (e.clientX - rect.left - offsetX) / zoomLevel;
485
+ const y = (e.clientY - rect.top - offsetY) / zoomLevel;
486
+
487
+ // Update cursor position display
488
+ document.getElementById('cursor-position').textContent =
489
+ `${Math.round(x)}, ${Math.round(y)}`;
490
+
491
+ if (currentTool === 'pen' || currentTool === 'highlighter' || currentTool === 'eraser') {
492
+ if (currentBoardIndex >= 0 && boards[currentBoardIndex].actions.length > 0) {
493
+ const lastAction = boards[currentBoardIndex].actions[historyIndex];
494
+ if (lastAction && (lastAction.type === 'freehand' || lastAction.type === 'erase')) {
495
+ lastAction.points.push({ x, y });
496
+ redrawCanvas();
497
+ }
498
+ }
499
+ }
500
+ }
501
+
502
+ function stopDrawing() {
503
+ isDrawing = false;
504
+ }
505
+
506
+ // Touch event handlers
507
+ function handleTouchStart(e) {
508
+ e.preventDefault();
509
+ const touch = e.touches[0];
510
+ const mouseEvent = new MouseEvent('mousedown', {
511
+ clientX: touch.clientX,
512
+ clientY: touch.clientY
513
+ });
514
+ startDrawing(mouseEvent);
515
+ }
516
+
517
+ function handleTouchMove(e) {
518
+ e.preventDefault();
519
+ const touch = e.touches[0];
520
+ const mouseEvent = new MouseEvent('mousemove', {
521
+ clientX: touch.clientX,
522
+ clientY: touch.clientY
523
+ });
524
+ draw(mouseEvent);
525
+ }
526
+
527
+ function handleTouchEnd(e) {
528
+ e.preventDefault();
529
+ const mouseEvent = new MouseEvent('mouseup', {});
530
+ stopDrawing(mouseEvent);
531
+ }
532
+
533
+ // Tool selection
534
+ document.querySelectorAll('.tool-btn').forEach(btn => {
535
+ btn.addEventListener('click', function() {
536
+ document.querySelectorAll('.tool-btn').forEach(b => b.classList.remove('active'));
537
+ this.classList.add('active');
538
+
539
+ switch (this.id) {
540
+ case 'select-tool': currentTool = 'select'; break;
541
+ case 'pen-tool': currentTool = 'pen'; break;
542
+ case 'highlighter-tool': currentTool = 'highlighter'; break;
543
+ case 'eraser-tool': currentTool = 'eraser'; break;
544
+ case 'text-tool': currentTool = 'text'; break;
545
+ case 'shape-tool': currentTool = 'shape'; break;
546
+ case 'sticky-tool': currentTool = 'sticky'; break;
547
+ case 'laser-tool': currentTool = 'laser'; break;
548
+ }
549
+
550
+ // Change cursor based on tool
551
+ if (currentTool === 'pen' || currentTool === 'highlighter') {
552
+ canvas.style.cursor = 'crosshair';
553
+ } else if (currentTool === 'eraser') {
554
+ canvas.style.cursor = 'url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\' width=\'16\' height=\'16\' viewBox=\'0 0 16 16\'><circle cx=\'8\' cy=\'8\' r=\'8\' fill=\'black\'/></svg>") 8 8, auto';
555
+ } else {
556
+ canvas.style.cursor = 'default';
557
+ }
558
+ });
559
+ });
560
+
561
+ // Color selection
562
+ document.querySelectorAll('.color-option').forEach(option => {
563
+ option.addEventListener('click', function() {
564
+ document.querySelectorAll('.color-option').forEach(o => o.classList.remove('selected'));
565
+ this.classList.add('selected');
566
+ currentColor = this.dataset.color;
567
+ document.getElementById('custom-color').value = currentColor;
568
+ });
569
+ });
570
+
571
+ // Custom color picker
572
+ document.getElementById('custom-color').addEventListener('input', function() {
573
+ currentColor = this.value;
574
+ // Find and select the matching color option if it exists
575
+ let found = false;
576
+ document.querySelectorAll('.color-option').forEach(option => {
577
+ if (option.dataset.color.toLowerCase() === currentColor.toLowerCase()) {
578
+ option.classList.add('selected');
579
+ found = true;
580
+ } else {
581
+ option.classList.remove('selected');
582
+ }
583
+ });
584
+
585
+ if (!found) {
586
+ document.querySelectorAll('.color-option').forEach(o => o.classList.remove('selected'));
587
+ }
588
+ });
589
+
590
+ // Brush size
591
+ document.getElementById('brush-size').addEventListener('input', function() {
592
+ brushSize = this.value;
593
+ document.getElementById('brush-size-value').textContent = brushSize;
594
+ });
595
+
596
+ // Zoom controls
597
+ document.getElementById('zoom-in').addEventListener('click', function() {
598
+ zoomLevel = Math.min(zoomLevel * 1.2, 5);
599
+ updateZoomDisplay();
600
+ redrawCanvas();
601
+ });
602
+
603
+ document.getElementById('zoom-out').addEventListener('click', function() {
604
+ zoomLevel = Math.max(zoomLevel / 1.2, 0.2);
605
+ updateZoomDisplay();
606
+ redrawCanvas();
607
+ });
608
+
609
+ document.getElementById('zoom-fit').addEventListener('click', function() {
610
+ zoomLevel = 1;
611
+ offsetX = 0;
612
+ offsetY = 0;
613
+ updateZoomDisplay();
614
+ redrawCanvas();
615
+ });
616
+
617
+ function updateZoomDisplay() {
618
+ document.getElementById('zoom-level').textContent = `${Math.round(zoomLevel * 100)}%`;
619
+ }
620
+
621
+ // Undo/redo buttons
622
+ document.getElementById('undo-btn').addEventListener('click', undo);
623
+ document.getElementById('redo-btn').addEventListener('click', redo);
624
+
625
+ // Keyboard shortcuts
626
+ document.addEventListener('keydown', function(e) {
627
+ // Ctrl+Z for undo
628
+ if (e.ctrlKey && e.key === 'z') {
629
+ e.preventDefault();
630
+ undo();
631
+ }
632
+ // Ctrl+Y for redo
633
+ else if (e.ctrlKey && e.key === 'y') {
634
+ e.preventDefault();
635
+ redo();
636
+ }
637
+ });
638
+
639
+ // New board button
640
+ document.getElementById('new-board-btn').addEventListener('click', createNewBoard);
641
+
642
+ // Clear button
643
+ document.getElementById('clear-btn').addEventListener('click', function() {
644
+ if (confirm('Are you sure you want to clear the board?')) {
645
+ if (currentBoardIndex >= 0) {
646
+ boards[currentBoardIndex].actions = [];
647
+ historyIndex = -1;
648
+ redrawCanvas();
649
+ updateUndoRedoButtons();
650
+ }
651
+ }
652
+ });
653
+
654
+ // Save button
655
+ document.getElementById('save-btn').addEventListener('click', function() {
656
+ alert('Board saved!');
657
+ // In a real app, this would save to localStorage or a server
658
+ });
659
+
660
+ // Initialize
661
+ initCanvas();
662
+ window.addEventListener('resize', initCanvas);
663
+
664
+ // Create first board
665
+ createNewBoard();
666
+ });
667
+ </script>
668
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=madansa7/board" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
669
+ </html>
prompts.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ 🧾 Prompt: Online Whiteboard Web App for Teaching & Collaboration 🎯 Objective Build a clean, intuitive online whiteboard that combines the simplicity of Google Keep’s Notes UI with robust drawing, zooming, and content-saving capabilities for teaching, brainstorming, or personal note-taking. Should work seamlessly on desktop, tablet, and mobile. 🧰 Core Features 🖼️ Canvas & Drawing Tools Infinite or scrollable whiteboard space (similar to Miro or Excalidraw). Pen tool with multiple brush sizes. Color palette with custom hex support. Highlighter tool (semi-transparent ink). Eraser (soft and hard modes). Text tool with basic formatting (font size, color, bold, italic). Shape tool (rectangle, circle, arrow, line). Sticky Notes that can be moved or minimized. 🔍 Smart Interaction Features Lasso tool or selection mode to grab and move drawn content or text. Pinch to zoom (mobile/tablet) or scroll to zoom (desktop). Pan/drag mode for navigating large boards. Zoom-to-selection feature to focus on any drawn/selected area. 💾 Save & Export Save to cloud (Google Drive, Firebase, or local storage for MVP). Export board as: PNG or JPEG (cropped to content) PDF (with optional background grid) SVG (for vector drawings) Auto-save every few seconds or after any interaction. 🗃️ Board Management Create multiple boards with titles and tags. Quick thumbnail preview for each saved board. Duplicate, delete, or rename boards. 👩‍🏫 Teaching & Presentation Mode Laser pointer mode (click-and-hold to show a pointer circle). Fullscreen mode for teaching. Optional voice recorder to sync voice notes with board activity. Real-time sync or sharing via a URL (use Firebase or WebRTC for MVP collaboration).
2
+ not able to draw anythng in the board and new board button does not wokr, does not need math class notes, have undo redo button, select option in tools tray,