Image Blur Reveal Effect with JavaScript & CSS3

Image Blur Reveal Effect with JavaScript & CSS3
Image Blur Reveal Effect with JavaScript & CSS3
This is a vanilla JavaScript code snippet that creates an interactive image reveal effect triggered by cursor movement.

Users can reveal portions of your blurred image by moving their mouse and expanding the reveal circle through click interactions.

Features:

  • CSS-Based Blur: Uses native CSS filter property for blur effect.
  • Smooth Animations: Uses requestAnimationFrame API for smooth radius transitions at 60fps.
  • Interactive Radius Control: Click to expand reveal circle from 100px to 200px with eased animation.
  • Precise Cursor Tracking: Real-time mousemove event handling for accurate clip-path positioning.
  • Automatic Reset: Reveals collapse to zero when cursor leaves the image container.

See It In Action:

How To Use It:

1. Create a container and place two identical images inside. One will serve as the blurred background, and the other as the clear foreground.

<div class="image-container">
  <img id="blurred" src="1.jpg" alt="" />
  <img id="clear" src="1.jpg" alt="" />
</div>

2. Position both images absolutely within the container and apply the blur filter and initial clip-path.

.image-container {
  position: relative;
}

.image-container img {
  position: absolute;
  top: 0;
  left: 0;
  max-width: 100%;
}

#clear {
  clip-path: circle(0px at 0 0);
}

#blurred {
  filter: blur(15px);
}

3. Initialize the reveal effect with cursor tracking and click-to-expand functionality.

// Select elements
const clearImg = document.getElementById('clear');
const container = document.querySelector('.image-container');

// Configuration variables
let radius = 100; // Default reveal radius in pixels
let bigRadius = 200; // Expanded radius on click
let currentRadius = radius; // Current animation state
let targetRadius = radius; // Animation target value
let animating = false; // Animation lock flag

// Store cursor position
let mouseX = 0, mouseY = 0;

// Track cursor movement and update clip-path position
container.addEventListener('mousemove', (e) => {
  const rect = container.getBoundingClientRect();
  mouseX = e.clientX - rect.left; // Calculate x relative to container
  mouseY = e.clientY - rect.top; // Calculate y relative to container

  // Only update immediately if not currently animating
  if (!animating) {
    clearImg.style.clipPath = `circle(${currentRadius}px at ${mouseX}px ${mouseY}px)`;
  }
});

// Reset reveal when cursor leaves container
container.addEventListener('mouseleave', () => {
  clearImg.style.clipPath = 'circle(0px at 0 0)';
  animating = false;
});

// Expand reveal circle on mouse press
container.addEventListener('mousedown', (e) => {
  targetRadius = bigRadius;
  if (!animating) {
    animating = true;
    animateCircle(); // Start animation loop
  }
});

// Shrink reveal circle on mouse release
container.addEventListener('mouseup', () => {
  targetRadius = radius;
  if (!animating) {
    animating = true;
    animateCircle(); // Start animation loop
  }
});

// Smooth animation function using easing
function animateCircle() {
  if (!animating) return;

  // Ease towards target radius (20% per frame)
  currentRadius += (targetRadius - currentRadius) * 0.2;
  clearImg.style.clipPath = `circle(${currentRadius}px at ${mouseX}px ${mouseY}px)`;

  // Continue animation until close enough to target
  if (Math.abs(currentRadius - targetRadius) > 0.5) {
    requestAnimationFrame(animateCircle);
  } else {
    currentRadius = targetRadius; // Snap to exact value
    clearImg.style.clipPath = `circle(${currentRadius}px at ${mouseX}px ${mouseY}px)`;
    animating = false; // Release animation lock
  }
}

FAQs:

Q: Does this work on mobile devices or tablets?
A: No, the current implementation only supports mouse events. To add touch support, you would need to include touchmove, touchstart, and touchend event listeners that extract touch coordinates from event.touches[0].clientX and event.touches[0].clientY properties. The core clip-path logic remains the same once you have the coordinate values.

Q: Can I change the reveal shape from circle to something else?
A: Yes, CSS clip-path supports multiple shapes including ellipse, polygon, and path. Replace the circle() function in the clip-path property with your desired shape. For example, ellipse(100px 50px at ${mouseX}px ${mouseY}px) creates an oval reveal.

Q: How do I prevent the animation from lagging on large images?
A: The blur filter can be GPU-intensive on high-resolution images. Consider using lower-resolution images or reducing the blur radius from 15px to 8-10px. You can also add will-change: clip-path, filter to the CSS for both images to hint browser optimization, though use this sparingly as it increases memory usage.

Q: Can I use different images for the blurred and clear versions?
A: Absolutely. The src attributes can point to completely different images. This opens creative possibilities like revealing alternate color grades, before/after edits, or even entirely different compositions. Just ensure both images have identical dimensions to avoid visual glitches.

Q: Why does the reveal disappear when I move the cursor quickly?
A: The mouseleave event fires when the cursor exits the container bounds. If your cursor moves too fast, the browser may register it as leaving and re-entering the element. You can add a small delay using setTimeout before resetting the clip-path, or increase the container’s padding to create a larger interaction area that reduces accidental exits.

The post Image Blur Reveal Effect with JavaScript & CSS3 appeared first on CSS Script.


Discover more from RSS Feeds Cloud

Subscribe to get the latest posts sent to your email.

Discover more from RSS Feeds Cloud

Subscribe now to keep reading and get access to the full archive.

Continue reading