🌟前端使用Lottie实现炫酷的开关效果🌟

简介: 🌟前端使用Lottie实现炫酷的开关效果🌟

前言

在平时的开发过程中,前端或多或少都会遇到实现动画效果的场景。手写动画是一件相当麻烦的事情,调来调去不仅费时费力,可能还会被产品/UI吐槽:这动画效果也不难呀,为什么就不能实现呢?/为什么就没有还原成我想要的样子呢。

111.png


比如说产品让我们实现这样的一个开关动效

121.png 链接



今天我们就用动画的实现方式——Lottie,来百分百还原设计师的动画效果,并且可以大大提高我们的工作效率(摸鱼时间)。

232.png


Lottie简介

首先我们先来看一下,平时我们实现动画都有哪些方式,它们分别有什么优缺点:

动画类型 优点 缺点
CSS 动画 使用简便,通过@keyframestransition创建动画;浏览器原生支持,性能较好 控制有限,不适用于复杂动画;复杂动画可能需要大量 CSS 代码,冗长
JavaScript 动画 提供更高程度的控制和灵活性;适用于复杂和精细动画效果 引入库增加页面负担,可能需要学习曲线;使用不当容器对页面性能造成影响,产生卡顿
GIF 动画 制作和使用简单,无需额外代码;几乎所有浏览器原生支持 有限颜色深度,不适用于所有场景;清晰度与文件尺寸成正比,无法适应所有分辨率
Lottie 支持矢量动画,保持清晰度和流畅性 ;跨平台使用,适用于 iOS、Android 和 Web 在一些较旧或性能较低的设备上,播放较大的 Lottie 动画可能会导致性能问题;对设计师要求较高

Lottie是由Airbnb开发的一个开源库,用于在移动端和Web上呈现矢量动画。它基于JSON格式的Bodymovin文件,可以将由设计师在AE中创建的动画导出为可在Lottie库中播放的文件。

相对于手写CSS/JS动画而言,它可以大大减少前端开发的工作量,相对于GIF文件来说,它可以在一个合理的文件体积内保证动画的清晰度以及流畅程度。下面我们就介绍一下如何播放一个Lottie动画,并实现一个炫酷的开关效果。

Hello Lottie

假设我们现在已经有一个Lottiejson文件,那么现在安装一些依赖

npm i react-lottie prop-types

安装完之后我们就可以这样子来播放一个Lottie动画:

import animationData from "../../assets/switch-lottie.json";

const LottieSwitch = () => {
  const playing = useRef(false);
  const options = {
    loop: true,
    autoplay: true,
    animationData: animationData,
    rendererSettings: {
      preserveAspectRatio: "xMidYMid slice",
    },
  };
  return (
    <Lottie
      options={options}
      height={20}
      width={40}
    />
  );
};

343.png 链接


来解释一下上面的options参数里面各个字段是什么意思:

  • loop:是否循环播放
  • autoplay:是否自动播放
  • animationDataLottie动画json资源
  • rendererSettings.preserveAspectRatio:指定如何在给定容器中渲染Lottie动画
  • xMidYMid: 表示在水平和垂直方向上都在中心对齐
  • 表示保持纵横比,但可能会裁剪超出容器的部分

正/反向播放

正常的把Lottie动画播放出来之后,我们就可以开始实现一个开关的功能。其实就是点击的时候更换Lottie的播放方向,这里对应的是direction字段,direction1时正向播放,direction-1时反向播放。

我们就要实现下面的功能:

  • 点击时切换方向
  • 播放过程中加锁,禁止切换方向
  • 监听播放结束事件,解锁
  • loop改为falseautoplay改为false

实现代码如下:

