CSS实现吃豆豆动画

「本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!

介绍

在此之前啊,看到一个吃豆豆的游戏。那我们今天就用css3来搞一个吃豆豆的动画啊。

其实实现的方法也很简单。使用CSS3 @keyframes 动画和rotate() 属性进行一个旋转的控制,再加上一个box-shadow属性基本是就差不多了。

效果图

吃豆豆.gif

我们可以看到啊,小圆点一直做从右往左的动作,左边一个圆球又开又闭合,看起来就行往嘴里送东西的样子。

实现步骤

  • 简单写个布局样式
  • 圆球的上下闭合动画
  • 小圆点动画

布局样式

布局

我们这里只需要一个圆球和小圆点组成就够了

<div class="demo">
    <div class="pacman"></div>
    <div class="dot"></div>
</div>
复制代码

圆球样式

接下来搞点样式,这里我们用伪元素来写。注意这里给它加上绝对定位(absolute),因为要做上下闭合的动画,我们先给加上。

body .pacman:before {
      content: '';
      position: absolute;
      background: #fb07ff;
      width: 100px;
      height: 50px;
      /*保持居中位置*/
      left: 50%;
      top: 50%;
      /*保持居中位置*/
      margin-left: -50px;
      margin-top: -50px;
      /*上半圆效果*/
      border-radius: 50px 50px 0 0;
}
复制代码

然后就长这样啊

d1.png
然后给after也加上

body .pacman:before,
body .pacman:after
{
      content: '';
      position: absolute;
      background: #fb07ff;
      width: 100px;
      height: 50px;
      /*保持居中位置*/
      left: 50%;
      top: 50%;
      /*保持居中位置*/
      margin-left: -50px;
      margin-top: -50px;
      /*上半圆效果*/
      border-radius: 50px 50px 0 0;
}
复制代码

d2.png

这里可能又会问怎么长这样,都重叠一起咯。:before和:after都设置了在页面居中的效果,不重叠在一起才奇怪呢!所以啊莫惊慌!

圆点样式

这里喜欢啥颜色就搞啥颜色就完事了,也要加绝对定位

body .dot {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 12px;
    height: 12px;
    margin-top: -5px;
    margin-left: 30px;
    border-radius: 50%;
    background: #02ec2a;
}
复制代码

圆球动画

这里有个注意的小点啊,我们上面不是对圆球的:before和:after都写了相同的样式么,为了方便我们先对其中之一进行操作,等最后效果写完了加上就完事了。这里我们对 :before进行操作

在此之前先搞个上下会动的效果先,用到我们的 @keyframes 动画配合上transform: rotate() 来完成。

@keyframes是什么?

@keyframes:以百分比来规定改变发生的时间,或者通过关键词 “from” 和 “to“,等价于 0% 和 100%。0% 是动画的开始时间,100% 动画的结束时间

注意

  • Internet Explorer 10、Firefox 以及 Opera 支持 @keyframes 规则和 animation 属性。

  • Chrome 和 Safari 需要前缀 -webkit-。

  • Internet Explorer 9,以及更早的版本,不支持 @keyframe 规则或 animation 属性。

上半球动画(up)

所以我们这里做一个适配,然后rotate的旋转角度搞到合适即可。是一个向下咬合的效果。代码如下:

/* up */
@-webkit-keyframes up {

  0%,
  100% {
    transform: rotate(0);
  }

  50% {
    /*咬合张开的角度*/
    transform: rotate(-30deg);
  }
}

@-moz-keyframes up {

  0%,
  100% {
    transform: rotate(0);
  }

  50% {
    transform: rotate(-30deg);
  }
}

@-o-keyframes up {

  0%,
  100% {
    transform: rotate(0);
  }

  50% {
    transform: rotate(-30deg);
  }
}

@keyframes up {

  0%,
  100% {
    transform: rotate(0);
  }

  50% {
    transform: rotate(-30deg);
  }
}
复制代码

接下来给上半圆球加上无限循环的动画

这里是动画是上半球的,所以只需加在:before身上即可

body .pacman:before{
  content: '';
  position: absolute;
  background: #fb07ff;
  width: 100px;
  height: 50px;
  /*保持居中位置*/
  left: 50%;
  top: 50%;
  /*保持居中位置*/
  margin-left: -50px;
  margin-top: -50px;
  /*上半圆效果*/
  border-radius: 50px 50px 0 0;
  
  /**** 添加动画 ****/
  -webkit-animation: up 0.6s infinite;
  /* 0.6s 动画的速度,越大越慢  infinite --- 无限循环 */
  -moz-animation: up 0.6s infinite;
  -o-animation: up 0.6s infinite;
  animation: up 0.6s infinite;
}
复制代码

再看看效果
d4.gif

下半球动画(down)

