A cursor-driven field of arrows using atan2 and vector normalization.
Move your cursor over the field. Each arrow calculates the angle to your cursor using atan2 and rotates accordingly.
One arrow. Move your cursor and watch Math.atan2(dy, dx) calculate the angle between the arrow's center and your cursor position. The result is in radians, multiply by 180 / Math.PI to get degrees.
0.0°
Same arrow, but now the length scales with distance from the center. Close to the center means a short arrow. Move to the edges and the arrow stretches. This is the raw, unnormalized version.
0px
Fix the length. Now the arrow always points at the same distance, only the direction changes. This is what you want for a uniform field. Move to the edges and compare with Step 2.
Length is always 80px. Only angle changes.
Put 16 arrows in a 4x4 grid. Each one independently calculates its angle to the cursor. This is the DOM approach, 16 separate elements, each with its own rotation.
Loading...
The same 8x8 grid, but rendered with <canvas>. One requestAnimationFrame loop redraws 64 arrows every frame. No DOM overhead, no layout thrashing.
Loading...
The canvas version handles 64 arrows without breaking a sweat. The DOM version creates 64 separate elements, each one triggers paint and compositing on every frame.
Canvas (imperative)
DOM (declarative)
Tweak the arrow size, grid density, and normalization. The code updates in real-time.
Loading...