Skip to content

Commit e2c6e26

Browse files
Add files via upload
1 parent 0e954c2 commit e2c6e26

1 file changed

Lines changed: 244 additions & 0 deletions

File tree

PerfectDrawingSoFar.html

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<!-- TO DO
4+
colour switch
5+
confirm Clear
6+
retrieve uploaded images
7+
save icon visual confirmation
8+
9+
-->
10+
<head>
11+
<meta charset="UTF-8">
12+
<title>Best Drawing</title>
13+
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
14+
<style>
15+
html, body {
16+
background-color: white;
17+
margin: 0; padding: 0; height: 100%;
18+
overflow: hidden;
19+
}
20+
body {
21+
display: grid;
22+
place-items: center;
23+
}
24+
button {
25+
margin: 0 5px;
26+
font-size: 1rem;
27+
}
28+
</style>
29+
</head>
30+
<body>
31+
<canvas id="c" width="600" height="600" style="border: 1px solid black; width: 600px; height: 600px; image-rendering: pixelated; touch-action: none;"></canvas>
32+
<div id="buttons" style="display: flex; justify-content: center; align-items: center;">
33+
<img onclick="toggleEraser()" id="toolpic" src="https://files.reimage.dev/filesghs/a459809638ee/original" width="60" height="60">
34+
<img onclick="toggleBrushSize()" id="brushsize" src="https://files.reimage.dev/filesghs/e291bce2b8ae/original" width="60" height="60">
35+
<img onclick="upload()" src="https://files.reimage.dev/filesghs/ae4d320d50bb/original" width="60" height="60">
36+
<img onclick="clearCanvas()" id="clearState" src="https://files.reimage.dev/filesghs/1ffb5bbb8772/original" width="60" height="60">
37+
</div>
38+
<img src="https://files.reimage.dev/filesghs/d293f3c9c999/original" width="60" height="60" onclick="alert('designed by dr. art, M.D. please try to produce as much anti corporate slop.')">
39+
</div>
40+
<script>
41+
const API_KEY = "9c66638c1adf8ae793f0237f52f2b26355de5045da146f606322f966925a3625";
42+
const canvas = document.getElementById("c");
43+
const ctx = canvas.getContext("2d");
44+
ctx.imageSmoothingEnabled = false;
45+
46+
let drawing = false, x = 0, y = 0, lastX = 0, lastY = 0, lastTime = 0;
47+
let maxSize = 10;
48+
let currentBrushIndex = 0;
49+
let currentToolIndex = 0;
50+
let currentClearIndex = 0;
51+
let isEraser = false;
52+
53+
54+
//brush size pics
55+
const brushSources = [
56+
"https://files.reimage.dev/filesghs/e291bce2b8ae/original", // large
57+
"https://files.reimage.dev/filesghs/f88f8323042b/original", // medium
58+
"https://files.reimage.dev/filesghs/a5509d0a4c71/original", // small
59+
"https://files.reimage.dev/filesghs/32535a74784d/original" // x-large
60+
];
61+
62+
//tool pics
63+
const toolSources = [
64+
"https://files.reimage.dev/filesghs/a459809638ee/original", // pencil
65+
"https://files.reimage.dev/filesghs/f277250a14fb/original", // eraser
66+
];
67+
68+
//clear pics
69+
const clearSources = [
70+
"https://files.reimage.dev/filesghs/1ffb5bbb8772/original", // clear!
71+
"https://files.reimage.dev/filesghs/7144fa6f69d2/original", // you sure?
72+
];
73+
74+
75+
//clear canvas function
76+
function clearCanvas() {
77+
if (currentClearIndex === 1) {
78+
ctx.clearRect(0, 0, canvas.width, canvas.height);
79+
currentClearIndex = 0;
80+
document.getElementById('clearState').src = clearSources[0];
81+
} else {
82+
preClear();
83+
}
84+
}
85+
//confirmation for clearing
86+
function preClear() {
87+
const clearElement = document.getElementById('clearState');
88+
currentClearIndex = (currentClearIndex + 1) % clearSources.length;
89+
clearElement.src = clearSources[currentClearIndex];
90+
if (currentClearIndex === 1) {
91+
setTimeout(() => {
92+
currentClearIndex = 0;
93+
clearElement.src = clearSources[0];
94+
}, 2000);
95+
}
96+
}
97+
98+
99+
100+
// Function to toggle brush size between 6, 10, and 3
101+
function toggleBrushSize() {
102+
maxSize = (maxSize === 10) ? 6 :
103+
(maxSize === 6) ? 3 :
104+
(maxSize === 3) ? 20 : 10;
105+
const brushElement = document.getElementById('brushsize');
106+
currentBrushIndex = (currentBrushIndex + 1) % brushSources.length;
107+
brushElement.src = brushSources[currentBrushIndex];
108+
}
109+
110+
// Function to toggle between drawing and erasing mode
111+
function toggleEraser() {
112+
isEraser = !isEraser;
113+
const toolElement = document.getElementById('toolpic');
114+
currentToolIndex = (currentToolIndex + 1) % toolSources.length;
115+
toolElement.src = toolSources[currentToolIndex];
116+
}
117+
118+
// Function to calculate velocity-based brush size
119+
function calculateBrushSize(newX, newY) {
120+
const now = performance.now();
121+
const deltaTime = now - lastTime;
122+
const dx = newX - lastX;
123+
const dy = newY - lastY;
124+
const distance = Math.sqrt(dx * dx + dy * dy);
125+
const speed = distance / (deltaTime || 1);
126+
127+
const minSize = 0;
128+
const velocity = Math.min(speed, 100); // clamp max speed
129+
const size = maxSize - (velocity / 2) * (maxSize - minSize);
130+
131+
lastX = newX;
132+
lastY = newY;
133+
lastTime = now;
134+
135+
return size;
136+
}
137+
138+
139+
// Upload the drawing
140+
function upload() {
141+
canvas.toBlob(async blob => {
142+
const formData = new FormData();
143+
formData.append("file", blob, "drawing.png");
144+
formData.append("tags", JSON.stringify(["drawing"]));
145+
146+
try {
147+
const res = await fetch("https://api.reimage.dev/upload/", {
148+
method: "POST",
149+
headers: { Authorization: `Bearer ${API_KEY}` },
150+
body: formData
151+
152+
});
153+
154+
const data = await res.json();
155+
alert("success");
156+
} catch (err) {
157+
console.error("Upload failed.");
158+
alert("Upload failed.");
159+
}
160+
}, "image/png");
161+
}
162+
163+
164+
165+
166+
// Drawing function
167+
168+
function drawLine(newX, newY,) {
169+
const size = calculateBrushSize(newX, newY,);
170+
ctx.lineWidth = size;
171+
ctx.beginPath();
172+
ctx.moveTo(x, y);
173+
ctx.lineTo(newX, newY);
174+
ctx.stroke();
175+
ctx.lineCap = "square";
176+
}
177+
178+
// Mouse events for drawing
179+
canvas.onmousedown = e => {
180+
drawing = true;
181+
x = e.offsetX;
182+
y = e.offsetY;
183+
lastX = x;
184+
lastY = y;
185+
lastTime = performance.now();
186+
};
187+
canvas.onmouseup = () => { drawing = false; };
188+
canvas.onmousemove = e => {
189+
if (drawing) {
190+
if (isEraser) {
191+
ctx.clearRect(e.offsetX - maxSize / 2, e.offsetY - maxSize / 2, (maxSize*2), (maxSize*2));
192+
} else {
193+
drawLine(e.offsetX, e.offsetY);
194+
}
195+
x = e.offsetX;
196+
y = e.offsetY;
197+
}};
198+
199+
// Mobile touch events for drawing
200+
canvas.addEventListener('touchstart', e => {
201+
e.preventDefault();
202+
const touch = e.touches[0];
203+
const rect = canvas.getBoundingClientRect();
204+
x = touch.clientX - rect.left;
205+
y = touch.clientY - rect.top;
206+
lastX = x;
207+
lastY = y;
208+
lastTime = performance.now();
209+
drawing = true;
210+
});
211+
canvas.addEventListener('touchmove', e => {
212+
if (!drawing) return;
213+
e.preventDefault();
214+
const touch = e.touches[0];
215+
const rect = canvas.getBoundingClientRect();
216+
const newX = touch.clientX - rect.left;
217+
const newY = touch.clientY - rect.top;
218+
if (isEraser) {
219+
ctx.clearRect(newX - maxSize / 2, newY - maxSize / 2, (maxSize*2), (maxSize*2));
220+
} else {
221+
drawLine(newX, newY);
222+
}
223+
x = newX;
224+
y = newY;
225+
});
226+
canvas.addEventListener('touchend', () => { drawing = false; });
227+
228+
addEventListener("keydown", (event) => {
229+
if (event.key === "c" || event.key === "C") {
230+
clearCanvas();
231+
}
232+
if (event.key === "x" || event.key === "X") {
233+
upload();
234+
}
235+
if (event.key === "z" || event.key === "Z") {
236+
toggleBrushSize();
237+
}
238+
if (event.key === "Shift" && event.location === 1) {
239+
toggleEraser();
240+
}
241+
});
242+
</script>
243+
</body>
244+
</html>

0 commit comments

Comments
 (0)