Urgent.News

What's breaking now, across thousands of outlets.

Tech

How I built a live halftone portrait in React with just Canvas 2D

My portfolio is set like a newspaper, so my photo couldn't just be a photo. I wanted it to look like a printed halftone: a grid of dots, bigger where the picture is dark and smaller where it's light. And I wanted it to be alive, so the dots swell and get pushed away when you move the cursor over them. It turned out to be about 150 lines of React and plain Canvas 2D, with no dependencies. Here's…

The author wanted their portfolio's photo to resemble a halftone print, featuring a grid of dots that vary in size based on lightness and darkness. They achieved this using just 150 lines of React and the Canvas 2D API without any dependencies. The process is broken down into four steps.

First, the image is transformed into a grid of samples, essentially creating a low-resolution version of the picture made of dots. This is done by drawing the image onto a small offscreen canvas and reading the pixels back using getImageData. The browser handles the downscaling by averaging the source pixels for each sample, which provides the color and darkness needed for each dot.

Next, a dot is drawn for each sample. The radius of each dot is determined by the sample's darkness, with darker samples resulting in larger dots. A tone curve is applied to the darkness value to prevent midtones from appearing too light. Additionally, an elliptical vignette is used to give the portrait a soft edge instead of a hard rectangle.

To add a sense of life to the portrait, a small sine wave is introduced, causing each dot to ripple slightly based on its position. This ripple effect is relatively slow, making the portrait appear to breathe.

Finally, the portrait reacts to the cursor. The cursor's position is smoothed out and targeted, causing the dots to grow or shrink as the cursor moves around them. This creates an interactive experience where the dots appear to swell and recede as the cursor moves over them.

Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at dev.to →

More in Tech

Pushing Beats Polling Explained: Live Poll Trust Above a Handful of Viewers

Short answer: pushing beats polling above a handful of viewers because one state change should not trigger repeated reads for every screen, but treat delivery as an optimization, not as authorization.

  • Pushing poll results, not polling, reduces unnecessary load and scaling issues with more viewers
  • Trust must be established independently of transport layer for untrusted clients
  • Small, immutable poll state snapshots enable reconnects with correct, up-to-date view

Why we stopped retrying on timeout and built reconciliation instead

Early in StareBrain’s action dispatch layer, we had a simple rule: if an action times out, retry it. It felt safe. It felt standard. It was wrong. The problem isn’t the retry.

  • StareBrain's previous rule was to retry actions on timeout, which proved incorrect.
  • New state model tracks Delivery and Acceptance states independently to reconcile ambiguous actions.

How to preview a coding benchmark run before spending on model calls

Use the --dry-run option to inspect a benchmark plan before launching model calls. In Weave Router's public weave-bench harness, the option resolves the pinned task manifest and prints the Harbor…

  • Use --dry-run option to preview benchmark plan without network impact.
  • --smoke selects smaller task set but may initiate jobs and incur costs.
  • Verify task selection, pinned versions, and comparison arms before removing --dry-run flag.

My users table reads one pagination contract: paginate(15), withQueryString, and a React pager that trusts meta

The first admin panel I built fetched all users, dumped them into state, and sliced pages client-side. It worked until a client hit 2,000 users and the list page took eleven seconds to load.

  • Implemented server-side pagination with Laravel's paginate(15) for 2,000+ users
  • React pager relied on backend meta data, fetching users based on page and meta
  • Consistent pagination contract extended to all admin panels in Laravel + React SaaS Starter Kit

More from Saturday 17 October →