You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

图片:hover交互效果实现后,布局与代码优化问题求助

问题解决与代码优化方案

1. 图案居中显示在衬衫图片上

当前图案未居中是因为.scale元素的原点设置偏移,且容器未做居中对齐。修改如下:

  • 给.art容器添加居中布局,确保图案处于容器中心:
.grid-container > div > .art {
  grid-area: 1/1;
  transition: .5s;
  display: grid;
  place-items: center;
}
  • 调整.scale和对应动画的原点为中心:
.grid-container > div > .art > .scale {
  max-width: 50%;
  transform-origin: center;
}

.scale {
  opacity: 0;
  transform-origin: center;
}

@keyframes scale {
  0%{
    transform-origin: center;
    transform: scale(0,0);
    opacity: 0;
  }
  100%{
    transform-origin: center;
    transform: scale(1,1);
    opacity: 1;
  }
}
  • 移除 hover 时.art的底部原点设置:
.grid-container div:hover .art {
  transform: scale(2);
}

2. 限制衬衫图片不超过原始尺寸

通过给.shirt容器设置宽度限制,确保图片最大显示为原始尺寸:

.grid-container > div > .shirt {
  grid-area: 1/1;
  transition: .5s;
  max-width: fit-content;
}

.grid-container > div > .shirt > .slideup {
  max-width: 100%;
  width: 100%;
}

这样容器宽度不会超出图片原始尺寸,图片也就不会被过度放大。

3. 简化JavaScript代码

将重复的IntersectionObserver实例合并为一个,通过类名匹配对应动画:

const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    const target = entry.target;
    let animationName = '';
    let duration = '1s';

    if (target.classList.contains('anim')) {
      animationName = 'square-animation';
      duration = '.5s';
    } else if (target.classList.contains('slideup')) {
      animationName = 'slideup';
    } else if (target.classList.contains('scale')) {
      animationName = 'scale';
    } else if (target.classList.contains('sliding')) {
      animationName = 'sliding';
      duration = '.5s';
    }

    if (entry.intersectionRatio > 0) {
      target.style.animation = `${animationName} ${duration} ${target.dataset.delay} forwards ease-out`;
    } else {
      target.style.animation = 'none';
    }
  });
});

const elements = document.querySelectorAll('.anim, .slideup, .scale, .sliding');
elements.forEach(el => observer.observe(el));

优化后完整代码

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>HOME</title>
    <link rel="stylesheet" href="stylesheet.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fullPage.js/4.0.11/fullpage.min.css"
        integrity="sha512-NGRhMiWY9pf5z8PLens7/u+LLwIPAu1dhJ7u9sHRWIo8TKrVbKiWlRdYRH3pVDCZA10zmobo+PBLGeLOREklBw=="
        crossorigin="anonymous" referrerpolicy="no-referrer" />
</head>
<body>
    <div id="fullpage">
        <div class="section one">
            <div class="grid-title-container">
                <div class="title-bar anim" data-delay=".1s">
                    <p class="title-text"> First Banner </p>
                </div>
                <div class="grid-container ">                        
                    <div>
                        <div class="shirt">
                            <img src="https://i.imgur.com/oS8QWPI.png" class="slideup" data-delay=".4s">
                        </div>
                        <div class="art">
                            <img src="https://i.imgur.com/jeNzULX.png"    class="scale" data-delay="1s">
                        </div>
                    </div>
                    <div>
                        <div class="shirt">
                            <img src="https://i.imgur.com/oS8QWPI.png" class="slideup" data-delay=".6s">
                        </div>
                        <div class="art">
                            <img src="https://i.imgur.com/jeNzULX.png"    class="scale" data-delay="1.2s">
                        </div>
                    </div>
                    <div>
                        <div class="shirt">
                            <img src="https://i.imgur.com/oS8QWPI.png" class="slideup" data-delay=".8s">
                        </div>
                        <div class="art">
                            <img src="https://i.imgur.com/jeNzULX.png"    class="scale" data-delay="1.4s">
                        </div>
                    </div>
                </div>
           </div>
        </div>
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/fullPage.js/4.0.11/fullpage.min.js"
        integrity="sha512-ojnoeSkK5NDwnuW5S0ZnddobHez8Bx1yVa3RE+Cd0fGEuY/NEd4sgVF/CJ6eDtnOeLZLbTJpNFrCkUYbHS2hRA=="
        crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script src="script.js"></script>
    <script>
        new fullpage('#fullpage', {
            autoScrolling: true,
            scrollHorizontally: true
        });
    </script>
