CURSOR EFFECTS

Image Reveal Cursor

An interactive cursor effect that reveals a different project image on hover and follows the mouse inside the preview area.

Creative Website
UI Dashboard
Portfolio Design
HTML
<div class="image-reveal-area">

  <div
    class="reveal-preview"
    data-reveal-preview
  >
    <img
      src=""
      alt=""
      class="reveal-preview-image"
      data-reveal-image
    >
  </div>

  <div class="reveal-projects">

    <div
      class="reveal-project"
      data-reveal-image-src="https://getcoderipple.com/wp-content/uploads/2026/09/Modern-Web.png"
    >
      Creative Website
    </div>

    <div
      class="reveal-project"
      data-reveal-image-src="https://getcoderipple.com/wp-content/uploads/2026/09/Analytics.png"
    >
      UI Dashboard
    </div>

    <div
      class="reveal-project"
      data-reveal-image-src="https://getcoderipple.com/wp-content/uploads/2026/09/Portfolio.png"
    >
      Portfolio Design
    </div>

  </div>

</div>
CSS
.image-reveal-area{
  position:relative;
  width:100%;
  min-height:240px;

  display:flex;
  align-items:center;
  justify-content:center;

  overflow:hidden;
}

.reveal-projects{
  position:relative;
  z-index:1;

  width:100%;
  max-width:520px;
}

.reveal-project{
  padding:18px 4px;

  border-bottom:1px solid #263750;

  color:#ffffff;

  font-size:20px;
  font-weight:700;

  cursor:none;

  transition:
    color .2s ease,
    padding-left .2s ease;
}

.reveal-project:first-child{
  border-top:1px solid #263750;
}

.reveal-project:hover{
  color:#22d3ee;
  padding-left:10px;
}

.reveal-preview{
  position:absolute;
  top:0;
  left:0;
  z-index:9999;

  width:190px;
  height:125px;

  overflow:hidden;

  border:1px solid rgba(255,255,255,.18);
  border-radius:14px;

  opacity:0;

  pointer-events:none;

  transform:
    translate(-50%, -50%)
    scale(.85)
    rotate(-3deg);

  box-shadow:
    0 18px 45px rgba(0,0,0,.48),
    0 0 25px rgba(34,211,238,.15);

  transition:
    opacity .18s ease,
    transform .22s ease;
}

.reveal-preview.active{
  opacity:1;

  transform:
    translate(-50%, -50%)
    scale(1)
    rotate(0deg);
}

.reveal-preview-image{
  width:100%;
  height:100%;

  display:block;

  object-fit:cover;

  border-radius:13px;
}
JavaScript
const area =
  document.querySelector('.image-reveal-area');

if (area) {

  const preview =
    area.querySelector('[data-reveal-preview]');

  const image =
    area.querySelector('[data-reveal-image]');


  area.addEventListener(
    'mousemove',
    function(event) {

      if (!preview) {
        return;
      }

      const rect =
        area.getBoundingClientRect();

      preview.style.left =
        event.clientX -
        rect.left +
        'px';

      preview.style.top =
        event.clientY -
        rect.top +
        'px';
    }
  );


  area.addEventListener(
    'mouseover',
    function(event) {

      const item =
        event.target.closest(
          '[data-reveal-image-src]'
        );

      if (!item) {
        return;
      }

      if (!preview) {
        return;
      }

      if (!image) {
        return;
      }

      image.src =
        item.getAttribute(
          'data-reveal-image-src'
        );

      image.alt =
        item.textContent.trim();

      preview.classList.add(
        'active'
      );
    }
  );


  area.addEventListener(
    'mouseout',
    function(event) {

      const item =
        event.target.closest(
          '[data-reveal-image-src]'
        );

      if (!item) {
        return;
      }

      if (!preview) {
        return;
      }

      preview.classList.remove(
        'active'
      );
    }
  );

}

How This Component Works

This effect shows a floating image preview that follows the mouse and updates its content depending on which list item the cursor is hovering over — a technique commonly seen on agency and portfolio websites when browsing a list of projects. The HTML structure has two main parts: a hidden preview box (reveal-preview) containing an empty img tag, and a list of project items (reveal-project), each carrying its own image URL stored in a data-reveal-image-src attribute.

The JavaScript handles three separate behaviors. First, a mousemove listener continuously updates the preview box’s position so it follows the cursor anywhere inside the container. Second, a mouseover listener checks whether the cursor has entered a project item — if it has, the script reads that item’s data attribute (data-reveal-image-src) and injects it directly into the preview image’s src attribute, while also setting the image’s alt text from the item’s own text content for accessibility. At the same time, it adds an active class to reveal the preview box. Third, a mouseout listener removes that active class once the cursor leaves the item, hiding the preview again.

The visual polish comes from CSS. The preview box starts scaled down, slightly rotated, and fully transparent — then transitions to full size, zero rotation, and full opacity when the active class is applied, giving the image a subtle “pop into place” feel rather than an abrupt appearance. A soft box-shadow with a cyan-tinted glow adds depth, making the floating preview feel like it’s hovering above the page.

Customizing This Image Reveal Cursor Effect

Several parts of this effect can be adjusted without changing the JavaScript logic:

  • Change the preview image size — update the width and height values in .reveal-preview (currently 190px by 125px) to make the floating preview larger or smaller.
  • Adjust the entrance animation — modify the scale() and rotate() values in .reveal-preview to change how dramatic the “pop-in” effect feels.
  • Update the project list styling — text size, spacing, and hover color are controlled in .reveal-project, independent of the image preview logic.
  • Add or remove projects — this image reveal cursor setup lets each project item carry its own image URL through the data-reveal-image-src attribute, so you can add as many list items as needed without touching the JavaScript at all.

Where to Use This Image Reveal Cursor Effect

This effect is purpose-built for showcasing a list of linked visual content, making it ideal for:

  • Portfolio and agency websites, where a list of project names reveals a preview thumbnail on hover, exactly as shown in the demo.
  • Blog or article index pages, where hovering over a post title shows a relevant featured image.
  • Case study or client work pages, letting visitors preview a project visually before clicking through to read more.

This effect depends on a list-based layout to work well — it’s not suited for single-image galleries or grid-based layouts, since it’s built specifically around text items triggering image previews.

If you’re looking for a simpler hover effect without image previews, take a look at our Cursor Ring Hover Effect component for a more minimal interactive touch.

Frequently Asked Questions

Can I use real project links instead of plain text items?
Yes. Since the data-reveal-image-src attribute can be added to any element, you can wrap each project name in an <a> tag and the hover-reveal behavior will continue to work exactly the same way, letting users click through after previewing the image.

Why doesn’t the image preview show up on mobile devices?
Since mobile devices rely on touch rather than a hovering mouse cursor, there’s no mousemove or mouseover event to trigger the preview. The component’s mobile styles intentionally hide the preview box entirely, since a fixed image reveal doesn’t translate well to touch interaction.

Does each project need a unique image, or can images repeat?
Each project can technically use any image URL, including a repeated one, since the script simply reads whatever value is stored in data-reveal-image-src for that specific item. There’s no requirement for the images to be unique, though using distinct images obviously makes the preview more useful for visitors.

Scroll to Top