最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do I make my Vertical Image Animation Smoother? - Stack Overflow

programmeradmin1浏览0评论

I'm trying to make a parallax effect similar to the hover-over effects on the images on this site:

and here is the code I have so far:

document.querySelectorAll('.image-container').forEach(item => {
    const img = item.querySelector('img');

    item.addEventListener('mousemove', (e) => {
        const rect = item.getBoundingClientRect();
        const mouseY = e.clientY - rect.top; // Mouse Y position relative to the item
        const halfHeight = rect.height / 2; // Midpoint of the element
        const imgHeight = img.height - rect.height
        const mousePercentage = mouseY/imgHeight*100

        img.style.transform = `translateY(-${mousePercentage}px)`; // Move up
        img.style.transition = "transform 0s ease-out"
        
    });

    item.addEventListener('mouseleave', () => {
        img.style.transform = 'translateY(0)'; // Reset position when mouse leaves
        img.style.transition = " transform 2s ease-out"
    });

    item.addEventListener('mouseenter', () =>{
        img.style.transition = "transform 2s ease-out"
    })
});
#display-grid{
    display: grid;
    width: 80%;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(24%, 1fr));

}

.cell{
    border: 1px solid #EEEEEE;
    border-radius: 1rem;
    width: 100%;
    overflow-y: hidden;
    position: relative;
  overflow: hidden;
  border-radius: 12px;
  aspect-ratio: 1 / 1.2;
}

.cell .image-container{
  width: 100%;
  height: 90%;
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: 1rem;
  overflow-y: hidden;

}

.cell img {
  width: 100%;
  height: auto;
  object-fit: cover;
  object-position: top;
  border-radius: 1rem;
}
<div id="display-grid">
    <div class="cell">
      <div class="image-container">
        <img id="website-preview" src=".jpg?scale-down-to=1024">
      </div>
      <p>Image Title</p>
    </div>
    <div class="cell">
      <div class="image-container">
        <img id="website-preview" src=".jpg?scale-down-to=1024">
      </div>
      <p>InfoSwap</p>
    </div>
</div>

I'm trying to make a parallax effect similar to the hover-over effects on the images on this site: https://www.framer/gallery/categories/portfolio

and here is the code I have so far:

document.querySelectorAll('.image-container').forEach(item => {
    const img = item.querySelector('img');

    item.addEventListener('mousemove', (e) => {
        const rect = item.getBoundingClientRect();
        const mouseY = e.clientY - rect.top; // Mouse Y position relative to the item
        const halfHeight = rect.height / 2; // Midpoint of the element
        const imgHeight = img.height - rect.height
        const mousePercentage = mouseY/imgHeight*100

        img.style.transform = `translateY(-${mousePercentage}px)`; // Move up
        img.style.transition = "transform 0s ease-out"
        
    });

    item.addEventListener('mouseleave', () => {
        img.style.transform = 'translateY(0)'; // Reset position when mouse leaves
        img.style.transition = " transform 2s ease-out"
    });

    item.addEventListener('mouseenter', () =>{
        img.style.transition = "transform 2s ease-out"
    })
});
#display-grid{
    display: grid;
    width: 80%;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(24%, 1fr));

}

.cell{
    border: 1px solid #EEEEEE;
    border-radius: 1rem;
    width: 100%;
    overflow-y: hidden;
    position: relative;
  overflow: hidden;
  border-radius: 12px;
  aspect-ratio: 1 / 1.2;
}

.cell .image-container{
  width: 100%;
  height: 90%;
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: 1rem;
  overflow-y: hidden;

}

.cell img {
  width: 100%;
  height: auto;
  object-fit: cover;
  object-position: top;
  border-radius: 1rem;
}
<div id="display-grid">
    <div class="cell">
      <div class="image-container">
        <img id="website-preview" src="https://framerusercontent/images/B7ykrtzOQa5hEXGFIhcq8gyaE.jpg?scale-down-to=1024">
      </div>
      <p>Image Title</p>
    </div>
    <div class="cell">
      <div class="image-container">
        <img id="website-preview" src="https://framerusercontent/images/B7ykrtzOQa5hEXGFIhcq8gyaE.jpg?scale-down-to=1024">
      </div>
      <p>InfoSwap</p>
    </div>