/* down */
  @-webkit-keyframes down {

    0%,
    100% {
      transform: rotate(0);
    }

    50% {
      transform: rotate(30deg);
    }
  }

  @-moz-keyframes down {

    0%,
    100% {
      transform: rotate(0);
    }

    50% {
      transform: rotate(30deg);
    }
  }

  @-o-keyframes down {

    0%,
    100% {
      transform: rotate(0);
    }

    50% {
      transform: rotate(30deg);
    }
  }

  @keyframes down {

    0%,
    100% {
      transform: rotate(0);
    }

    50% {
      transform: rotate(30deg);
    }
  }
复制代码

加在:after上

body .pacman:after {
      /*下半圆效果*/
    border-radius: 0 0 50px 50px;
    -webkit-animation: down 0.6s infinite;
    -moz-animation: down 0.6s infinite;
    -o-animation: down 0.6s infinite;
    animation: down 0.6s infinite; 
}
复制代码

上下动画都写完了,我们来看看现在的效果先,激动人心的时候到了,上才艺

d3.gif

咿呀我去!这什么玩意啊?怎么跟想象的不一样的。这时候肯定是骂骂咧咧退出群聊,搞这么久就搞成这样啊!你这也不行啊

那我们只需给 :after 加上一个margin-top即可,这才是最终时刻

来人!给我上图!上代码!

body .pacman:after {
  /*为了使两个半圆咬合时不出现缝隙*/
  margin-top: -1px; 
}
复制代码

d5.gif

哎,现在没话说了吧(打不着打不着…),就是玩儿~

接下来搞点正经的,圆点动画,简直不要太简单!

圆点动画

这里是一个从左到右的动画,我们要改变的是margin-left值,改变当前的位置。到了这你就应该明白之前我们为什么要设置绝对定位

/* r-to-l */
  @-webkit-keyframes r-to-l {
    100% {
      margin-left: -1px;
    }
  }

  @-moz-keyframes r-to-l {
    100% {
      margin-left: -1px;
    }
  }

  @-o-keyframes r-to-l {
    100% {
      margin-left: -1px;
    }
  }

  @keyframes r-to-l {
    100% {
      margin-left: -1px;
    }
  }
复制代码

给小圆点加上,效果就出来了

body .dot {
    -webkit-animation: r-to-l 0.6s infinite;
    -moz-animation: r-to-l 0.6s infinite;
    -o-animation: r-to-l 0.6s infinite;
    animation: r-to-l 0.6s infinite;
}
复制代码

d6.gif
我们可以明显的看到小圆点是从右到左的一个动作啊!

哎呀,你这也不像开头那样那么多圆点啊,你这又忽悠我?

上才艺!咋们给它加上box-shadow就完事了啊,然后再加上z-index让小圆点在圆球的下方,这时候再来看看效果的话,就像是无限产生的小圆点。

body .dot {
    /*层级关系 越大越在上层*/
    z-index: -1; 
      
    /*实际上只有一个圆点,用了box-shadow的阴影属性。*/
    box-shadow: 30px 0 0 #02ec2a, 60px 0 0 #02ec2a, 90px 0 0 #02ec2a, 120px 0 0 #02ec2a, 150px 0 0 #02ec2a; 
}
复制代码

不着急,咋先解释一波啊!

box-shadow

  1. box-shadow: offset-x | offset-y | blur-radius | spread-radius | color ()

    (1) <offset-x> <offset-y>: 这是头两个 <length>值,用来设置阴影偏移量。<offset-x> 设置水平偏移量,如果是负值则阴影位于元素左边。 <offset-y> 设置垂直偏移量,如果是负值则阴影位于元素上面。可用单位请查看 <length>。如果两者都是0,那么阴影位于元素后面。这时如果设置了 <blur-radius><spread-radius> 则有模糊效果。

    (2) <blur-radius>: 这是第三个 <length> 值。值越大,模糊面积越大,阴影就越大越淡。 不能为负值。默认为0,此时阴影边缘锐利。

    (3) <spread-radius> : 这是第四个 <length> 值。取正值时,阴影扩大;取负值时,阴影收缩。默认为0,此时阴影与元素同样大。(默认为 0 ,所以这里只设置了前3个值)

    (4) <color> : 相关事项查看 <color> 。如果没有指定,则由浏览器决定——通常是color的值,不过目前Safari取透明。

  2. 这里用的border-style: type(类型)是outset而不是inset(定义 3D outset 边框。其效果取决于 border-color 的值);

效果

d7.gif
到这里,我们的代码编写就全部完成啦!

完整代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>吃豆豆</title>
</head>

