Masking

마스킹

A mask uses another layer's alpha or brightness to decide where an image remains visible.

Also known as: Layer maskMask

Moves in browsers that support WebGPU

This device could not render the demo — showing a still

React
// Renders only in browsers with WebGPU.
// /samples/… are this site’s sample files — point them at your own image or video.
import { Shader, Circle, ImageTexture } from 'shaders/react'

export default function ShaderEffect() {
  return (
    <Shader style={{ width: '100%', height: 320 }} disableTelemetry>
      <Circle
        id="reveal"
        radius={{
          type: "auto-animate",
          mode: "ping-pong",
          outputMin: 0.25,
          outputMax: 0.6,
          speed: 0.5
        }}
        softness={0.2}
        visible={false} />
      <ImageTexture
        maskSource="reveal"
        objectFit="cover"
        url="/samples/photo.jpg" />
    </Shader>
  )
}
Vue
<!-- Renders only in browsers with WebGPU. -->
<!-- /samples/… are this site’s sample files — point them at your own image or video. -->
<script setup lang="ts">
import { Shader, Circle, ImageTexture } from 'shaders/vue'
</script>

<template>
  <Shader style="width: 100%; height: 320px" :disable-telemetry="true">
    <Circle
      id="reveal"
      :radius="{
        type: 'auto-animate',
        mode: 'ping-pong',
        outputMin: 0.25,
        outputMax: 0.6,
        speed: 0.5
      }"
      :softness="0.2"
      :visible="false"/>
    <ImageTexture
      mask-source="reveal"
      object-fit="cover"
      url="/samples/photo.jpg"/>
  </Shader>
</template>
Svelte
<!-- Renders only in browsers with WebGPU. -->
<!-- /samples/… are this site’s sample files — point them at your own image or video. -->
<script>
  import { Shader, Circle, ImageTexture } from 'shaders/svelte'
</script>

<Shader style="width: 100%; height: 320px" disableTelemetry>
  <Circle
    id="reveal"
    radius={{
      type: "auto-animate",
      mode: "ping-pong",
      outputMin: 0.25,
      outputMax: 0.6,
      speed: 0.5
    }}
    softness={0.2}
    visible={false} />
  <ImageTexture
    maskSource="reveal"
    objectFit="cover"
    url="/samples/photo.jpg" />
</Shader>
Solid
// Renders only in browsers with WebGPU.
// /samples/… are this site’s sample files — point them at your own image or video.
import { Shader, Circle, ImageTexture } from 'shaders/solid'

export default function ShaderEffect() {
  return (
    <Shader style={{ width: '100%', height: '320px' }} disableTelemetry>
      <Circle
        id="reveal"
        radius={{
          type: "auto-animate",
          mode: "ping-pong",
          outputMin: 0.25,
          outputMax: 0.6,
          speed: 0.5
        }}
        softness={0.2}
        visible={false} />
      <ImageTexture
        maskSource="reveal"
        objectFit="cover"
        url="/samples/photo.jpg" />
    </Shader>
  )
}
JavaScript
// Renders only in browsers with WebGPU.
// /samples/… are this site’s sample files — point them at your own image or video.
// expects <canvas id="canvas" style="width:100%;height:320px"></canvas> on the page
import { createShader } from 'shaders/js'

const shader = await createShader(document.getElementById("canvas"), {
  components: [
    {
      type: 'Circle',
      id: 'reveal',
      props: {
        radius: {
          type: 'auto-animate',
          mode: 'ping-pong',
          outputMin: 0.25,
          outputMax: 0.6,
          speed: 0.5
        },
        softness: 0.2,
        visible: false,
      },
    },
    {
      type: 'ImageTexture',
      props: {
        maskSource: 'reveal',
        objectFit: 'cover',
        url: '/samples/photo.jpg',
      },
    }
  ]
}, { disableTelemetry: true })

Props · Circle

Changes apply to the demo above and to the code tabs. Descriptions come from the library registry (MIT).

NameValueDefaultRange / optionsDescription
originOriginSet in codecenter—Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.
colorColor#ffffff—The color of the circle
radiusRadiusAuto-animated in the demo — moving it pins the value10 – 2 (step 0.01)The radius of the circle. A value of one (1) is sets the circle to fit the canvas.
softnessSoftness00 – 1 (step 0.01)Edge softness. Lower values like zero (0) are sharp, higher values like one (1) are softer.
centerCenter Position
x0.5y0.5
{"x":0.5,"y":0.5}x, y: 0 – 1The center point of the circle
strokeThicknessStroke Thickness00 – 0.5 (step 0.01)The thickness of the stroke outline. Zero (0) means no stroke.
strokeColorStroke Color#000000—The color of the stroke outline
strokePositionStroke Positioncenteroutside · center · insidePosition of the stroke relative to the circle edge
colorSpaceColor Blendinglinearlinear · oklch · oklab · hsl · hsv · lchColor space for blending fill and stroke colors in soft edges

Every component also takes blendMode · opacity · visible · maskSource/maskType · boundingBox · id

A mask works like a stencil or a paper cutout: it decides which parts of an image show through. A circular mask can reveal only a circle of a rectangular image without changing the image itself.

Give the mask layer an `id` and hide it with `visible: false`; connect the target layer to that id with `maskSource`. Set `maskType` to `alpha`, `alphaInverted`, `luminance`, or `luminanceInverted` to choose whether transparency or brightness controls the reveal.

A hidden mask can still be referenced, so it does not appear as a separate layer. Decide whether transparency or color brightness should define the cut, and check that the mask id is unique and connected to the intended target.

When to use

Use masking to crop a photo into a circle or star, reveal a gradient through text or a shape, or animate a gradual reveal. For a plain rectangular crop or a uniform fade, use layout cropping or `opacity` instead.

Open as page ↗