Skip to content

Commit 705873a

Browse files
Add files via upload
0 parents  commit 705873a

File tree

3 files changed

+197
-0
lines changed

3 files changed

+197
-0
lines changed

index.html

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
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>Responsive Whiteboard</title>
7+
<link
8+
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
9+
rel="stylesheet"
10+
/>
11+
<link
12+
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css"
13+
rel="stylesheet"
14+
/>
15+
<link rel="stylesheet" href="style.css" />
16+
</head>
17+
<body>
18+
<!-- Navigation Bar -->
19+
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
20+
<div class="container-fluid">
21+
<a class="navbar-brand" href="#">Whiteboard</a>
22+
<button
23+
class="navbar-toggler"
24+
type="button"
25+
data-bs-toggle="collapse"
26+
data-bs-target="#navbarNav"
27+
>
28+
<span class="navbar-toggler-icon"></span>
29+
</button>
30+
<div class="collapse navbar-collapse" id="navbarNav">
31+
<ul class="navbar-nav ms-auto">
32+
<li class="nav-item">
33+
<a
34+
href="#"
35+
id="fullscreen"
36+
class="nav-link"
37+
title="Fullscreen"
38+
>
39+
<i class="fas fa-expand"></i>
40+
</a>
41+
</li>
42+
</ul>
43+
</div>
44+
</div>
45+
</nav>
46+
47+
<!-- Flexbox Container -->
48+
<div class="d-flex flex-column vh-100">
49+
<!-- Controls Section -->
50+
<div id="controls" class="d-flex justify-content-around align-items-center bg-light p-3">
51+
<div>
52+
<label for="color" class="form-label">Brush Color</label>
53+
<input type="color" id="color" class="form-control form-control-color" value="#000000" />
54+
</div>
55+
<div>
56+
<label for="size" class="form-label">Brush Size</label>
57+
<input
58+
type="number"
59+
id="size"
60+
class="form-control"
61+
min="2"
62+
max="50"
63+
value="10"
64+
step="1"
65+
/>
66+
</div>
67+
<button id="clear" class="btn btn-danger">Clear</button>
68+
<button id="save" class="btn btn-success">Save Image</button>
69+
<div>
70+
<label for="upload" class="form-label">Upload Image</label>
71+
<input type="file" id="upload" class="form-control" accept="image/*" />
72+
</div>
73+
</div>
74+
75+
<!-- Canvas Section -->
76+
<div class="flex-grow-1 d-flex justify-content-center align-items-center bg-white">
77+
<canvas id="whiteboard"></canvas>
78+
</div>
79+
</div>
80+
81+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
82+
<script src="script.js"></script>
83+
</body>
84+
</html>

script.js

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// Variables for canvas
2+
const canvas = document.getElementById("whiteboard");
3+
const ctx = canvas.getContext("2d");
4+
5+
// Set canvas to fill available space dynamically
6+
function resizeCanvas() {
7+
canvas.width = canvas.parentElement.offsetWidth;
8+
canvas.height = canvas.parentElement.offsetHeight;
9+
}
10+
resizeCanvas();
11+
window.addEventListener("resize", resizeCanvas);
12+
13+
// Variables for drawing
14+
let isDrawing = false;
15+
let brushColor = "#000000";
16+
let brushSize = 10;
17+
18+
// Event listeners for drawing
19+
canvas.addEventListener("mousedown", startDrawing);
20+
canvas.addEventListener("mousemove", draw);
21+
canvas.addEventListener("mouseup", stopDrawing);
22+
canvas.addEventListener("mouseout", stopDrawing);
23+
24+
// Event listeners for controls
25+
document.getElementById("color").addEventListener("input", (e) => {
26+
brushColor = e.target.value;
27+
});
28+
29+
document.getElementById("size").addEventListener("input", (e) => {
30+
const value = parseInt(e.target.value, 10);
31+
if (value >= 2 && value <= 50) {
32+
brushSize = value;
33+
}
34+
});
35+
36+
document.getElementById("clear").addEventListener("click", clearCanvas);
37+
38+
document.getElementById("save").addEventListener("click", saveImage);
39+
40+
document.getElementById("upload").addEventListener("change", uploadImage);
41+
42+
document.getElementById("fullscreen").addEventListener("click", () => {
43+
document.documentElement.requestFullscreen();
44+
});
45+
46+
// Drawing functions
47+
function startDrawing(e) {
48+
isDrawing = true;
49+
ctx.beginPath();
50+
ctx.moveTo(e.offsetX, e.offsetY);
51+
}
52+
53+
function draw(e) {
54+
if (!isDrawing) return;
55+
56+
ctx.lineWidth = brushSize;
57+
ctx.lineCap = "round";
58+
ctx.strokeStyle = brushColor;
59+
60+
ctx.lineTo(e.offsetX, e.offsetY);
61+
ctx.stroke();
62+
}
63+
64+
function stopDrawing() {
65+
isDrawing = false;
66+
ctx.closePath();
67+
}
68+
69+
// Clear the canvas
70+
function clearCanvas() {
71+
ctx.clearRect(0, 0, canvas.width, canvas.height);
72+
}
73+
74+
// Save the canvas as an image
75+
function saveImage() {
76+
const link = document.createElement("a");
77+
link.download = "whiteboard.png";
78+
link.href = canvas.toDataURL("image/png");
79+
link.click();
80+
}
81+
82+
// Upload an image to the canvas
83+
function uploadImage(e) {
84+
const file = e.target.files[0];
85+
if (!file) return;
86+
87+
const reader = new FileReader();
88+
reader.onload = () => {
89+
const img = new Image();
90+
img.onload = () => {
91+
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
92+
};
93+
img.src = reader.result;
94+
};
95+
reader.readAsDataURL(file);
96+
}

style.css

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/* Ensure full coverage of canvas */
2+
html,
3+
body {
4+
margin: 0;
5+
padding: 0;
6+
height: 100%;
7+
width: 100%;
8+
}
9+
10+
#whiteboard {
11+
border: 1px solid #ccc;
12+
background-color: white;
13+
display: block;
14+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
15+
width: 100%;
16+
height: 100%;
17+
}

0 commit comments

Comments
 (0)