<style>
  /* up */
  @-webkit-keyframes up {

    0%,
    100% {
      transform: rotate(0);
    }

    50% {
      transform: rotate(-30deg);
    }
  }

  /*咬合张开的角度*/


  @-moz-keyframes up {

    0%,
    100% {
      transform: rotate(0);
    }

    50% {
      transform: rotate(-30deg);
    }
  }

  @-o-keyframes up {

    0%,
    100% {
      transform: rotate(0);
    }

    50% {
      transform: rotate(-30deg);
    }
  }

  @keyframes up {

    0%,
    100% {
      transform: rotate(0);
    }

    50% {
      transform: rotate(-30deg);
    }
  }

  /* down */
  @-webkit-keyframes down {

    0%,
    100% {
      transform: rotate(0);
    }

    50% {
      transform: rotate(30deg);
    }
  }

  @-moz-keyframes down {

    0%,
    100% {
      transform: rotate(0);
    }

    50% {
      transform: rotate(30deg);
    }
  }

  @-o-keyframes down {

    0%,
    100% {
      transform: rotate(0);
    }

    50% {
      transform: rotate(30deg);
    }
  }

  @keyframes down {

    0%,
    100% {
      transform: rotate(0);
    }

    50% {
      transform: rotate(30deg);
    }
  }

  /* r-to-l */
  @-webkit-keyframes r-to-l {
    100% {
      margin-left: -1px;
    }
  }

  @-moz-keyframes r-to-l {
    100% {
      margin-left: -1px;
    }
  }

  @-o-keyframes r-to-l {
    100% {
      margin-left: -1px;
    }
  }

  @keyframes r-to-l {
    100% {
      margin-left: -1px;
    }
  }

  body {
    background: #d44747;
    overflow: hidden;
    margin: 0;
  }

  body .pacman:before,
  body .pacman:after {
    content: '';
    position: absolute;
    background: #fb07ff;
    width: 100px;
    height: 50px;
    /*保持居中位置*/
    left: 50%;
    top: 50%;
    /*保持居中位置*/
    margin-left: -50px;
    margin-top: -50px;
    /*上半圆效果*/
    border-radius: 50px 50px 0 0;
    /*动画*/
    -webkit-animation: up 0.6s infinite;
    /* 0.6s 动画的速度,越大越慢  infinite --- 无限循环 */
    -moz-animation: up 0.6s infinite;
    -o-animation: up 0.6s infinite;
    animation: up 0.6s infinite;
  }

  body .pacman:after {
    /*为了使两个半圆咬合时不出现缝隙*/
    margin-top: -1px;
    /*下半圆效果*/
    border-radius: 0 0 50px 50px;
    -webkit-animation: down 0.6s infinite;
    -moz-animation: down 0.6s infinite;
    -o-animation: down 0.6s infinite;
    animation: down 0.6s infinite;
  }

  body .dot {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 12px;
    height: 12px;
    margin-top: -5px;
    margin-left: 30px;
    border-radius: 50%;
    background: #02ec2a;
    /*层级关系 越大越在上层*/
    z-index: -1;
    /*实际上只有一个圆点,用了box-shadow的阴影属性。*/
    box-shadow: 30px 0 0 #02ec2a, 60px 0 0 #02ec2a, 90px 0 0 #02ec2a, 120px 0 0 #02ec2a, 150px 0 0 #02ec2a;
    /*
   1、box-shadow: offset-x | offset-y | blur-radius | spread-radius | color ()
    (1)<offset-x> <offset-y>: 这是头两个 <length>值,用来设置阴影偏移量。<offset-x> 设置水平偏移量,如果是负值则阴影位于元素左边。 <offset-y> 设置垂直偏移量,如果是负值则阴影位于元素上面。可用单位请查看 <length>。如果两者都是0,那么阴影位于元素后面。这时如果设置了 <blur-radius> 或 <spread-radius> 则有模糊效果。
    (2)<blur-radius>: 这是第三个 <length> 值。值越大,模糊面积越大,阴影就越大越淡。 不能为负值。默认为0,此时阴影边缘锐利。
    ※(3)<spread-radius> : 这是第四个 <length> 值。取正值时,阴影扩大;取负值时,阴影收缩。默认为0,此时阴影与元素同样大。(默认为 0 ,所以这里只设置了前3个值)
	(4)<color> : 相关事项查看 <color> 。如果没有指定,则由浏览器决定——通常是color的值,不过目前Safari取透明。

   2、这里用的border-style:type(类型)是outset而不是inset(定义 3D outset 边框。其效果取决于 border-color 的值);

  */
    -webkit-animation: r-to-l 0.6s infinite;
    -moz-animation: r-to-l 0.6s infinite;
    -o-animation: r-to-l 0.6s infinite;
    animation: r-to-l 0.6s infinite;
  }
</style>

<body>

  <div class="demo">
    <div class="pacman"></div>
    <div class="dot"></div>
  </div>

</body>

</html>
复制代码

效果图

吃豆豆.gif

结尾

今天就先到这里啦!我们下期再见!码字不易,觉得不错的可以动动小指头点点赞哟~

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享