Author: | osmosupply |
---|---|
Views Total: | 0 views |
Official Page: | Go to website |
Last Update: | February 28, 2025 |
License: | MIT |
Preview:

Description:
This project presents a dynamic way to transition between images. When you hover over an image, it transforms into another through a pixelated effect.
The transition breaks the image into a grid of small squares that randomly appear and disappear. This creates a digital dissolve effect between two images.
See It In Action:
How to use it:
1. Add the following HTML structure for each image card you want to include. The structure contains:
- A container with data attributes for targeting
- A default image that appears initially
- An active image that appears after the transition
- A grid container that will hold the pixels for the transition effect
<div data-hover="" data-pixelated-image-reveal="" class="pixelated-image-card"> <div class="before__100"></div> <div class="pixelated-image-card__default"> <img src="1.jpg" width="400" alt="" class="pixelated-image-card__img"> </div> <div data-pixelated-image-reveal-active="" class="pixelated-image-card__active"> <img src="2.jpg" width="400" alt="" class="pixelated-image-card__img"> </div> <div data-pixelated-image-reveal-grid="" class="pixelated-image-card__pixels"> <div class="pixelated-image-card__pixel"></div> </div> </div>
2. Add the following CSS snippets to the page. These styles create the container structure and set up the positioning for the transition components.
.pixelated-image-card { background-color: #131313; color: #ff4c24; border-radius: .5em; width: 30vw; max-width: 100%; position: relative; overflow: hidden; } .before__100 { padding-top: 100%; } .pixelated-image-card__default, .pixelated-image-card__img, .pixelated-image-card__active, .pixelated-image-card__pixels{ width: 100%; height: 100%; position: absolute; top: 0; left: 0; } .pixelated-image-card__active { display: none; } .pixelated-image-card__pixel { background-color: currentColor; width: 100%; height: 100%; display: none; position: absolute; }
3. Add the GSAP animation library to your HTML document:
<script src="/dist/gsap.min.js"></script>
4. Add this JavaScript code to enable the pixelated transition effect:
document.addEventListener('DOMContentLoaded', function () { const animationStepDuration = 0.3; // Adjust this value to control the timing const gridSize = 7; // Number of pixels per row and column (adjustable) // Calculate pixel size dynamically const pixelSize = 100 / gridSize; // Calculate the size of each pixel as a percentage // Select all cards const cards = document.querySelectorAll('[data-pixelated-image-reveal]'); // Detect if device is touch device const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0 || window.matchMedia("(pointer: coarse)").matches; // Loop through each card cards.forEach((card) => { const pixelGrid = card.querySelector('[data-pixelated-image-reveal-grid]'); const activeCard = card.querySelector('[data-pixelated-image-reveal-active]'); // Remove any existing pixels with the class 'pixelated-image-card__pixel' const existingPixels = pixelGrid.querySelectorAll('.pixelated-image-card__pixel'); existingPixels.forEach(pixel => pixel.remove()); // Create a grid of pixels dynamically based on the gridSize for (let row = 0; row < gridSize; row++) { for (let col = 0; col < gridSize; col++) { const pixel = document.createElement('div'); pixel.classList.add('pixelated-image-card__pixel'); pixel.style.width = `${pixelSize}%`; // Set the pixel width dynamically pixel.style.height = `${pixelSize}%`; // Set the pixel height dynamically pixel.style.left = `${col * pixelSize}%`; // Set the pixel's horizontal position pixel.style.top = `${row * pixelSize}%`; // Set the pixel's vertical position pixelGrid.appendChild(pixel); } } const pixels = pixelGrid.querySelectorAll('.pixelated-image-card__pixel'); const totalPixels = pixels.length; const staggerDuration = animationStepDuration / totalPixels; // Calculate stagger duration dynamically let isActive = false; // Variable to track if the card is active let delayedCall; const animatePixels = (activate) => { isActive = activate; gsap.killTweensOf(pixels); // Reset any ongoing animations if (delayedCall) { delayedCall.kill(); } gsap.set(pixels, { display: 'none' }); // Make all pixels invisible instantly // Show pixels randomly gsap.to(pixels, { display: 'block', duration: 0, stagger: { each: staggerDuration, from: 'random' } }); // After animationStepDuration, show or hide the activeCard delayedCall = gsap.delayedCall(animationStepDuration, () => { if (activate) { activeCard.style.display = 'block'; // **Set pointer-events to none so clicks pass through activeCard** activeCard.style.pointerEvents = 'none'; } else { activeCard.style.display = 'none'; } }); // Hide pixels randomly gsap.to(pixels, { display: 'none', duration: 0, delay: animationStepDuration, stagger: { each: staggerDuration, from: 'random' } }); }; if (isTouchDevice) { // For touch devices, use click event card.addEventListener('click', () => { animatePixels(!isActive); }); } else { // For non-touch devices, use mouseenter and mouseleave card.addEventListener('mouseenter', () => { if (!isActive) { animatePixels(true); } }); card.addEventListener('mouseleave', () => { if (isActive) { animatePixels(false); } }); } }); });
How It Works:
The JavaScript code first sets up a grid of div elements. These act as the “pixels.” Each pixel is sized and positioned using percentages. This approach makes the grid responsive.
The code then uses GSAP to animate these pixels. When you hover (or tap on touch devices), the pixels are displayed one by one, but with a random start point. It creates the visual transition, and the activeCard is set to visiable. After the animation time which defined in animationStepDuration, these pixels become invisible, also with random start point.
The isTouchDevice check optimizes the interaction. On touch devices, a click triggers the effect. On non-touch devices, the effect is triggered by hovering.