const LottieSwitch = () => {
  const [direction, setDirection] = useState(null);
  const playing = useRef(false);
  const options = {
    loop: false,
    autoplay: false,
    animationData: animationData,
    rendererSettings: {
      preserveAspectRatio: "xMidYMid slice",
    },
  };

  const handleClick = () => {
    if (playing.current) {
      return;
    }
    playing.current = true;
    setDirection((prevState) => (prevState === 1 ? -1 : 1));
  };
  return (
    <div style={{ padding: 40 }}>
      <div onClick={handleClick} className={styles.lottieWrapper}>
        <Lottie
          direction={direction}
          options={options}
          speed={2}
          height={20}
          width={40}
          eventListeners={[
            {
              eventName: "complete",
              callback: () => {
                playing.current = false;
              },
            },
          ]}
        />
      </div>
    </div>
  );
};

这样我们就是实现了一个开关的效果 343.png 链接


持续时长

Lottiejson中,有几个关键的字段跟动画的播放时长有关系:

  • fr:帧率,每一秒的帧数
  • ip:开始帧
  • op:结束帧

假如说有下面的一个描述:

{
  "fr": 30,
  "ip": 0,
  "op": 60,
}

则表示帧率是30帧,从第0帧开始,60帧结束,那这个动画的持续时长是 (op-ip)/fr,为2s。那如果我们希望整个动画的播放时长是500ms,则只需要把Lottie的倍速调整为4。对应的就是speed字段:

<Lottie
  direction={direction}
  options={options}
  speed={4}
  height={20}
  width={40}
  eventListeners={[
    {
      eventName: "complete",
      callback: () => {
        playing.current = false;
      },
    },
  ]}
/>

313.png 链接

修改Lottie

Lottie json中,描述整个动画的过程以及效果其实对应的就是某个值。在实现的过程中,其实开发是可以去修改这些值的。比如说我们可以修改上面开关的边框颜色以及小球的颜色。

首先在页面中找到小球对应的颜色是rgb(99, 102, 241)

141.png




Lottie JSON文件中,颜色信息通常出现在表示图层样式的字段中。常见的字段是 "c"(color)"c" 字段表示颜色,通常以RGBA格式(红绿蓝透明度)存储。例如:

"c": {"a":0,"k":[1,0,0,1]}

这表示红色,RGBA值为 [1, 0, 0, 1]

rgb(99, 102, 241)转成上面的写法那就是"c": {"a":0,"k":[99/255,102/255,241/255,1]}。以99/255为例,结果是0.38823529411764707,那么就拿这个结果去json文件中找到对应的节点。

454.png


对应有2个结果,就是小球的颜色以及边框的颜色。当我们找到这个值的时候,如果我们想修改这个值,就必须知道这个值的路径,在一个Lottie中,想肉眼找到这个值的路径是一件很难的事情。所以我们写一个辅助函数:

const updateJsonValue = (json, targetValue, newValue) => {
  const find = (json, targetValue, currentPath = []) => {
    for (const key in json) {
      if (json[key] === targetValue) {
        return [...currentPath, key];
      } else if (typeof json[key] === "object" && json[key] !== null) {
        const path = find(json[key], targetValue, [...currentPath, key]);
        if (path) {
          return path;
        }
      }
    }
  };
  const res = JSON.parse(JSON.stringify(json));
  const path = find(res, targetValue);
  let current = res;

  for (let i = 0; i < path.length - 1; i++) {
    const key = path[i];
    current = current[key];
  }

  const lastKey = path[path.length - 1];
  current[lastKey] = newValue;

  return json;
};

上面的辅助函数就帮助我们找到这个值的路径,并修改目标值。比如说我们想把目前的颜色改成绿色(rgb(25, 195, 125)),就可以找到对应的路径,并修改。别忘了替换的时候把rgb对应的值除以255

let newAnimationData = updateJsonValue(animationData, 0.388235300779, 0.09803921568627451)
newAnimationData = updateJsonValue(newAnimationData, 0.388235300779, 0.09803921568627451)
newAnimationData = updateJsonValue(newAnimationData, 0.40000000596, 0.7647058823529411)
newAnimationData = updateJsonValue(newAnimationData, 0.40000000596, 0.7647058823529411)
newAnimationData = updateJsonValue(newAnimationData, 0.945098042488, 0.49019607843137253)
newAnimationData = updateJsonValue(newAnimationData, 0.945098042488, 0.49019607843137253)

4343.png


掌握了这种方式之后,我们就能修改Lottie里面的大部分内容,包括文案、资源图片、颜色等等。

最后

以上就是一些Lottie的使用以及修改的介绍,下次再遇到比较麻烦的动画需求。就可以跟产品说:可以做,让UI给我导出一个Lottie

555.png

如果你有一些别的想法,欢迎评论区交流~如果你觉得有意思的话,点点关注点点赞吧~

目录
打赏
0
0
0
0
26
分享
相关文章
前端学习笔记202303学习笔记第五天-状态列渲染为switch开关
前端学习笔记202303学习笔记第五天-状态列渲染为switch开关
73 0
前端 - Lottie 中渐变填充的实现研究(一)
前端 - Lottie 中渐变填充的实现研究(一)
302 0
前端 - Lottie 中渐变填充的实现研究(一)
前端 - Lottie 中渐变填充的实现研究(二)
前端 - Lottie 中渐变填充的实现研究(二)
160 0
前端 - Lottie 中渐变填充的实现研究(二)
前端 - Lottie 实现 AE 动效(Bodymovin)(四)
前端 - Lottie 实现 AE 动效(Bodymovin)(四)
481 0
前端 - Lottie 实现 AE 动效(Bodymovin)(四)
前端 - Lottie 实现 AE 动效(Bodymovin)(三)
前端 - Lottie 实现 AE 动效(Bodymovin)(三)
521 0
前端 - Lottie 实现 AE 动效(Bodymovin)(三)
前端 - Lottie 实现 AE 动效(Bodymovin)(二)
前端 - Lottie 实现 AE 动效(Bodymovin)(二)
253 0
前端 - Lottie 实现 AE 动效(Bodymovin)(二)
前端 - Lottie 实现 AE 动效(Bodymovin)(一)
前端 - Lottie 实现 AE 动效(Bodymovin)(一)
538 0
前端 - Lottie 实现 AE 动效(Bodymovin)(一)
前端工作总结141-根据后台传值动态显示开关状态及文字说明(0为文字,1为图标)
前端工作总结141-根据后台传值动态显示开关状态及文字说明(0为文字,1为图标)
170 0
前端大模型应用笔记(三):Vue3+Antdv+transformers+本地模型实现浏览器端侧增强搜索
本文介绍了一个纯前端实现的增强列表搜索应用,通过使用Transformer模型,实现了更智能的搜索功能,如使用“番茄”可以搜索到“西红柿”。项目基于Vue3和Ant Design Vue,使用了Xenova的bge-base-zh-v1.5模型。文章详细介绍了从环境搭建、数据准备到具体实现的全过程,并展示了实际效果和待改进点。
316 14

热门文章

最新文章

  • 1
    【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    14
  • 2
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    38
  • 3
    【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
    2
  • 4
    详解智能编码在前端研发的创新应用
    15
  • 5
    巧用通义灵码,提升前端研发效率
    26
  • 6
    智能编码在前端研发的创新应用
    39
  • 7
    【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
    22
  • 8
    【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
    8
  • 9
    抛弃node和vscode,如何用记事本开发出一个完整的vue前端项目
    3
  • 10
    大前端之前端开发接口测试工具postman的使用方法-简单get接口请求测试的使用方法-简单教学一看就会-以实际例子来说明-优雅草卓伊凡
    27
  • 1
    以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
    29
  • 2
    大前端之前端开发接口测试工具postman的使用方法-简单get接口请求测试的使用方法-简单教学一看就会-以实际例子来说明-优雅草卓伊凡
    51
  • 3
    【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
    26
  • 4
    巧用通义灵码,提升前端研发效率
    93
  • 5
    【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    142
  • 6
    详解智能编码在前端研发的创新应用
    96
  • 7
    智能编码在前端研发的创新应用
    83
  • 8
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    37
  • 9
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    121
  • 10
    【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
    75