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

实现图片到内容的Zoom in过渡效果及滚动问题修复求助

图片到内容的Zoom In过渡效果实现方案

问题说明

我正在学习原生JavaScript,需完成一个点击按钮触发图片到内容的Zoom in过渡效果项目,需求如下:

  • 页面初始展示占满浏览器视口的图片+按钮(intro容器)
  • 点击按钮后,先延迟1-2秒,再进行平滑的Zoom in过渡(效果类似穿过图片中的门进入场景)
  • 过渡完成后显示网站实际内容(trailer容器)

当前代码存在两个问题:

  1. 过渡效果不符合预期
  2. 因body设置overflow:hidden、trailer-container设置position:fixed,导致页面无法滚动

修复方案

1. 优化Zoom In过渡效果

  • 给intro容器添加overflow:hidden,防止图片缩放溢出
  • 动态设置缩放原点为按钮位置(视觉焦点),用transform-origin锚定按钮中心,模拟"穿过门"的沉浸感
  • 用setTimeout实现1.5秒延迟后执行缩放动画
  • 缩放完成后隐藏intro容器,避免遮挡主体内容

2. 恢复页面滚动功能

  • 移除body默认的overflow:hidden,仅在intro显示时临时添加该属性,过渡完成后移除
  • 将trailer-container的position:fixed改为position:relative,回归正常文档流
  • 调整trailer-container布局,用常规方法适配内容,移除transform: translate(-50%, -50%)

修改后的完整代码

HTML

<body>
  <div class="intro-container">
    <img src="https://www.hoganbakery.com.my/wp-content/uploads/2019/09/lion-office-tower.jpg" alt="场景图片">
    <button class="btn">点击进入选择页面</button>
  </div>
  <div class="trailer-container active">
    <form action="" name="myForm">
      <section class="first-section">
        <h3>选择商品:</h3>
        <div>
          <input type="number" name="bread" id="bread" placeholder="数量?">
          <label for="bread">面包</label>
        </div>
        <div>
          <input type="number" name="croissant" id="croissant" placeholder="数量?">
          <label for="croissant">可颂</label>
        </div>
      </section>
      <section class="third-section">
        <h3>您有账号吗?</h3>
        <div>
          <input type="radio" name="account" id="yes">
          <label for="yes">我有账号</label>
        </div>
        <div>
          <input type="radio" name="account" id="no">
          <label for="no">我没有账号</label>
        </div>
      </section>
      <section class="commands">
        <input type="button" id="submit" value="提交">
      </section>
    </form>
  </div>
</body>

CSS

body {
  margin: 0;
  /* 初始不隐藏滚动,仅intro显示时添加类控制 */
}

body.intro-active {
  overflow: hidden;
  height: 100vh;
}

.intro-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  overflow: hidden;
  z-index: 10;
  transition: opacity 0.5s ease-out;
}

.intro-container img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  transition: transform 2s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.intro-container.disappear img {
  transform: scale(5);
}

.intro-container.hidden {
  opacity: 0;
  pointer-events: none;
}

button.btn {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  padding: 15px 20px;
  background: #2a78d7;
  font-size: 18px;
  font-weight: 700;
  border-radius: 12px;
  cursor: pointer;
  color: white;
  text-transform: uppercase;
  border: 3px solid #20323e;
  text-shadow: 1px 1px 4px black;
  z-index: 11;
}

.trailer-container {
  position: relative;
  width: 100%;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: start;
  align-items: center;
  background-color: rgb(228, 223, 224);
  padding: 2rem 0;
  opacity: 0;
  transition: opacity 0.5s ease-in;
}

.trailer-container.active {
  opacity: 1;
}

form {
  width: 90%;
  max-width: 600px;
}

section {
  margin-bottom: 2rem;
}

JavaScript

const btnEl = document.querySelector(".btn");
const trailerContainerEl = document.querySelector(".trailer-container");
const introContainerEl = document.querySelector(".intro-container");
const introImgEl = introContainerEl.querySelector("img");
const bodyEl = document.body;

// 动态设置缩放原点为按钮中心位置
const btnRect = btnEl.getBoundingClientRect();
const originX = btnRect.left + btnRect.width / 2;
const originY = btnRect.top + btnRect.height / 2;
introImgEl.style.transformOrigin = `${originX}px ${originY}px`;

btnEl.addEventListener("click", () => {
  // 临时隐藏页面滚动
  bodyEl.classList.add("intro-active");
  
  // 1.5秒延迟后执行缩放动画
  setTimeout(() => {
    introContainerEl.classList.add("disappear");
    
    // 缩放动画完成后,隐藏intro、显示内容并恢复滚动
    setTimeout(() => {
      introContainerEl.classList.add("hidden");
      trailerContainerEl.classList.remove("active");
      bodyEl.classList.remove("intro-active");
    }, 2000);
  }, 1500);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 10:25:14