webdevpuneet.com

Pixel Resolve Text — Canvas Text That Sharpens From Blocks

Pixel Resolve Text · Text Animation · Plain HTML, CSS & JS · Live preview

Copy & paste

Source Code

<main class="stage">
  <h1 class="sr">Crisp at last</h1>
  <canvas id="cv" role="img" aria-label="Crisp at last"></canvas>
  <div class="row">
    <button type="button" id="resolve" class="primary">Resolve</button>
    <button type="button" id="pixelate" class="ghost">Pixelate</button>
    <label class="pace">Steps
      <select id="steps" aria-label="Number of resolution steps">
        <option value="6">6 (jumpy)</option>
        <option value="9" selected>9</option>
        <option value="14">14 (smooth)</option>
      </select>
    </label>
  </div>
</main>

Extend with AI

Take This Snippet Further With AI

Ask an AI coding assistant to explain why drawing a canvas into a smaller canvas and back with imageSmoothingEnabled set to false produces real pixel blocks, and why the block sizes are generated with a geometric progression rather than evenly spaced. A good follow-up is how to wait for a web font before drawing.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a pixel-resolve text effect on an HTML canvas in plain JavaScript, with no libraries.

Requirements:
- A canvas sized from CSS dimensions multiplied by devicePixelRatio (capped at 2). Draw the headline once onto an offscreen source canvas using a heavy font and a horizontal gradient fill.
- A function showAtBlock(b) that clears the main canvas; for b of 1 or less draws the source directly; otherwise draws the source into a tiny canvas of width/b by height/b, then draws that tiny canvas stretched to full size with imageSmoothingEnabled set to false so each pixel becomes a hard block.
- Generate the list of block sizes geometrically from about 64 down to exactly 1, with a configurable step count. A timer steps through the list every ~150ms, and the list can be reversed so the same function pixelates text instead of resolving it.
- Buttons for Resolve and Pixelate and a select for 6, 9 or 14 steps; starting a new run cancels the previous timer.
- Include a visually hidden h1 with the same text and an aria-label on the canvas. Under prefers-reduced-motion draw the sharp text immediately.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

What's included

Features

Real pixelation
The text is downscaled and stretched with smoothing off, so every frame has hard-edged blocks instead of a blur.
Geometric steps
Block sizes shrink by a constant factor, so the sharpening looks even from first frame to last.
Both directions
One function resolves or pixelates (it reverses the same list), so the effect can be an exit as well as an entrance.
Retina-sharp finish
The canvas uses the device pixel ratio so the last frame is crisp on high-density screens.
Adjustable steps
A select changes between 6, 9 and 14 steps for choppy or smooth results.
Readable by everything else
A hidden <h1> and an aria-label carry the text for search engines and screen readers.

About this UI Snippet

Pixel Resolve Text — Canvas Downscale and Nearest-Neighbour Upscale in Steps

Screenshot of the Pixel Resolve Text snippet rendered live

Think of a low-resolution image loading, or a retro game mock-up resolving into sharp art: the picture starts as a few huge squares and gets finer until the detail snaps in. This snippet does that to a headline using the canvas. It isn't blur and it isn't a filter, but a real change of resolution, so the intermediate frames look like actual pixel art.

How to fake a low resolution

The sharp text is drawn once onto an offscreen canvas, filled with a green-to-cyan gradient. To show it "at block size b", the code draws that canvas into a much smaller one (width ÷ b, height ÷ b), which throws detail away, then draws the small canvas back to full size with imageSmoothingEnabled = false. With smoothing off, the browser uses nearest-neighbour scaling, so each source pixel becomes a hard-edged b×b square.

Steps that feel even

Block sizes aren't linear. Going from 64 to 1 in equal steps would spend most frames on blocks too small to notice a change. Instead each step multiplies by the same factor (Math.pow), so the text sharpens at a steady perceived rate; the last step is forced to exactly 1, which draws the original crisp image. A step timer of 150ms and a select for 6, 9 or 14 steps lets you trade snappy for smooth.

Practical details

The canvas is sized by device pixel ratio (capped at 2) so the final frame is truly sharp on retina screens. Because canvas text can't be read by search engines or screen readers, a visually hidden <h1> holds the same text and the canvas has an aria-label. Reduced-motion visitors get the sharp text immediately.

Step by step

How to Use

  1. 1
    Paste the three blocksA dark panel appears with a green-cyan headline that starts as big blocks and sharpens in nine steps. Resolve and Pixelate buttons replay it in each direction.
  2. 2
    Change the textEdit TEXT in the JS, and update the hidden <h1> and the canvas aria-label so they match. The font starts at 118px and shrinks automatically so any text fits the 760px width; change 118 to set the largest size.
  3. 3
    Change the coloursEdit the two addColorStop values for another gradient, or set a flat fillStyle.
  4. 4
    Set the speedThe 150 in setTimeout is milliseconds per step; the select changes how many steps there are. Fewer steps with a longer delay looks more like a retro game; many fast steps looks like an image loading.
  5. 5
    Use it as a loaderCall play(false) when your content is ready, or call it on scroll into view for a one-time reveal.

Real-world uses

Common Use Cases

Retro and game-style landing pages
Title screens and "insert coin" heroes where pixel art is on-theme.
Image and video loading states
Resolve a headline or logo as a progressive reveal while the page's real assets arrive.
Privacy and redaction demos
Show how pixelation hides a name or number, then reverse it for contrast.
Tech and glitch-adjacent branding
Cybersecurity, AI and dev-tool brands can use a resolving wordmark as an intro.
Transitions between hero messages
Pixelate one phrase out, swap the text, and resolve the next phrase in.

Got questions?

Frequently Asked Questions

It's pixels on a canvas. That is why the snippet includes a visually hidden heading with the same words, which keeps the page accessible and indexable.

CSS can't pixelate live text at changing block sizes. image-rendering: pixelated only affects images, so a canvas that really resamples the picture is the simplest approach.

Yes, but the font must be loaded before drawing. Wait for document.fonts.ready (or document.fonts.load()) and then call drawSource(), or the canvas will use the fallback font.

Replace the text drawing in drawSource() with sctx.drawImage(img, ...). The downscale-then-stretch step works the same way for any picture.