I cheated at drawing a circle on neal.fun :)
So there's this game
neal.fun has a game where you just... draw a circle. That's it. Hold mouse, draw circle, get scored.
I thought "how hard can it be."
Reader, I got 35%.
I tried slow. I tried fast. I tried holding my breath like that helps. I tried tracing a actual round object on my screen with my finger like a complete weirdo. My best was somewhere around 40% and even that felt like a gift.
My circles looked like someone described a circle to a person who had never seen one.
The moment I gave up and opened the console
After way too many attempts, I had a thought.
The site listens to mouse events. Mouse events are just little JavaScript objects with x and y coordinates. What if instead of using my dumb, bad, broken human hand... I just made JavaScript send fake mouse events that trace a perfect circle?
The browser can't tell if a mouse event came from a real mouse or from code. They look exactly the same. So I opened DevTools, and started writing.
The part where I tried 180 and got a line
The script moves around the circle by jumping a fixed number of degrees each step. I called this variable diff.
My testing went like this:
| what I tried | what happened |
|---|---|
| diff = 8 | Beautiful perfect circle. Also took 45 seconds. I aged. |
| diff = 10 | Still slow. My grandma draws faster. |
| diff = 180 | Drew a straight line. Just a line. Back and forth. I stared at it. |
| diff = 179 | Cursor went absolutely feral across the screen. Scored 99.8%. |
I want to be very clear: diff = 179 does not draw a circle. If you watch it run, the cursor is random three lines on the place like it drank too much coffee. It looks completely wrong. And then it scores 99.8%.
Meanwhile diff = 180, which looks like it should be "halfway around the circle", just draws a line and gives up on life by telling "Wrong Way"
One degree of difference. That's it. 180 = failure. 179 = glory.
I don't fully understand it either and I wrote the code.
check out my Github: github.com/sanz-s/neal-fun-draw-perfect-circle/
The code
Open the console on neal.fun/draw-a-perfect-circle, paste this, hit Enter:
let el = document.querySelector("#__layout > div > div > main > section > div");
let dotBound = document.querySelector("#__layout > div > div > main > header > button").getBoundingClientRect();
let r = 400;
let gap = 10;
let diff = 179; // not 180. never 180. 180 is a liar.
let cx = dotBound.x + (dotBound.width / 2);
let cy = dotBound.y + (dotBound.height / 2);
function createEvent(type, x, y) {
let e = new MouseEvent(type, {
bubbles: true,
cancelable: true,
clientX: x,
clientY: y
});
el.dispatchEvent(e);
}
function getPoint(deg) {
const rad = (deg % 360) * (Math.PI / 180);
return {
x: cx + r * Math.cos(rad),
y: cy + r * Math.sin(rad)
};
}
let d = 0;
createEvent('mousedown', getPoint(d).x, getPoint(d).y);
let interval = setInterval(function () {
d += diff;
createEvent('mousemove', getPoint(d).x, getPoint(d).y);
if (d == 360) {
clearInterval(interval);
createEvent('mouseup', getPoint(d).x, getPoint(d).y);
}
}, gap);
What it actually does
- Finds the drawing area on the page
- Finds the center dot (the target)
- Calculates points on a perfect circle using basic trig (cos and sin — the only thing I remember from school)
- Fires fake mouse events at those points, 10ms apart
The cursor looks like it's panicking. It teleports around the screen in no obvious order. Any human watching would think something is very wrong.
The scoring algorithm looks at where the cursor actually went, connects all the dots, and goes "oh that's a circle." 99.8%.
Why not 100%?
No idea honestly. Maybe the site smooths the path a bit. Maybe it can sense the dishonesty. Maybe 0.2% is the universe's way of saying "we saw what you did."
I'll take it.
How to run it
- Go to neal.fun/perfect-circle/
- Press F12 → Console tab
- Paste the code, hit Enter
- Watch the cursor have a meltdown and somehow win
Personal hand score: 30–40%. Will not be accepting, Why ?.
See You Around Soon :)
Top comments (0)