• About Us
  • Privacy Policy
  • Disclaimer
  • Contact Us
AimactGrow
  • Home
  • Technology
  • AI
  • SEO
  • Coding
  • Gaming
  • Cybersecurity
  • Digital marketing
No Result
View All Result
  • Home
  • Technology
  • AI
  • SEO
  • Coding
  • Gaming
  • Cybersecurity
  • Digital marketing
No Result
View All Result
AimactGrow
No Result
View All Result

Animated Product Grid Preview with GSAP & Clip-Path

Admin by Admin
May 27, 2025
Home Coding
Share on FacebookShare on Twitter


My (design) accomplice, Gaetan Ferhah, likes to ship me his design and movement experiments all through the week. It’s at all times enjoyable to see what he’s engaged on, and it usually sparks concepts for my very own tasks. Someday, he despatched over a fast idea for making a product grid really feel a bit extra inventive and interactive. 💬 The concept for this tutorial got here from that message.

We’ll discover a “grid to preview” hover interplay that transforms product playing cards right into a full preview. As with many animations and interactions, there are often a number of methods to strategy the implementation—ranging in complexity. It might probably really feel intimidating (or nearly unattainable) to recreate a designer’s imaginative and prescient from scratch. However I’m an enormous fan of simplifying wherever doable and leaning on optical illusions (✨ pretend it ’til you make it ✨).

All photographs are generated with DALL-E (unhappy, I do know.. I wished the whole lot to be actual too 💔)

For this tutorial, I knew I wished to maintain issues simple and recreate the impact of puzzle items shifting into place utilizing a mixture of clip-path animation and a picture overlay.

Let’s break it down in a couple of steps:

  1. Structure and Overlay (HTML, CSS)Arrange the preliminary structure and punctiliously match the place of the preview overlay to the grid.
  2. Construct JavaScript construction (JavaScript)Creating some lessons to maintain us organised, add some interactivity (occasion listeners).
  3. Clip-Path Creation and Animation (CSS, JS, GSAP)Including and animating the clip-path, together with some calculations on resize—this types a key a part of the puzzle impact.
  4. Transferring Product Playing cards (JS, GSAP)Arrange animations to maneuver the product playing cards in direction of one another on hover.
  5. Preview Picture Scaling (JS, GSAP)Barely cutting down the preview overlay in response to the inward motion of the opposite components.
  6. Including Pictures (HTML, JS, GSAP)Sufficient with the strong colors, let’s add some photographs and a gallery animation.
  7. Debouncing occasions (JS)Debouncing the mouse-enter occasion to forestall extreme triggering and scale back jitter.
  8. Ultimate tweaks Crossed the t’s and dotted the i’s—small clean-ups and enhancements.

Structure and Overlay

On the basis of each good tutorial is a strong HTML construction. On this step, we’ll create two key components: the product grid and the overlay for the preview playing cards. Since each want an analogous structure, we’ll place them inside the identical container (.merchandise).

Our grid will include 8 merchandise (4 columns by 2 rows) with a gutter of 5vw. To maintain issues easy, I’m solely including the corresponding li components for the merchandise, however not but including some other components. Within the HTML, you’ll discover there are two preview containers: one for the left facet and one for the appropriate. If you wish to see the preview overlays immediately, head to the CodePen and set the opacity of .product-preview to 1.

Why I Opted for Two Containers

At first, I deliberate to make use of only one preview container and transfer it to the other facet of the hovered card by updating the grid-column-start. That strategy labored wonderful—till I obtained to testing.

Once I hovered over a product card on the left and rapidly switched to 1 on the appropriate, I realised the issue: with just one container, I additionally had only one timeline controlling the whole lot inside it. That made it mainly unattainable to handle the “in/out” transition between sides easily.

So, I made a decision to go together with two containers—one for the left facet and one for the appropriate. This manner, I may animate each side independently and keep away from timeline conflicts when switching between them.

See the Pen
Untitled by Gwen Bogaert (@gwen-bo)
on CodePen.

JavaScript Set-up

On this step, we’ll add some lessons to maintain issues structured earlier than including our occasion listeners and initiating our timelines. To maintain issues organised, let’s cut up it into two lessons: ProductGrid and ProductPreview.

ProductGrid can be pretty primary, answerable for dealing with the cut up between left and proper, and managing top-level occasion listeners (resembling mouseenter and mouseleave on the product playing cards, and a common resize).

