一篇文章教你如何用CSS+JS实现按钮状态的动态切换

1,299 阅读3分钟

我正在参加「码上掘金挑战赛」详情请看:码上掘金挑战赛来了!

前言

这篇文章讲述如何实现按钮状态的动画切换,借助了第三方库GSAP来实现动画过度效果的控制

可以通过码上掘金查看实时效果

API

需要用到的CSS原生API做简单的介绍

calc

calc() 此 CSS 函数允许在声明 CSS 属性值时执行一些计算。它可以用在如下场合:<length><frequency><angle><time><percentage><number>、或 <integer>

使用 CSS 自定义属性(变量)

自定义属性(有时候也被称作CSS 变量或者级联变量)是由 CSS 作者定义的,它包含的值可以在整个文档中重复使用。由自定义属性标记设定值(比如: --main-color: black; ),由 var() 函数来获取值(比如: color: var(--main-color);

这篇文章在全局root定义了属性

    :root {
      --color-background-off: #4e4e4e;
      --color-off: #494949;
      --shadow-off: 0 1.2rem 1.5rem #4d4d4d;

      --color-background-on: #2f86d5;
      --color-on: #1ab1fd;
      --shadow-on: 0 1.2rem 1.5rem #2c82cc;

      font-size: 62.5%;
    }

transform

CSS transform 属性允许你旋转,缩放,倾斜或平移给定元素。这是通过修改 CSS 视觉格式化模型的坐标空间来实现的。

实现逻辑

本文对关键的逻辑点进行梳理,样式部分相信屏幕前的大帅哥肯定洒洒水的

飞机的颜色变化

通过动画可以看到飞机颜色由灰色变色蓝色,且左右有移动的效果

初始化,在没有执行动画的时候,我们实现定义了一个蓝色的飞机dom,移动了100%

    .airplane.-on {
      transform: translateY(-50%);
      right: 100%;
    }

image.png

如我们要把.airplane.-on移动到前面的宽度为飞机的一半加按钮的一半

image.png

const airplanes = switchContainer.querySelectorAll(".airplane");
const airplanesFinalX =
switchButton.clientWidth / 2 + airplanes[0].clientWidth / 2;
const airplanesX = isOn ? airplanesInitialX : airplanesFinalX;
gsap.to(airplanes, duration, {
  x: airplanesX,
  ease,
});

通过上面几行代码就实现的蓝色的飞机向前移动到对应的位置,因为两个飞机用了同一个airplane,所以这个时候灰色的飞机也会向前移动同样的距离,这样就实现飞机的颜色切换

白色按钮的移动逻辑如下,获取对应的dom,改变x的位置

const switchButton = switchContainer.querySelector(".switch__button");
const switchButtonFinalX =
  switchContainer.clientWidth - switchButton.clientWidth;
const switchButtonX = isOn ? 0 : switchButtonFinalX;
gsap.to(switchButton, duration, {
  x: switchButtonX,
       ease,
});

body背景的切换

通过gsap的api可以非常简单的实现body背景颜色的过渡动画,一句代码就可以实现

如果我们通过css就需要transition,然后再添加对应class,由此可见节省了很多代码逻辑的实现

gsap.to(document.body, duration, { background, ease });

跑道和蓝天的切换

gsap.timeline是原来控制时间排序,将动画作为一个整体控制,repeats设置为-1代表无限循环动画

      const animateClouds = (() => {
        const cloudFinalX = -cloudLine.children[0].clientWidth;
        const cloudTimeline = gsap.timeline({ repeat: -1 });
        cloudTimeline.to(cloudLine, 4, {
          x: cloudFinalX,
          duration: 2,
          ease: "none",
        });
      })();

这是个立即执行函数,js加载的时候就执行了,所以没有执行切换动画,蓝天的运动也是在进行,那为什么我们看不见呢,是因为父节点sky的初始的opacity为0

    .sky {
      width: 100%;
      height: 100%;
      position: absolute;
      left: 0;
      top: 0;
      border-radius: inherit;
      background: #78c7fe;
      opacity: 0;
      z-index: 2;
      overflow: hidden;
    }

我们执行切换动画的时候将透明度改为1

opacity = isOn ? 0 : 1;
gsap.to(sky, duration, {
  opacity,
  ease,
  onComplete() {
  isAnimating = false;
  },
});

总结

这篇文章简单介绍了GSAP + CSS实现简单的动画切换效果,不用通过CSS的大量属性变化来实现动画的过渡效果,只需要用GSAP提供的简单的api就可以实现非常好看的动画效果,后面我会用GASP实现更加复杂的动画效果