# Interactive Halftone Image

> An image rendered live as a halftone dot grid the pointer drags through: dots swell, smear along the stroke and split into misregistered ink at speed, then settle back elastically.

Canonical: https://gsapvault.com/effects/halftone-image
Live demo: https://gsapvault.com/demos/halftone-image/index.html

| Property | Value |
|----------|-------|
| Type | effect |
| Tier | paid |
| Price | £5 |
| Difficulty | advanced |
| Plugins | Core GSAP only |
| Techniques | canvas, halftone, pointer-effects, velocity-reactive, micro-interaction, load-sequence |
| Uses Lenis | No |

## Overview

A photograph rebuilt live as a halftone dot grid on a single canvas, running on GSAP's core ticker with zero plugins. Every dot is sized from the image's sampled luminance, so any same-origin photo drops straight in with no preprocessing.

The pointer drags an ink wake through the print: dots swell with pointer speed, elongate and smear along the stroke, and above a velocity threshold split into misregistered cyan and orange ink layers, like a print pulled mid-pass. Lift off and the whole wake settles back with an elastic wave.

## Features

- Live luminance sampling: the image is drawn to an offscreen canvas at grid resolution and read once, so any same-origin photo becomes a halftone with no preprocessing
- Velocity-reactive wake with three layered responses to one input: dot swell, directional smear, and misregistered ink splitting, all scaled by pointer speed
- Elastic settle driven by per-dot springs in typed arrays, so thousands of dots relax with natural overshoot and no per-dot tweens
- One-off print pass on load: a sweep resolves the image from scattered noise into the finished halftone in about a second
- Autonomous idle sweep keeps the print alive after a few seconds without input; any real pointer or touch input takes over instantly
- Touch-first pointer events, so a finger drag drives exactly the same wake as a mouse
- Batched rendering: the entire grid draws in at most three canvas fills per frame, with the resolution capped at 2x DPR
- Configured entirely through data attributes: cell size, ink colour, paper colour and wake strength

## Use Cases

- Portfolio and agency hero portraits with a centrepiece visitors touch rather than scroll past
- Music, zine and editorial landing pages with a genuine print-shop texture
- Speaker, artist and founder profile pages where one photograph carries the whole design
- About and team pages with portraits that answer the visitor's pointer
- Campaign microsites built around a single striking image

## Vibe-Code Ready Setup

This effect includes `START-HERE-AI.md`, a product-specific copy-paste setup prompt for Cursor, Claude Code, ChatGPT, GitHub Copilot, Windsurf, and other coding assistants. It tells the assistant to inspect the existing stack, integrate the supplied files, preserve the design, scope selectors, retain accessibility and responsive behaviour, add framework-appropriate GSAP cleanup, and report what it tested.

[How AI-assisted setup works](https://gsapvault.com/vibe-coding)

## How It Works

The source image is drawn to an offscreen canvas at one pixel per grid cell and sampled once with getImageData; each cell's luminance sets its resting dot radius, so bright areas print as big paper dots on the dark ground. A single gsap.ticker callback runs everything: pointer velocity is stamped into typed-array fields for swell, smear and ink split, per-dot springs relax those fields back toward rest with a slight elastic overshoot, and the grid is redrawn as batched Path2D fills, ink layers under paper. The load-in print pass and the idle sweep are ordinary GSAP tweens driving the same wake function as the real pointer, so every input shares one code path.

## Integration Preview

How this effect integrates into a page. The full documentation (examples, events, programmatic API, customization guide) ships with the download.

### Quick Start

**1. Add to your HTML `<head>`:**

```html
<link rel="stylesheet" href="path/to/style.css">
```

**2. Add before the closing `</body>` tag:**

```html
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
<script src="path/to/script.js"></script>
```

No GSAP plugins are needed.

**3. Add the markup to your `<body>`:**

```html
<figure class="ht-stage" data-halftone tabindex="0" role="img"
        aria-label="Halftone print of a portrait that reacts to the pointer">
  <img src="path/to/your-photo.webp" alt="Describe the photograph">
</figure>
```

That is the whole contract: a container carrying `data-halftone` with one `<img>` inside it. The script builds the `<canvas>` itself, waits for the image to decode, samples it, and takes over.

### Options

Set on the `[data-halftone]` container.

| Attribute | Values | Default | Description |
|-----------|--------|---------|-------------|
| `data-halftone-cell` | Number (px), 8 to 20 is sensible | `12` | Grid cell size. Smaller cells mean a finer print and more dots to draw; below 8px profile before shipping |
| `data-halftone-ink` | Any CSS colour | `#22d3ee` | Leading ink of the misregistration split, revealed on a fast whip |
| `data-halftone-paper` | Any CSS colour | `#f2efe8` | The dot colour, the "paper" the image is printed with |
| `data-halftone-strength` | Number, `0.4` to `2` is sensible | `1` | Wake multiplier. Below 1 the print barely stirs; above 1 gentle passes already smear and tear |

### Accessibility

- **Reduced motion**: under `prefers-reduced-motion: reduce` the script renders the fully resolved halftone once as a still image. No print pass, no idle sweep, no wake, and never a blank stage.
- **No JavaScript**: the real `<img>` is visible by default; the script hides it only after it has taken over. If GSAP or the image fails to load, the photograph returns.
- **Keyboard**: with `tabindex="0"` the stage is focusable. Focusing it (via keyboard) runs one sweep pass across the print, and Enter or Space replays it.
- **Focus visible**: the stage shows an accent outline under `:focus-visible`.
- **Labels**: `role="img"` with a descriptive `aria-label` on the container, plus a real `alt` on the image, keeps the composition meaningful to screen readers.

### Dependencies

**Required:**
- GSAP 3.12+ (core only, no plugins)

**Optional:**
- None

## What You Get

- `index.html`: working demo page
- `assets/script.js`: commented, readable source
- `assets/style.css`: effect styles
- `README.md`: full documentation with examples and framework integration notes
- `START-HERE-AI.md`: product-specific copy-paste prompt for AI-assisted setup
- `LICENSE.txt`: standard license terms
- Lifetime updates: re-download anytime from your library

## Get the Code

This is a premium effect. The standard license costs £5 one-time and covers unlimited personal and commercial projects with no attribution required. The only restrictions: no redistribution of the code itself and no competing effect libraries.

- [Buy Interactive Halftone Image](https://gsapvault.com/effects/halftone-image)
- [Effects & Templates Vault (£39 one-time, best value): every current and future effect and template](https://gsapvault.com/effects)

## Judge the Code Quality First

These related effects are free with complete source published, written to the same production standard (cleanup functions, reduced-motion support, framework-agnostic):

- [Hover Underline](https://gsapvault.com/effects/hover-underline.md): Three material link underlines (an exit-through line, marker sweep, and hand-drawn wave) with coordinated type and active-index responses.
- [Image Clip Reveal](https://gsapvault.com/effects/image-clip-reveal.md): A cinematic image reveal where a directional polygon aperture opens as the photograph settles from a restrained Ken Burns scale and its editorial caption lands.

---

From [GSAP Vault](https://gsapvault.com): production-ready GSAP animation effects. Full catalog for agents: https://gsapvault.com/llms-full.txt