ProductPreview is the place the magic occurs. ✨ That is the place we’ll management the whole lot that occurs as soon as a mouse occasion is triggered (enter or depart). To cross the ‘lively’ product, we’ll outline a setProduct technique, which, in later steps, will act as the place to begin for controlling our GSAP animation(s).

Splitting Merchandise (Left – Proper)

Within the ProductGrid class, we are going to cut up all of the merchandise into left and proper teams. We now have 8 merchandise organized in 4 columns, with every row containing 4 gadgets. We’re splitting the product playing cards into left and proper teams primarily based on their column place.

this.ui.merchandise.filter((_, i) => i % 4 === 2 || i % 4 === 3)

The logic depends on the modulo or the rest operator. The road above teams the product playing cards on the appropriate. We use the index (i) to test if it’s within the third (i % 4 === 2) or 4th (i % 4 === 3) place of the row (bear in mind, indexing begins at 0). The remaining merchandise (with i % 4 === 0 or i % 4 === 1) can be grouped on the left.

Now that we all know which merchandise belong to the left and proper sides, we are going to provoke a ProductPreview for each side and cross alongside the merchandise array. This may enable us to outline productPreviewRight and productPreviewLeft.

To finalize this step, we are going to outline occasion listeners. For every product, we’ll pay attention for mouseenter and mouseleave occasions, and both set or unset the lively product (each internally and within the corresponding ProductPreview class). Moreover, we’ll add a resize occasion listener, which is at present unused however can be arrange for future use.

That is the place we’re at thus far (solely adjustments in JavaScript):

See the Pen
Tutorial – step 2 (JavaScript construction) by Gwen Bogaert (@gwen-bo)
on CodePen.

Clip-path

On the base of our impact lies the clip-path property and the power to animate it with GSAP. Should you’re not conversant in utilizing clip-path to clip content material, I extremely suggest this text by Sarah Soueidan.

Regardless that I’ve used clip-path in lots of my tasks, I usually battle to recollect precisely outline the form I’m on the lookout for. As earlier than, I’ve as soon as once more turned to the fantastic software Clippy, to get a head begin on defining (or exploring) clip-path shapes. For me, it helps demystify which worth influences which a part of the form.

Let’s begin with the cross (from Clippy) and modify the factors to create a extra mathematical-looking cross (✚) as an alternative of the non secular model (✟).

clip-path: polygon(10% 25%, 35% 25%, 35% 0%, 65% 0%, 65% 25%, 90% 25%, 90% 50%, 65% 50%, 65% 100%, 35% 100%, 35% 50%, 10% 50%);

Be at liberty to experiment with among the values, and shortly you’ll discover that with small changes, we are able to get a lot nearer to the specified form! For instance, by stretching the horizontal arms fully to the perimeters (set to 10% and 90% earlier than) and shifting the whole lot extra equally in direction of the middle (with a ten% distinction from the middle — so both 40% or 60%).

clip-path: polygon(0% 40%, 40% 40%, 40% 0%, 60% 0%, 60% 40%, 100% 40%, 100% 60%, 60% 60%, 60% 100%, 40% 100%, 40% 60%, 0% 60%);

And bada bing, bada increase! This clip-path nearly instantly creates the phantasm that our single preview container is cut up into 4 elements — precisely the impact we wish to obtain! Now, let’s transfer on to animating the clip-path to get one step nearer to our closing outcome:

Animating Clip-paths

The idea of animating clip-paths is comparatively easy, however there are a couple of key issues to remember to make sure a clean transition. One essential consideration is that it’s finest to outline an equal variety of factors for each the beginning and finish shapes.

The concept is pretty simple: we start with the clipped elements hidden, and by the tip of the animation, we wish the clip-path to vanish, revealing your complete preview container (by making the arms of the cross so skinny that they’re barely seen or not seen in any respect). This may be achieved simply with a fromTo animation in GSAP (although it’s additionally supported in CSS animations).

The Catch

You may suppose, “That’s it, we’re achieved!” — however alas, there’s a catch relating to utilizing this as our puzzle impact. To make it look practical, we have to be sure that the form of the cross aligns with the underlying product grid. And that’s the place a little bit of JavaScript is available in!

We have to issue within the gutter of our grid (5vw) to calculate the width of the arms of our cross form. It may’ve been so simple as including or subtracting (half!) of the gutter to/from the 50%, however… there’s a catch within the catch!

We’re not working with a sq., however with a rectangle. Since our values are percentages, subtracting 2.5vw (half of the gutter) from the middle wouldn’t give us equal-sized arms. It is because there would nonetheless be a distinction between the x and y dimensions, even when utilizing the identical proportion worth. So, let’s check out repair that:

