超轻的页面滚动库 lax.js

13,994 阅读5分钟

钉钉官网的特效,自己的实现起来还是比较复杂。以下是它交互逻辑,

  • 进入状态

image.png

  • logo 上移滚动状态

滚动状态.png

  • 开始展开状态

开始展开状态.png

  • 绝大部分内容展开状态

绝大部分展开状态.png

  • 全部展开状态

全部展开状态.png

动画需求综合分析

  • 核心:页面滚动触发动画
  • 页面滚动 钉钉 logo + description 发生 位置/大小/透明度 等 css 变化。
  • 当 钉钉 logo 开始消失,钉钉的内部的常用功能开始展现,从一个中间位置,随着页面的滚动开始移动到自己的位置。形成一个列表。

lax.js

首先要搞明白 lax.js 是什么? Lax.js 自己这样说:

Simple & lightweight (<4kb gzipped) vanilla JavaScript library to create smooth & beautiful animations when you scroll. 轻量级的原生 js 库,为了在滚动时创建滑动漂亮的动画。

一个简单的 lax.js 源码提取

lax-source-simple.png

lax 采用了 js 的面向对象的方式,管理代码,本质上 lax.js 是一个 立即执行函数,对外输出的是 lax 的实例。使用时候需要先调用 init 方法。

安装

<npm_manager> install lax.js

如果使用 typescript 需要声明 lax.js

基本概念

驱动器 Driver

滚动驱动器是用于计算页面元素的滚动效果的组件. 默认情况下,Lax.js 提供了一些预定义的滚动驱动器(如 scrollY、scrollX、scrollTop、scrollBottom、scrollRight 等),但用户可以使用 lax.addDriver 方法添加自己的滚动驱动器来实现更加复杂的滚动效果。

lax.addDriver(
  'scrollY',                          // Driver name
  function(laxFrame) {                     
    return window.scrollY    // Value method
  },
  {
    inertiaEnabled: false
    frameStep: 1
  }                                 // Options
)

滚动元素

lax.js 中,需要添加滚动元素 lax.addElements:

lax.addElements(
  '.selector',  // Element selector rule
  {             // Animation data
    scrollY: {  
      opacity: [
        [0, 100],
        [1, 0]
      ]
    }
  },
  {             
    style: {}   // Element options
  }
)
  • 第一个元素是 css 选择器。
  • 第二个参数是 Lax.js 支持或者自定义的 css 属性对象,通过配置此对象,Lax.js 的滚动动画行为。
  • 第三个参数是 Lax.js 的 options (可选):
    • transform: 给元素添加静态的 CSS 属性
    • elements: 传递对原始 DOM 元素的引用以允许更灵活的选择模式。
    • onUpdate: 一种使用当前 driverValues 和 domElement 调用每一帧的方法。

滚动元素 scrollY 的属性解读

  • opacity: 一个数组表示滚动的位置 [p1, p2, p3, ...]
  • 第二位 表示 opacity 的属性具体的值 [0, 1, 0] 具体的属性值。

支持的 CSS 属性

姓名
不透明度opacity
规模XscaleX
比例YscaleY
规模scale
倾斜XskewX
倾斜YskewY
倾斜skew
旋转XrotateX
旋转YrotateY
旋转rotate
翻转XtranslateX
翻转YtranslateY
翻转ZtranslateZ
模糊blur
色调旋转hue-rotate
亮度brightness

特殊值

可以使用的特殊的值

screenWidth屏幕当前的宽度
screenHeight屏幕当前的高度
pageWidth文档的宽度
pageHeight文档的高度
elWidth元素的宽度
elHeight元素的高度
elInY当元素出现在屏幕底部时的窗口 scrollY 位置
elOutY当元素消失在屏幕顶部时的窗口 scrollY 位置
elCenterY当元素垂直居中于屏幕时的窗口 scrollY 位置
elInX当元素出现在屏幕右侧时的窗口 scrollX 位置
elOutX当元素消失在屏幕左侧时的窗口 scrollX 位置
elCenterX当元素水平居中于屏幕时的窗口 scrollX 位置
index使用 lax.addElements 添加元素时的元素索引

