Pixelate

Chunks the node into rectangular blocks, like After Effects' Mosaic effect.

The block values are a block count (how many blocks span the node), not a pixel size. A count equal to the node's pixel dimension on that axis is pristine (one block per pixel); lower counts give larger, coarser blocks. For a 1920×1080 image, 1920 × 1080 is untouched and 40 × 24 is heavily pixelated.

Pixelate effect demo

Usage

import { Effects } from '@motion-script/core';

// Uniform block count on both axes
<Rect fill={{ type: 'image', src: './photo.jpg', fit: 'fill' }} effects={Effects.pixelate(120)} />

// Per-axis block counts + sharp colours
<Rect effects={Effects.pixelate({ blocks: { x: 200, y: 180 }, sharpColors: true })} />

// Uniform count via an options object
<Rect effects={Effects.pixelate({ blocks: 80, sharpColors: false })} />

// Raw effect object
<Rect effects={[{ type: 'pixelate', blocks: { x: 200, y: 180 }, sharpColors: true }]} />

Effects.pixelate(options) takes a bare number (the same block count on both axes) or an options object. Per-axis counts go in blocks as { x, y } — one field for one quantity, so there is never a pair to keep in sync.

Props

The builder takes a single options object — these are its fields, and also the fields of the effect object it produces.

PropTypeDefaultDescription
type'pixelate'Effect identifier
blocksnumber | { x: number; y: number }Block count across the node. A single number applies to both axes; { x, y } sets them independently (AE "Horizontal/Vertical Blocks")
sharpColorsbooleantrueSolid blocks (true) vs. smoothly blended (false); mirrors AE's "Sharp Colors"
mode'foreground' | 'backdrop''foreground''backdrop' pixelates the content beneath the node, clipped to its silhouette, leaving the node's own content untouched

Animating

Start with a low block count (coarse) and animate up to the node's resolution to reveal the image:

import { createScene, Rect, Effects, tween, lerpNumber, easeInOut } from '@motion-script/core';

export default createScene(function* (stage) {
  const img = new Rect({
    width: 600,
    height: 400,
    fill: { type: 'image', src: './photo.jpg', fit: 'fill' },
  });
  img.set({ effects: Effects.pixelate(40) });
  stage.add(img);

  yield* tween(1.5, (t) => {
    img.set({ effects: Effects.pixelate(lerpNumber(40, 600, easeInOut(t))) });
  });
});

Stacking with other effects

<Rect effects={Effects.pixelate(120).grayscale(0.5)} />