H5 活动页翻页动画:Swiper 全屏滑动、元素入场和 3D 过渡

H5 活动页翻页动画:Swiper 全屏滑动、元素入场和 3D 过渡

这篇文章复盘的是以前 H5 活动页里常见的一类效果:一屏一页,上下滑动翻页,每一页里的图片、文字、按钮按顺序入场。

这种页面在早期移动端活动页、招聘页、品牌介绍页里很常见。它不是普通网页滚动,而是更像 PPT:用户每滑一下,就切换到下一屏。

我在旧项目里看到了一套比较完整的实现方式,主要用到了:

  • Swiper
  • swiper.animate
  • animate.css
  • CSS3 @keyframes
  • transform: translate3d(...)
  • opacity
  • rem 和简单的屏幕缩放

适合提炼的技术点

这类页面里最值得单独拿出来讲的,不是某个业务页面,而是这些前端技术点:

  1. 怎么用 Swiper 做 H5 全屏上下翻页。
  2. 怎么让每一页的元素进入当前页时才播放动画。
  3. 怎么通过 onProgress 自定义翻页过程中的 3D 过渡效果。
  4. 怎么做底部“向上滑动”箭头提示动画。
  5. 怎么处理 320x480 旧设计稿到不同手机屏幕的缩放。

下面逐个拆开。

一、页面结构:一屏就是一个 swiper-slide

页面基本结构是:

<div class="swiper-container">
  <div class="swiper-wrapper">
    <section class="swiper-slide">
      第一屏内容
    </section>

    <section class="swiper-slide">
      第二屏内容
    </section>

    <section class="swiper-slide">
      第三屏内容
    </section>
  </div>

  <div class="swiper-pagination"></div>
  <img src="images/arrow.png" id="array">
</div>

关键点是:

  • swiper-container 占满整个屏幕。
  • swiper-wrapper 包住所有页面。
  • 每一个 swiper-slide 就是一屏。
  • 底部箭头 #array 用来提示用户继续向上滑。

对应 CSS:

html,
body {
  height: 100%;
}

.swiper-container {
  width: 100%;
  height: 100%;
  background: #000;
}

.swiper-slide {
  width: 100%;
  height: 100%;
  background-size: 100% 100%;
}

这一步解决的是“整屏翻页”的基础布局。

二、初始化 Swiper:设置 vertical 翻页

旧项目里 Swiper 初始化大致是这样:

var mySwiper = new Swiper(".swiper-container", {
  direction: "vertical",
  pagination: ".swiper-pagination",
  loop: true,
  mousewheelControl: true
});

几个配置的作用:

  • direction: "vertical":上下翻页。
  • pagination:右侧或底部小圆点分页。
  • loop: true:循环翻页。
  • mousewheelControl: true:PC 上也可以用鼠标滚轮切换,方便调试。

这样页面就从普通滚动变成了“整屏切换”。

三、元素入场动画:ani + swiper-animate-effect

页面里很多元素都写了类似这样的属性:

<img
  class="ani"
  src="images/logo.png"
  swiper-animate-effect="zoomIn"
  swiper-animate-duration="1.2s"
  swiper-animate-delay="0s"
>

这几个属性来自 swiper.animate

  • class="ani":标记这个元素需要动画。
  • swiper-animate-effect:动画名称,比如 zoomInbounceInRight
  • swiper-animate-duration:动画时长。
  • swiper-animate-delay:延迟多久开始。

实际动画效果来自 animate.css

这套写法很适合 H5 活动页,因为每一页里有很多素材:logo、标题、人物、按钮、二维码。它们不是同时出现,而是按节奏依次出现。

例如:

<div
  class="ani"
  swiper-animate-effect="bounceInRight"
  swiper-animate-duration="1.2s"
  swiper-animate-delay="0s"
>
  第一段文案
</div>

<div
  class="ani"
  swiper-animate-effect="fadeIn"
  swiper-animate-duration="1.2s"
  swiper-animate-delay="1s"
>
  第二段文案
</div>

