Skip to content

Instantly share code, notes, and snippets.

@nicodevs
Created June 18, 2025 17:47
Show Gist options
  • Save nicodevs/d57025a96259bce8cadee23dbe79670a to your computer and use it in GitHub Desktop.
Save nicodevs/d57025a96259bce8cadee23dbe79670a to your computer and use it in GitHub Desktop.
Guess This Drawing!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Guess This Drawing!</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://fonts.googleapis.com/css2?family=Bowlby+One+SC&display=swap" rel="stylesheet">
</head>
<body class="min-h-screen flex flex-col items-center justify-center gap-6 bg-gradient-to-br from-slate-50 to-indigo-100 px-4" style="font-family: 'Bowlby One SC', cursive;">
<h1 class="text-center text-balance text-4xl text-transparent bg-clip-text bg-gradient-to-r from-indigo-500 to-indigo-600 drop-shadow-lg md:text-5xl">
Guess This Drawing!
</h1>
<canvas id="sketchpad" width="500" height="500" class="shadow-xl rounded-2xl bg-white border-4 border-black"></canvas>
<form id="form" action="/guess" method="POST" enctype="multipart/form-data" class="text-4xl">
@csrf
<button type="submit" class="bg-gradient-to-r from-indigo-500 to-indigo-400 text-white rounded-lg px-8 py-3 shadow-md hover:from-indigo-600 hover:to-indigo-500 hover:shadow-xl focus:outline-none focus:ring-2 focus:ring-indigo-400 transition">
Guess 🤔
</button>
</form>
<script>
const canvas = document.getElementById('sketchpad');
if (window.innerWidth < 500) {
canvas.width = canvas.parentElement.clientWidth - 40;
canvas.height = canvas.width;
}
const ctx = canvas.getContext('2d');
ctx.lineWidth = 5;
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, canvas.width, canvas.height);
let drawing = false;
canvas.addEventListener('mousedown', (e) => {
drawing = true;
ctx.beginPath();
ctx.moveTo(e.offsetX, e.offsetY);
});
canvas.addEventListener('mousemove', (e) => {
if (!drawing) return;
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
});
canvas.addEventListener('mouseup', () => {
drawing = false;
});
canvas.addEventListener('mouseleave', () => {
drawing = false;
});
canvas.addEventListener('touchstart', (e) => {
e.preventDefault();
drawing = true;
const rect = canvas.getBoundingClientRect();
const touch = e.touches[0];
ctx.beginPath();
ctx.moveTo(touch.clientX - rect.left, touch.clientY - rect.top);
}, {
passive: false
});
canvas.addEventListener('touchmove', (e) => {
if (!drawing) return;
e.preventDefault();
const rect = canvas.getBoundingClientRect();
const touch = e.touches[0];
ctx.lineTo(touch.clientX - rect.left, touch.clientY - rect.top);
ctx.stroke();
}, {
passive: false
});
canvas.addEventListener('touchend', () => {
drawing = false;
});
canvas.addEventListener('touchcancel', () => {
drawing = false;
});
const form = document.getElementById('form');
form.addEventListener('submit', async (e) => {
e.preventDefault();
const formData = new FormData(form);
canvas.toBlob(async function (blob) {
formData.append('image', blob, 'drawing.png');
form.querySelector('button').textContent = 'Guessing...';
form.querySelector('button').disabled = true;
const guess = await fetch(form.action, {
method: 'POST',
body: formData
});
form.innerHTML = await guess.text();
}, 'image/png');
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment