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

如何实现类似Mobile Depth Page Transformer的上下滑动卡片滚动动画?

实现移动端上下滑动卡片深度滚动动画

需求

实现类似深度页面转换效果的移动端上下滑动卡片滚动动画(滑动时卡片依次堆叠切换的视觉效果)。

尝试实现方案

使用position: sticky实现,代码如下:

容器样式

.gallery{
    width: 35rem;
    height: 22rem;
    position: relative;
    display: flex;
    flex-direction: column;
    overflow: auto;
    scroll-snap-type: y mandatory;
}

图片卡片样式

.gallery img{
    width: 100%;
    height: 100%;
    position: sticky;
    top: 0;
    flex-shrink: 0;
    object-fit: cover;
    scroll-snap-align: start;
}

额外样式

.gallery, .gallery img{
    transform: rotate(180deg);
}

遇到的问题

  • 卡片顺序颠倒(首卡变尾卡,尾卡变首卡)
  • 代码难以对接API实现自动化
  • 滚动速度过快

解决方案

1. 修复卡片顺序颠倒问题

移除transform: rotate(180deg)样式,该旋转操作会直接反转容器和卡片的整体顺序。若需调整滚动方向,可通过修改容器的flex-direction或滚动属性实现,而非旋转元素:

/* 移除旋转样式 */
.gallery, .gallery img{
    /* transform: rotate(180deg); */
}

2. 优化API对接的自动化实现

将卡片渲染改为动态生成,通过循环遍历API返回的图片列表创建DOM元素,同时抽离通用样式类:

// 示例:从API获取图片列表后动态生成卡片
const gallery = document.querySelector('.gallery');
const imageList = await fetch('你的API地址').then(res => res.json());

imageList.forEach(imgUrl => {
    const img = document.createElement('img');
    img.src = imgUrl;
    img.classList.add('gallery-item');
    gallery.appendChild(img);
});
.gallery-item{
    width: 100%;
    height: 100%;
    position: sticky;
    top: 0;
    flex-shrink: 0;
    object-fit: cover;
    scroll-snap-align: start;
}

3. 控制滚动速度

通过CSS开启平滑滚动,或用JavaScript实现自定义滚动逻辑:

.gallery{
    /* 新增平滑滚动 */
    scroll-behavior: smooth;
}

若需更精细控制,可拦截原生滚动事件:

const gallery = document.querySelector('.gallery');
let isScrolling = false;

gallery.addEventListener('wheel', (e) => {
    e.preventDefault();
    if(isScrolling) return;
    
    isScrolling = true;
    const scrollStep = e.deltaY > 0 ? gallery.clientHeight : -gallery.clientHeight;
    let currentScroll = gallery.scrollTop;
    const targetScroll = currentScroll + scrollStep;
    
    const animateScroll = () => {
        const diff = targetScroll - currentScroll;
        const step = diff * 0.1;
        currentScroll += step;
        
        if(Math.abs(diff) < 1){
            gallery.scrollTop = targetScroll;
            isScrolling = false;
            return;
        }
        
        gallery.scrollTop = currentScroll;
        requestAnimationFrame(animateScroll);
    };
    
    requestAnimationFrame(animateScroll);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 19:42:16