onResize() {
  const { width, top } = this.container.getBoundingClientRect()
  const vw = window.innerWidth / 100

  const armWidthVw = 5
  const armWidthPx = armWidthVw * vw

  this.armWidth = {
    x: (armWidthPx / width) * 100,
    y: (armWidthPx / top) * 100
  }
}

Within the code above (triggered on every resize), we get the width and top of the preview container (which spans 4 product playing cards — 2 columns and a pair of rows). We then calculate what proportion 5vw could be, relative to each the width and top.

To conclude this step, we’d have one thing like:

See the Pen
Tutorial – step 3 (clip path) by Gwen Bogaert (@gwen-bo)
on CodePen.

Transferring Product Playing cards

One other step within the puzzle impact is shifting the seen product playing cards collectively so they seem to kind one piece. This step is pretty easy — we already know the way a lot they should transfer (once more, gutter divided by 2 = 2.5vw). The one factor we have to work out is whether or not a card wants to maneuver up, down, left, or proper. And that’s the place GSAP involves the rescue!

We have to outline each the vertical (y) and horizontal (x) motion for every aspect primarily based on its index within the listing. Since we solely have 4 gadgets, and they should transfer inward, we are able to test whether or not the index is odd and even to find out the specified worth for the horizontal motion. For vertical motion, we are able to resolve whether or not it ought to transfer to the highest or backside relying on the place (prime or backside).

In GSAP, many properties (like x, y, scale, and so on.) can settle for a perform as an alternative of a set worth. Once you cross a perform, GSAP calls it for every goal aspect individually.

Horizontal (x): playing cards with a fair index (0, 2) get shifted proper by 2.5vw, the opposite (two) transfer to the left. Vertical (y): playing cards with an index decrease than 2 (0,1) are situated on the prime, so want to maneuver down, the opposite (two) transfer up.

{
  x: (i) => {
    return i % 2 === 0 ? '2.5vw' : '-2.5vw'
  },
  y: (i) => {
    return i < 2 ? '2.5vw' : '-2.5vw'
  }
}

See the Pen
Tutorial – step 3 (clip path) by Gwen Bogaert (@gwen-bo)
on CodePen.

Preview Picture (Scaling)

Cool, we’re slowly getting there! We now have our clip-path animating out and in on hover, and the playing cards are shifting inward as nicely. Nonetheless, you may discover that the playing cards and the picture not have a precise overlap as soon as the playing cards have been moved. To repair that and make the whole lot extra seamless, we’ll apply a slight scale to the preview container.

That is the place a bit of additional calculation is available in, as a result of we wish it to scale relative to the gutter. So we take into consideration the peak and width of the container.

onResize() {
    const { width, top } = this.container.getBoundingClientRect()
    const vw = window.innerWidth / 100
    
    // ...armWidth calculation (see earlier step)

    const widthInVw = width / vw
    const heightInVw = top / vw
    const shrinkVw = 5

    this.scaleFactor = {
      x: (widthInVw - shrinkVw) / widthInVw,
      y: (heightInVw - shrinkVw) / heightInVw
    }
  }

This calculation determines a scale issue to shrink our preview container inward, matching the playing cards coming collectively. First, the rectangle’s width/top (in pixels) is transformed into viewport width models (vw) by dividing it by the pixel worth of 1vw. Subsequent, the shrink quantity (5vw) is subtracted from that width/top. Lastly, the result’s divided by the unique width in vw to calculate the dimensions issue (which can be barely under 1). Since we’re working with a rectangle, the dimensions issue for the x and y axes can be barely completely different.

Within the codepen under, you’ll see the puzzle impact coming alongside properly on every container. Pink are the product playing cards (not shifting), purple and blue are the preview containers.

See the Pen
Tutorial – step 4 (shifting playing cards) by Gwen Bogaert (@gwen-bo)
on CodePen.

Including Footage

Let’s make our grid slightly extra enjoyable to have a look at!

On this step, we’re going so as to add the product photographs to our grid, and the product preview photographs contained in the preview container. As soon as that’s achieved, we’ll begin our picture gallery on hover.