支持的动画

以下是每个缓动函数的解释,使用表格格式:

NameDescription
easeInQuad开始时动画缓慢,然后逐渐加速。
easeOutQuad开始时动画快速,然后逐渐减速。
easeInOutQuad开始时动画缓慢,然后加速,再减速结束。
easeInCubic开始时动画缓慢,然后逐渐加速。
easeOutCubic开始时动画快速,然后逐渐减速。
easeInOutCubic开始时动画缓慢,然后加速,再减速结束。
easeInQuart开始时动画缓慢,然后逐渐加速。
easeOutQuart开始时动画快速,然后逐渐减速
easeInOutQuart开始时动画缓慢,然后加速,再减速结束。
easeInQuint开始时动画缓慢,然后逐渐加速。
easeOutQuint开始时动画快速,然后逐渐减速。
easeInOutQuint开始时动画缓慢,然后加速,再减速结束。
easeOutBounce动画结束时会反弹回来,类似于弹簧的效果。
easeInBounce开始时动画缓慢,然后快速反弹,再逐渐减速到终点。
easeOutBack动画结束时会超过终点一些距离,然后返回终点。
easeInBack开始时动画缓慢,然后超过起点一些距离,然后返回起点。

基本使用

  • 调用 init 方法
  • 添加 Driver 驱动器()
  • 添加元素

React 中使用 lax.js

import { useEffect } from "react";
import lax from "lax.js";
import "~/styles/cursor.css";

export default function HTMLInlineRoute() {
  useEffect(() => {
    lax.init();

    lax.addDriver("scrollY", function () {
      return window.scrollY;
    });

    return () => {
      lax.removeElement();
    };
  }, []);
  return (
    <div className="square lax lax_preset_spin:400:360 lax_preset_flipX"></div>
  );
}

在 Remix 中实现一个简答的滚动效果

import React, { useEffect } from "react";
import lax from "lax.js";

import "~/styles/lax.css";
import { cssBundleHref } from "@remix-run/css-bundle";
import type { LinksFunction } from "@remix-run/node";

export const links: LinksFunction = () => [
  ...(cssBundleHref ? [{ rel: "stylesheet", href: cssBundleHref }] : []),
];


function Example() {
  useEffect(() => {
    lax.init();

    lax.addDriver("scrollY", function () {
      return window.scrollY;
    });

    lax.addElements(
      ".box",
      {
        scrollY: {
        translateX: [[0, "screenHeight/3", "screenHeight"], [-300, 0, 300]],
          opacity: [[0, "screenHeight/3", "screenHeight"], [1, 1, 0]],
          scale: [[100, "screenHeight"], [0.25, 1]],
        },
      }
    );
  }, []);

  return (
    <div className="wrap" style={{
      background: '#000',
      color: '#fff'
    }}>
      <div style={{ width: '100%',  height: '100vh', background: '#ff0'}}></div>
      <div className="box">
        <img
          alt="dd"
          src="/your_icon.png"
        />
        <div>your description </div>
      </div>
    </div>
  );
}

export default Example;

同类库类推荐

  • scrollmagic 基于滚动的动画库,它可以让你在滚动页面时添加各种动画效果。它非常灵活,可以与其他库和框架一起使用。
  • AOS 基于滚动的动画库,它可以让你在滚动页面时添加各种动画效果。它支持各种类型的动画效果,包括渐变、旋转、缩放等。它的 API 简单易用,并且可以与其他库和框架一起使用。
  • skrollr 基于滚动的动画库,它可以帮助你创建各种各样的滚动效果。它支持各种类型的滚动,包括平移、旋转、缩放等。

更多

微信搜索并关注公踪号 进二开物,更多技术 JS/TS/CSS/Rust 文章...