# Image reveal

> Reveal an image on scroll with a blur, scale or fade effect, or a clip-path wipe or circle. Try it live, then copy the code for React, Vue, Astro or JavaScript.

A large image comes into view. The example uses a duration of 1000 ms, because a large element needs more time than a small one to look smooth.

* React

  ```jsx
  import { Reveal } from "@awesome-reveal/react";
  import { blur } from "@awesome-reveal/react/keyframes";

  export function Photo({ src, alt, width, height, caption }) {
    return (
      <Reveal as="figure" className="photo" keyframes={blur()} duration={1000}>
        <img src={src} alt={alt} width={width} height={height} loading="lazy" />
        <figcaption>{caption}</figcaption>
      </Reveal>
    );
  }
  ```

* Vue

  ```vue
  <script setup>
  import { Reveal } from "@awesome-reveal/vue";
  import { blur } from "@awesome-reveal/vue/keyframes";

  defineProps(["src", "alt", "width", "height", "caption"]);
  </script>

  <template>
    <Reveal as="figure" class="photo" :keyframes="blur()" :duration="1000">
      <img
        :src="src"
        :alt="alt"
        :width="width"
        :height="height"
        loading="lazy"
      />
      <figcaption>{{ caption }}</figcaption>
    </Reveal>
  </template>
  ```

* Astro

  ```astro
  ---
  import { Reveal } from "@awesome-reveal/astro";
  import { blur } from "@awesome-reveal/astro/keyframes";

  const { src, alt, width, height, caption } = Astro.props;
  ---

  <Reveal as="figure" class="photo" keyframes={blur()} duration={1000}>
    <img src={src} alt={alt} width={width} height={height} loading="lazy" />
    <figcaption>{caption}</figcaption>
  </Reveal>
  ```

* JavaScript

  ```html
  <figure class="photo">
    <img
      src="sunrise.jpg"
      alt="The sun rises behind green hills"
      width="1600"
      height="900"
      loading="lazy"
    />
    <figcaption>Sunrise over the hills</figcaption>
  </figure>
  ```

  ```js
  import { reveal } from "@awesome-reveal/core";
  import { blur } from "@awesome-reveal/core/keyframes";

  reveal(document.querySelector(".photo"), {
    keyframes: blur(),
    duration: 1000,
  });
  ```

## Wipe and circle

`wipe` and `circle` are custom keyframes: arrays that animate `clip-path`. The code puts each array in a constant next to the imports, so the markup stays short.

End the keyframes at a shape that shows the whole image, such as `inset(0)`. Do not end them at `{}`. `clip-path` interpolates only between basic shapes, and its resting value `none` is not a basic shape. With `{}`, the image appears at once halfway through the animation.

`blur`, `wipe` and `circle` repaint the image on each frame in some engines. On a large image, test them on a slow device. If the animation stutters, use `scale` or `fade`.

## Next steps

[Custom keyframes](/concepts/keyframes/#custom-keyframes): Keyframes arrays and defineKeyframes.

[Options](/concepts/options/): Duration, delay, stagger and the viewport options.

[Accessibility](/concepts/accessibility/): Reduced motion, screen readers and pages without JavaScript.

[Getting started](/getting-started/): Install the package for your framework.