The HTML adjustments are comparatively easy. We’ll add a picture to every product li aspect and… not do something with it. We’ll simply depart the picture as is.

  • "alt"
  • The remainder of the magic will occur contained in the preview container. Every container will maintain the preview photographs of the merchandise from the opposite facet (people who can be seen). So, the left container will include the pictures of the 4 merchandise on the appropriate, and the appropriate container will include the pictures of the 4 merchandise on the left. Right here’s an instance of one among these:

    As soon as that’s achieved, we are able to initialise by querying these photographs within the constructor of the ProductPreview, sorting them by their dataset.id. This may enable us to simply entry the pictures later through the data-index attribute that every product has. To sum up, on the finish of our animate-in timeline, we are able to name startPreviewGallery, which is able to deal with our gallery impact.

    startPreviewGallery(id) {
      const photographs = this.ui.previewImagesPerID[id]
      const timeline = gsap.timeline({ repeat: -1 })
    
      // first picture is already seen (don't cover)
      gsap.set([...images].slice(1), { opacity: 0 })
    
      photographs.forEach((picture) => {
        timeline
          .set(photographs, { opacity: 0 }) // Cover all photographs
          .set(picture, { opacity: 1 }) // Present solely this one
          .to(picture, { period: 0, opacity: 1 }, '+=0.5') 
      })
    
      this.galleryTimeline = timeline
    }

    Debouncing

    One factor I’d love to do is debounce hover results, particularly if they're extra advanced or take longer to finish. To realize this, we’ll use a easy (and vanilla) JavaScript strategy with setTimeout. Every time a hover occasion is triggered, we’ll set a really quick timer that acts as a debouncer, stopping the impact from firing if somebody is simply “passing by” on their strategy to the product card on the opposite facet of the grid.

    I ended up utilizing a 100ms “cooldown” earlier than triggering the animation, which helped scale back pointless animation begins and minimise jitter when interacting with the playing cards.

    productMouseEnter(product, preview) {
      // If one other timer (aka hover) was operating, cancel it
      if (this.hoverDelay) {
        clearTimeout(this.hoverDelay)
        this.hoverDelay = null
      }
    
      // Begin a brand new timer
      this.hoverDelay = setTimeout(() => {
        this.activeProduct = product
        preview.setProduct(product)
        this.hoverDelay = null // clear reference
      }, 100)
    }
    
    productMouseLeave() {
      // If person leaves earlier than debounce completes
      if (this.hoverDelay) {
        clearTimeout(this.hoverDelay)
        this.hoverDelay = null
      }
    
      if (this.activeProduct) {
        const preview = this.getProductSide(this.activeProduct)
        preview.setProduct(null)
        this.activeProduct = null
      }
    }

    Ultimate Tweaks

    I can’t consider we’re nearly there! Subsequent up, it’s time to piece the whole lot collectively and add some small tweaks, like experimenting with easings, and so on. The ultimate timeline I ended up with (which performs or reverses relying on mouseenter or mouseleave) is:

    buildTimeline() {
      const { x, y } = this.armWidth
    
      this.timeline = gsap
        .timeline({
          paused: true,
          defaults: {
            ease: 'power2.inOut'
          }
        })
        .addLabel('preview', 0)
        .addLabel('merchandise', 0)
        .fromTo(this.container, { opacity: 0 }, { opacity: 1 }, 'preview')
        .fromTo(this.container, { scale: 1 }, { scaleX: this.scaleFactor.x, scaleY: this.scaleFactor.y, transformOrigin: 'middle middle' }, 'preview')
        .to(
          this.merchandise,
          {
            opacity: 0,
            x: (i) => {
              return i % 2 === 0 ? '2.5vw' : '-2.5vw'
            },
            y: (i) => {
              return i < 2 ? '2.5vw' : '-2.5vw'
            }
          },
          'merchandise'
        )
        .fromTo(
          this.masked,
          {
            clipPath: `polygon(
          ${50 - x / 2}% 0%,
          ${50 + x / 2}% 0%,
          ${50 + x / 2}% ${50 - y / 2}%,
          100% ${50 - y / 2}%,
          100% ${50 + y / 2}%,
          ${50 + x / 2}% ${50 + y / 2}%,
          ${50 + x / 2}% 100%,
          ${50 - x / 2}% 100%,
          ${50 - x / 2}% ${50 + y / 2}%,
          0% ${50 + y / 2}%,
          0% ${50 - y / 2}%,
          ${50 - x / 2}% ${50 - y / 2}%
        )`
          },
          {
            clipPath: `polygon(
          50% 0%,
          50% 0%,
          50% 50%,
          100% 50%,
          100% 50%,
          50% 50%,
          50% 100%,
          50% 100%,
          50% 50%,
          0% 50%,
          0% 50%,
          50% 50%
          )`
          },
          'preview'
        )
    }

    Ultimate End result

    📝 A fast word on usability & accessibility

    Whereas this interplay could look cool and visually partaking, it’s essential to be aware of usability and accessibility. In its present kind, this impact depends fairly closely on movement and hover interactions, which might not be excellent for all customers. Right here are some things that must be thought-about for those who’d be planning on implementing an analogous impact:

    • Movement sensitivity: Make sure you respect the person’s prefers-reduced-motion setting. You'll be able to simply test this with a media question and supply a simplified or static various for customers preferring minimal movement.
    • Keyboard navigation: Since this interplay is hover-based, it’s not at present accessible through keyboard. Should you’d prefer to make it extra inclusive, take into account including assist for focus occasions and guaranteeing that each one interactive components could be reached and triggered utilizing a keyboard.

    Consider this as a playful, exploratory layer — not a basis. Use it thoughtfully, and prioritise accessibility the place it counts. 💛

    Acknowledgements

    I'm conscious that this tutorial assumes a super situation of solely 8 merchandise, as a result of what occurs if in case you have extra? I didn’t try it out myself, however the essential half is that the preview containers really feel like a precise overlay of the product grid. If extra playing cards are current, you would attempt ‘mapping’ the coordinates of the preview container to the 8 merchandise which might be fully in view. Or.. go loopy with your personal strategy for those who had one other thought. That’s the great thing about it, there’s at all times many approaches that may result in the identical (visible) end result. 🪄

    Thanks a lot for following alongside! An enormous due to Codrops for giving me the chance to contribute. I’m excited to see what you’ll create when impressed by this tutorial! If in case you have any questions, be happy to drop me a line!

    Tags: AnimatedClipPathgridGSAPPreviewproduct
    Admin

    Admin

    Next Post
    Enterprise to the Supply of a Lethal Curse in Wizardry Variants Daphne

    Enterprise to the Supply of a Lethal Curse in Wizardry Variants Daphne

    Leave a Reply Cancel reply

    Your email address will not be published. Required fields are marked *

    Recommended.

    Gmail unveils end-to-end encrypted messages. Solely factor is: It’s not true E2EE.

    Gmail unveils end-to-end encrypted messages. Solely factor is: It’s not true E2EE.

    April 4, 2025
    How I write SMART objectives and make them a actuality [+ free SMART goal templates]

    How I write SMART objectives and make them a actuality [+ free SMART goal templates]

    May 16, 2025

    Trending.

    Industrial-strength April Patch Tuesday covers 135 CVEs – Sophos Information

    Industrial-strength April Patch Tuesday covers 135 CVEs – Sophos Information

    April 10, 2025
    Expedition 33 Guides, Codex, and Construct Planner

    Expedition 33 Guides, Codex, and Construct Planner

    April 26, 2025
    How you can open the Antechamber and all lever places in Blue Prince

    How you can open the Antechamber and all lever places in Blue Prince

    April 14, 2025
    Important SAP Exploit, AI-Powered Phishing, Main Breaches, New CVEs & Extra

    Important SAP Exploit, AI-Powered Phishing, Main Breaches, New CVEs & Extra

    April 28, 2025
    Wormable AirPlay Flaws Allow Zero-Click on RCE on Apple Units by way of Public Wi-Fi

    Wormable AirPlay Flaws Allow Zero-Click on RCE on Apple Units by way of Public Wi-Fi

    May 5, 2025

    AimactGrow

    Welcome to AimactGrow, your ultimate source for all things technology! Our mission is to provide insightful, up-to-date content on the latest advancements in technology, coding, gaming, digital marketing, SEO, cybersecurity, and artificial intelligence (AI).

    Categories

    • AI
    • Coding
    • Cybersecurity
    • Digital marketing
    • Gaming
    • SEO
    • Technology

    Recent News

    Tackle bar exhibits hp.com. Browser shows scammers’ malicious textual content anyway.

    Tackle bar exhibits hp.com. Browser shows scammers’ malicious textual content anyway.

    June 18, 2025
    What’s going to influencer advertising and marketing appear to be in 2025? Knowledgeable predictions + new knowledge

    What’s going to influencer advertising and marketing appear to be in 2025? Knowledgeable predictions + new knowledge

    June 18, 2025
    • About Us
    • Privacy Policy
    • Disclaimer
    • Contact Us

    © 2025 https://blog.aimactgrow.com/ - All Rights Reserved

    No Result
    View All Result
    • Home
    • Technology
    • AI
    • SEO
    • Coding
    • Gaming
    • Cybersecurity
    • Digital marketing

    © 2025 https://blog.aimactgrow.com/ - All Rights Reserved