</body>
</html>

CSS

.section {
  height: 100%;
  width: 100%;
  display: block;
}
.section.one{
  background-color: rgb(6, 65, 65);
}

.title-bar {
  display: flex;
  overflow: visible;
  width: 100vw;
  height: 8vh;
  max-width: 70vw;
  min-height: 1vh;
  margin-top: 5vh;
  margin-bottom: 5vh;
  margin-right: auto;
  margin-left: auto;
  justify-content: center;
  align-items: center;
  border-top-style: solid;
  border-top-width: 1vh;
  border-top-color: #28f7e6;
  border-bottom-style: solid;
  border-bottom-width: 1vh;
  border-bottom-color: #28f7e6;
  perspective-origin: 50% 50%;
  transform-origin: 50% 50%;
}

.title-text {
    text-align: center;
    font-size: 6vh;
    margin: 0px 0px;
    font-family: PT Serif;
    color: #28f7e6;
}

.grid-container {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  grid-column-gap: 1%;
  max-width:70%;
  margin:auto;
}
.grid-container > div  {
  display: grid;
  place-items: center;
}
 
.grid-container > div > .shirt {
  grid-area: 1/1;
  transition: .5s;
  max-width: fit-content;
}

.grid-container > div > .art {
  grid-area: 1/1;
  transition: .5s;
  display: grid;
  place-items: center;
}
  
.grid-container > div > .shirt > .slideup {
  max-width: 100%;
  width: 100%;
}

.grid-container > div > .art > .scale {
  max-width: 50%;
  transform-origin: center;
}
  
.grid-container div:hover .shirt {
  transform: scale(0);
}

.grid-container div:hover .art {
  transform: scale(2);
}

.anim {
  opacity: 0;
}

.slideup {
  opacity: 0;
}

.scale {
  opacity: 0;
  transform-origin: center;
}

.sliding {
  opacity: 0;
}

@keyframes square-animation {
  0%{
    transform: scale(0, 1);
    opacity: 0;
  }
  100%{
    transform: scale(1, 1);
    opacity: 1;
  }
}

@keyframes slideup {
  0%{
    transform: translate(0px,50%);
    opacity: 0;
  }
  100%{
    transform: translate(0px,0px);
    opacity: 1;
  }
}

@keyframes scale {
  0%{
    transform-origin: center;
    transform: scale(0,0);
    opacity: 0;
  }
  100%{
    transform-origin: center;
    transform: scale(1,1);
    opacity: 1;
  }
}

@keyframes rotate {
  0%{
    transform: rotate(90deg);
    opacity: 0;
  }
  100%{
    transform: rotate(0deg);
    opacity: 1;
  }
}

@keyframes sliding {
  0%{
    transform: translate(50px,10px);
    opacity: 0;
  }
  100%{
    transform: translate(0px,0px);
    opacity: 1;
  }
}

JavaScript

const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    const target = entry.target;
    let animationName = '';
    let duration = '1s';

    if (target.classList.contains('anim')) {
      animationName = 'square-animation';
      duration = '.5s';
    } else if (target.classList.contains('slideup')) {
      animationName = 'slideup';
    } else if (target.classList.contains('scale')) {
      animationName = 'scale';
    } else if (target.classList.contains('sliding')) {
      animationName = 'sliding';
      duration = '.5s';
    }

    if (entry.intersectionRatio > 0) {
      target.style.animation = `${animationName} ${duration} ${target.dataset.delay} forwards ease-out`;
    } else {
      target.style.animation = 'none';
    }
  });
});

const elements = document.querySelectorAll('.anim, .slideup, .scale, .sliding');
elements.forEach(el => observer.observe(el));

内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 06:25:16