DEV Community

Cover image for A Circle Without Circle in neal.fun
Sanz
Sanz

Posted on

A Circle Without Circle in neal.fun

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);
Enter fullscreen mode Exit fullscreen mode

What it actually does

  1. Finds the drawing area on the page
  2. Finds the center dot (the target)
  3. Calculates points on a perfect circle using basic trig (cos and sin — the only thing I remember from school)
  4. 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

  1. Go to neal.fun/perfect-circle/
  2. Press F12 → Console tab
  3. Paste the code, hit Enter
  4. 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)