Skip to content
On this page

滚动动画的实现

有次看到Mackbook Pro的页面动画很酷炫:他会随着鼠标滚轮的滚动距离来加载动画(大部分是替换图片的操作)。本节我们就来看看它的实现方式。

实现方式

scroll事件+关键帧

这是Mackbook官网使用的方式,也是兼容性比较好的一种 首先确定dom结构,要保证随着滚动页面不滚只是播放动画的效果,我们将每个子元素设置上position:sticky,并在外包上一个固定高度的容器,这里我们暂定500vh

html
<div class="container">
    <div class="h-500vh">
        <div class="sticky top-0 left-0"></div>
    </div>
    <div class="h-500vh">
        <div class="sticky top-0 left-0"></div>
    </div>
    ...
</div>

这时候我们发现,滑动滚轮,在sticky下的内容滚出500vh之前都会保持不动,接着我们需要监听container的scroll事件,来判断当前活跃的滚动元素并播放相应的动画。

vue
<template>
    <div class="container" @scroll="detectScroll">
        ...
    </div>
</template>
<script setup>
    // 按元素顺序插入响应的动画函数
    const aniFn=[...]
    function detectScroll(e){
        // 当前活跃的元素索引
        const activeIndex=0
        // 当前活跃元素的滚动百分比
        const rate = 0
        aniFn[activeIndex]?.(rate)
    }
</script>

首先我们通过元素高度(500vh)和container当前滚动距离的关系可以得知activeIndex,之后再通过元素高度和元素内的滚动距离来计算出rate,有了这两个变量,我们就能很轻松的调用相应的动画元素并根据rate在每个函数里实现自己的动画效果。

CSS @scroll-timeline

根据window的滚动距离来充当动画的进度

WARNING

需要开启chrome的实验特性 示例

查看源码
vue
<template>
    <div class="ani-scroll-scale origin-left">这是chrome的一个实验属性,我们来简单示范下</div>
</template>
<script lang='ts' setup>


</script>
<style>
.ani-scroll-scale {
    animation: scale 1s ease-in;
    animation-timeline: box-move;
}

@scroll-timeline box-move {
    orientation: "vertical";
}

@keyframes scale {
    from {
        transform: scale(1);
    }

    to {
        transform: scale(2);
    }
}
</style>
这是chrome的一个实验属性,我们来简单示范下

Date: 2022/06/07

Authors: 徐安海

Tags: 动画、svg