---
url: /examples/basics/play-pause.md
description: Start and stop rendering with a button to control an animation loop.
---

::: example-editor

```ts
import { glCanvas } from "@radiancejs/gl";
import fragment from "./metaballs.frag?raw";
import "./styles.css";

const { play, pause, onAfterRender } = glCanvas({
  canvas: "#glCanvas",
  fragment,
  uniforms: {
    uTime: ({ time }) => time / 1000,
  },
  immediate: false, // prevent the loop from starting immediately
});

const playPauseButton = document.querySelector<HTMLButtonElement>("#playPause")!;
let isPlaying = false;

playPauseButton.addEventListener("click", () => {
  isPlaying = !isPlaying;
  playPauseButton.classList.toggle("playing", isPlaying);
  playPauseButton.setAttribute("aria-label", isPlaying ? "Pause" : "Play");
  if (isPlaying) {
    play();
  } else {
    pause();
  }
});

const renderCount = document.querySelector("#renderCount")!;
onAfterRender(() => {
  renderCount.firstChild!.nodeValue = `${Number(renderCount.textContent) + 1}`;
});

```

```frag
varying vec2 uv;
uniform float uTime;

// polynomial smooth min (https://iquilezles.org/articles/smin/)
float smin(float a, float b, float k) {
  float h = clamp(.5 + .5 * (b - a) / k, 0., 1.);
  return mix(b, a, h) - k * h * (1. - h);
}

void main() {
  vec2 p = (uv - .5) * 2.;
  float t = uTime;

  // three orbiting blobs
  vec2 c1 = vec2(cos(t * .8) * .5, sin(t * 1.1) * .4);
  vec2 c2 = vec2(cos(t * .6 + 2.1) * .55, sin(t * .9 + 1.3) * .45);
  vec2 c3 = vec2(sin(t * .5 + 4.2) * .45, cos(t + 3.1) * .35);

  float d = smin(length(p - c1) - .26, length(p - c2) - .2, .35);
  d = smin(d, length(p - c3) - .23, .35);

  float body = 1. - smoothstep(-.005, .005, d);
  float depth = clamp(-d * 2.5, 0., 1.); // deeper inside the field
  float rim = smoothstep(.06, -.02, abs(d)); // bright edge
  float halo = exp(-5. * max(d, 0.)); // outer glow

  vec3 color = mix(vec3(.05, .03, .12), vec3(.13, .05, .22), uv.y);
  color += vec3(.9, .3, .5) * halo * .45;
  color = mix(color, mix(vec3(.98, .5, .2), vec3(.8, .1, .6), depth), body);
  color += vec3(1., .8, .7) * rim * .6;

  gl_FragColor = vec4(color, 1.);
}

```

```css
html {
  color-scheme: light dark;
}

body {
  margin: 0;
  height: 100svh;
  display: grid;
  place-items: center;
}

canvas {
  width: min(90svmin, 900px);
  aspect-ratio: 1;
  display: block;
  border-radius: 8px;
  border: 1px solid rgb(128 128 128 / 0.4);
}

```

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>RadianceJS Example</title>
  </head>
  <body>
    <style>
      #renders {
        position: absolute;
        left: 1em;
        bottom: 1em;
        font-family: sans-serif;
        font-size: 1.5rem;
      }

      .canvas-container {
        position: relative;
        width: min(90svmin, 900px);
        aspect-ratio: 1;
      }

      .canvas-container canvas {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
      }

      #playPause {
        position: absolute;
        right: 0.5em;
        bottom: 0.5em;
        display: grid;
        place-items: center;
        background: rgb(128 128 128 / 0.1);
        width: 2.4em;
        height: 2.4em;
        font-size: 1.5rem;
        border-radius: 8px;
        border: 1px solid rgb(128 128 128 / 0.4);
        cursor: pointer;

        &:hover {
          background: rgb(128 128 128 / 0.2);
        }

        &:active {
          background: rgb(128 128 128 / 0.1);
        }
      }

      #playPause svg {
        width: 1.5em;
        height: 1.5em;
        fill: currentColor;
      }

      #playPause .icon-pause {
        display: none;
      }

      #playPause.playing .icon-play {
        display: none;
      }

      #playPause.playing .icon-pause {
        display: block;
      }
    </style>
    <div class="canvas-container">
      <canvas id="glCanvas"></canvas>
      <button id="playPause" type="button" aria-label="Play">
        <svg class="icon-play" viewBox="0 0 24 24" aria-hidden="true">
          <path d="M8 5v14l11-7z" />
        </svg>
        <svg class="icon-pause" viewBox="0 0 24 24" aria-hidden="true">
          <path d="M6 5h4v14H6zm8 0h4v14h-4z" />
        </svg>
      </button>
    </div>
    <div id="renders">Renders: <strong id="renderCount">0</strong></div>
    <script src="/index.ts"></script>
  </body>
</html>

```

:::