这样第一段先出现,第二段延迟 1 秒出现,页面就会有讲故事的节奏。

四、切换页面时重新触发动画

如果只写动画属性,还不够。因为 Swiper 切换到下一页时,需要让当前页的元素重新播放动画。

旧代码里用了三个生命周期回调:

var mySwiper = new Swiper(".swiper-container", {
  direction: "vertical",

  onInit: function (swiper) {
    swiperAnimateCache(swiper);
    swiperAnimate(swiper);
  },

  onSlideChangeEnd: function (swiper) {
    swiperAnimate(swiper);
  },

  onTransitionEnd: function (swiper) {
    swiperAnimate(swiper);
  }
});

这里的逻辑是:

  1. 页面初始化时,先缓存动画元素。
  2. 初始化完成后播放当前页动画。
  3. 每次切换结束,再播放当前页动画。

swiperAnimateCache(swiper) 可以理解为“先把未进入当前屏的动画元素藏起来”。

swiperAnimate(swiper) 可以理解为“当前页到了,就把这一页的动画放出来”。

这就是 H5 翻页动画最核心的一步。

五、底部箭头提示动画

活动页通常会在底部放一个小箭头,提示用户继续滑动。

旧代码里用 @keyframes 做了一个上下浮动 + 透明度变化的效果:

@keyframes start {
  0%,
  30% {
    opacity: 0;
    transform: translate(0, 10px);
  }

  60% {
    opacity: 1;
    transform: translate(0, 0);
  }

  100% {
    opacity: 0;
    transform: translate(0, -8px);
  }
}

#array {
  position: absolute;
  z-index: 999;
  animation: start 1.5s infinite ease-in-out;
}

这个动画做了三件事:

  • 一开始在下方并且透明。
  • 中间移动到原位并显示。
  • 最后继续向上移动并消失。

循环播放后,看起来就像箭头一直在提示“往上滑”。

这个效果很小,但很实用,几乎所有一屏一屏的 H5 都能用。

六、自定义 3D 翻页过渡

旧项目里最值得提炼的是这一段:它没有只用 Swiper 默认滑动,而是通过 onProgress 改每一页的透明度和 transform。

核心代码:

watchSlidesProgress: true,

onProgress: function (swiper) {
  for (var i = 0; i < swiper.slides.length; i++) {
    var slide = swiper.slides[i];
    var progress = slide.progress;
    var translate = progress * swiper.height / 4;
    var scale = 1 - Math.min(Math.abs(progress * 0.5), 1);
    var opacity = 1 - Math.min(Math.abs(progress / 2), 0.5);

    slide.style.opacity = opacity;

    var es = slide.style;
    es.webkitTransform =
      es.MsTransform =
      es.msTransform =
      es.MozTransform =
      es.OTransform =
      es.transform =
        "translate3d(0," +
        translate +
        "px,-" +
        translate +
        "px) scaleY(" +
        scale +
        ")";
  }
}

这段代码的核心是 progress

可以简单理解为:

  • 当前页的 progress 接近 0。
  • 上一页或下一页的 progress 会变成正数或负数。
  • 离当前页越远,绝对值越大。

于是就可以根据 progress 计算:

  • 这一页要移动多少:translate
  • 这一页要缩放多少:scale
  • 这一页要透明多少:opacity

最后统一写到 transform

translate3d(0, y, z) scaleY(scale)

这样翻页时就不只是普通上下滑动,而会带一点纵深和压缩感。

七、给过渡设置 transitionDuration

只改 transform 还不够,还需要让每一页跟着 Swiper 的速度过渡:

onSetTransition: function (swiper, speed) {
  for (var i = 0; i < swiper.slides.length; i++) {
    var es = swiper.slides[i].style;
    es.webkitTransitionDuration =
      es.MsTransitionDuration =
      es.msTransitionDuration =
      es.MozTransitionDuration =
      es.OTransitionDuration =
      es.transitionDuration =
        speed + "ms";
  }
}