</div>

I have made it as far as having the image scroll within the frame up and down a variable % depending on where the mouse is in the image-container, but I find when the mouse enters the image-container, the image jumps to the coordinates. If I add a transition time to my stylesheet or to the "mousemove" Event Listener, I find the image waits for the mouse to stop moving before slowly moving to where the image needs to be.

What can I do so that the image moves smoothly and consistently on entry, moving, and leaving the container?

Share Improve this question edited Mar 14 at 9:55 Sofiyullahi Olamilekan Jamiu 4074 silver badges11 bronze badges asked Mar 13 at 2:19 SkiddswarmikSkiddswarmik 2701 gold badge2 silver badges14 bronze badges 1
  • 2 Why do you call this shift effect “parallax”? Even though it has something in common (a very small similarity) and if this is a kind of jargon, this is not parallax. Also, what is the purpose of this shift on hover? What's the point? You can always peek CSS of that size, but... why?! – Sergey A Kryukov Commented Mar 13 at 3:02
Add a comment  | 

1 Answer 1

Reset to default 2

You're close to achieving the same effect seen on the provided site. You just need to change the "mouse move" state part, inside the JavaScript, from this:

img.style.transition = "transform 0s ease-out"

to this:

img.style.transition = "transform 2s ease-out" 

Like so:

document.querySelectorAll('.image-container').forEach(item => {
    const img = item.querySelector('img');

    item.addEventListener('mousemove', (e) => {
        const rect = item.getBoundingClientRect();
        const mouseY = e.clientY - rect.top; // Mouse Y position relative to the item
        const halfHeight = rect.height / 2; // Midpoint of the element
        const imgHeight = img.height - rect.height
        const mousePercentage = mouseY/imgHeight*100

        img.style.transform = `translateY(-${mousePercentage}px)`; // Move up
        img.style.transition = "transform 2s ease-out" // this is the changed part
        
    });

    item.addEventListener('mouseleave', () => {
        img.style.transform = 'translateY(0)'; // Reset position when mouse leaves
        img.style.transition = " transform 2s ease-out"
    });

    item.addEventListener('mouseenter', () =>{
        img.style.transition = "transform 2s ease-out"
    })
});
#display-grid {
  display: grid;
  width: 80%;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(24%, 1fr));

}

.cell {
  border: 1px solid #EEEEEE;
  border-radius: 1rem;
  width: 100%;
  overflow-y: hidden;
  position: relative;
  overflow: hidden;
  border-radius: 12px;
  aspect-ratio: 1 / 1.2;
}

.cell .image-container {
  width: 100%;
  height: 90%;
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: 1rem;
  overflow-y: hidden;

}

.cell img {
  width: 100%;
  height: auto;
  object-fit: cover;
  object-position: top;
  border-radius: 1rem;
}
<div id="display-grid">
  <div class="cell">
    <div class="image-container">
      <img id="website-preview" src="https://framerusercontent/images/B7ykrtzOQa5hEXGFIhcq8gyaE.jpg?scale-down-to=1024">
    </div>
    <p>Image Title</p>
  </div>
  <div class="cell">
    <div class="image-container">
      <img id="website-preview" src="https://framerusercontent/images/B7ykrtzOQa5hEXGFIhcq8gyaE.jpg?scale-down-to=1024">
    </div>
    <p>InfoSwap</p>
  </div>
</div>

Known Issue:

Sometimes, when the browser's DevTools is open, the performance throttling kicks in to limit how frequently the mousemove events are fired, especially if the browser detects excessive rendering work.

发布评论

评论列表(0)

  1. 暂无评论