这段代码是把 Swiper 当前的过渡速度同步到每一个 slide。

否则 transform 可能会瞬间变化,看起来就不平滑。

八、旧设计稿的缩放处理

在一个 demo 页面里,还看到过这种写法:

document.getElementsByTagName("html")[0].style.fontSize =
  document.documentElement.clientWidth / 20 + "px";

var scaleW = window.innerWidth / 320;
var scaleH = window.innerHeight / 480;
var resizes = document.querySelectorAll(".resize");

for (var j = 0; j < resizes.length; j++) {
  resizes[j].style.width = parseInt(resizes[j].style.width) * scaleW + "px";
  resizes[j].style.height = parseInt(resizes[j].style.height) * scaleH + "px";
  resizes[j].style.top = parseInt(resizes[j].style.top) * scaleH + "px";
  resizes[j].style.left = parseInt(resizes[j].style.left) * scaleW + "px";
}

这说明页面最初可能按 320x480 的设计稿写死了很多元素的位置,然后通过 JS 按屏幕比例重新计算。

这是一种早期活动页常见做法:

设计稿固定 320x480
        ↓
元素用绝对定位写死 width/height/top/left
        ↓
JS 按当前屏幕计算 scaleW、scaleH
        ↓
批量改元素尺寸和位置

这个方法能快速还原设计稿,但维护成本比较高。现在更推荐用 remvw、百分比、Flex 布局来减少 JS 计算。

九、可以提炼成自己的模板

如果以后要写一个类似 H5 翻页活动页,可以整理成这样的模板:

<link rel="stylesheet" href="swiper.min.css">
<link rel="stylesheet" href="animate.min.css">

<script src="swiper.min.js"></script>
<script src="swiper.animate.min.js"></script>

<div class="swiper-container">
  <div class="swiper-wrapper">
    <section class="swiper-slide">
      <img
        class="ani"
        src="logo.png"
        swiper-animate-effect="zoomIn"
        swiper-animate-duration="1s"
        swiper-animate-delay="0s"
      >
    </section>
  </div>
  <div class="swiper-pagination"></div>
  <div id="array">↑</div>
</div>

JS:

var mySwiper = new Swiper(".swiper-container", {
  direction: "vertical",
  pagination: ".swiper-pagination",
  mousewheelControl: true,

  onInit: function (swiper) {
    swiperAnimateCache(swiper);
    swiperAnimate(swiper);
  },

  onSlideChangeEnd: function (swiper) {
    swiperAnimate(swiper);
  },

  onTransitionEnd: function (swiper) {
    swiperAnimate(swiper);
  }
});

CSS:

html,
body,
.swiper-container,
.swiper-slide {
  width: 100%;
  height: 100%;
}

.ani {
  position: absolute;
}

这样就有了一个基础的翻页动画骨架。

十、复盘:这套写法的优缺点

优点:

  • 适合活动页,开发速度快。
  • 每一屏结构清楚,像做 PPT。
  • 入场动画声明在 HTML 上,调节时长和延迟很方便。
  • onProgress 可以扩展出更有层次的翻页效果。

缺点:

  • 很多元素使用绝对定位,后期维护比较麻烦。
  • 动画属性写在 HTML 上,页面长了会显得乱。
  • 旧版本 Swiper API 和新版本不完全一样,升级时需要改写。
  • 过度依赖图片素材,页面性能要注意。

总结

这个旧项目里最有价值的技术点,是一套完整的 H5 活动页动画思路:

Swiper 负责整屏翻页
swiper.animate 负责当前屏元素入场
animate.css 提供动画名称
@keyframes 做持续提示动画
onProgress 自定义翻页过程中的 3D 过渡
rem/scale 处理移动端适配

把这条链路理解清楚,以后再做活动页、招聘页、产品介绍页、年度总结页,就不会只是堆图片,而是能有意识地控制“页面怎么切换、元素什么时候出现、用户怎么知道还能继续滑”。

posted @ 2026-06-22 14:04  万物皆object  阅读(85)  评论(0)    收藏  举报