【第1816期】巧用 CSS 实现酷炫的充电动画

【第1816期】巧用 CSS 实现酷炫的充电动画
jiutian99
jiutian99
313
阅读
0
评论
2021年08月05日01:15:21 0 313

关注前言

看着这些就觉得很美妙。今日早读文章由腾讯@chokcoco授权分享。

正文从这开始~~

循序渐进,看看只使用 CSS ,可以鼓捣出什么样的充电动画效果。

画个电池

当然,电池充电,首先得用 CSS 画一个电池,这个不难,随便整一个:

欧了,勉强就是它了。有了电池,那接下来直接充电吧。最最简单的动画,那应该是用色彩把整个电池灌满即可。

方法很多,代码也很简单,直接看效果:

有内味了,如果要求不高,这个勉强也就能够交差了。通过蓝色渐变表示电量,通过色块的位移动画实现充电的动画。但是总感觉少了点什么。

增加阴影及颜色的变化

如果要继续优化的话,需要添加点细节。

我们知道,低电量时,电量通常表示为红色,高电量时表示为绿色。再给整个色块添加点阴影的变化,呼吸的感觉,让充电的效果看起来确实是在动。

知识点

到这里,其实只有一个知识点:

使用 filter: hue-rotate() 对渐变色彩进行色彩过渡变换动画

我们无法对一个渐变色直接进行 animation ,这里通过滤镜对色相进行调整,从而实现了渐变色的变换动画。

完整Demo:https://codepen.io/Chokcoco/pen/bGNqyra?editors=1100

<div

class

=

"container"

>

<div

class

=

"battery"

></div>

</div>

html

,

body 

{

    width

:

100

%;

    height

:

100

%;

    display

:

 flex

;

    background

:

#e4e4e4;

}

.

container 

{

    position

:

 relative

;

    width

:

140px

;

    margin

:

auto

;

}

.

battery 

{

    height

:

220px

;

    box

-

sizing

:

 border

-

box

;

    border

-

radius

:

15px

15px

5px

5px

;

    filter

:

 drop

-

shadow

(

0

1px

3px

 rgba

(

0

,

0

,

0

,

0.22

));

    background

:

#fff;

    z

-

index

:

1

;

&::

before 

{

        content

:

""

;

        position

:

 absolute

;

        width

:

26px

;

        height

:

10px

;

        left

:

50

%;

        top

:

0

;

        transform

:

 translate

(-

50

%,

-

10px

);

        border

-

radius

:

5px

5px

0

0

;

        background

:

 rgba

(

240

,

240

,

240

,

.

88

);

}

&::

after 

{

        content

:

""

;

        position

:

 absolute

;

        left

:

0

;

        right

:

0

;

        bottom

:

0

;

        top

:

90

%;

        background

:

 linear

-

gradient

(

to bottom

,

#7abcff 0%, #00BCD4 44%, #2196F3 100%);

        border

-

radius

:

0px

0px

5px

5px

;

        box

-

shadow

:

0

14px

28px

 rgba

(

33

,

150

,

243

,

0

),

0

10px

10px

 rgba

(

9

,

188

,

215

,

0.08

);

        animation

:

 charging 

6s

 linear infinite

;

        filter

:

 hue

-

rotate

(

90deg

);

}

}

@keyframes

 charging 

{

50

%

{

        box

-

shadow

:

0

14px

28px

 rgba

(

0

,

150

,

136

,

0.83

),

0px

4px

10px

 rgba

(

9

,

188

,

215

,

0.4

);

}

95

%

{

        top

:

5

%;

        filter

:

 hue

-

rotate

(

0deg

);

        border

-

radius

:

0

0

5px

5px

;

        box

-

shadow

:

0

14px

28px

 rgba

(

4

,

188

,

213

,

.

2

),

0

10px

10px

 rgba

(

9

,

188

,

215

,

0.08

);

}

100

%

{

        top

:

0

%;

        filter

:

 hue

-

rotate

(

0deg

);

        border

-

radius

:

15px

15px

5px

5px

;

        box

-

shadow

:

0

14px

28px

 rgba

(

4

,

188

,

213

,

0

),

0

10px

10px

 rgba

(

9

,

188

,

215

,

0.4

);

}

}

添加波浪

ok,刚刚算一个小里程碑,接下来再进一步。电量的顶部为一条直线有点呆呆的感觉,这里我们进行改造一下,如果能将顶部直线,改为波浪滚动,效果会更为逼真一点。

改造之后的效果:

使用 CSS 实现这种波浪滚动效果,其实只是用了一种障眼法,具体的可以我早期写的这篇文章:纯 CSS 实现波浪效果!

知识点

这里的一个知识点就是上述说的使用 CSS 实现简易的波浪效果,通过障眼法实现,看看图就明白了:

完整Demo:https://codepen.io/Chokcoco/pen/qBErGoO

<div

class

=

"container"

>

<div

class

=

"header"

></div>

<div

class

=

"battery"

>

</div>

<div

class

=

"battery-copy"

>

<div

class

=

"g-wave"

></div>

<div

class

=

"g-wave"

></div>

<div

class

=

"g-wave"

></div>

</div>

</div>

html

,

body 

{

    width

:

100

%;

    height

:

100

%;

    display

:

 flex

;

    background

:

#e4e4e4;

}

.

container 

{

    position

:

 relative

;

    width

:

140px

;

    margin

:

auto

;

}

.

header 

{

    position

:

 absolute

;

    width

:

26px

;

    height

:

10px

;

    left

:

50

%;

    top

:

0

;

    transform

:

 translate

(-

50

%,

-

10px

);

    border

-

radius

:

5px

5px

0

0

;

    background

:

 rgba

(

255

,

255

,

255

,

.

88

);

}

.

battery

-

copy 

{

    position

:

 absolute

;

    top

:

0

;

    left

:

0

;

    height

:

220px

;

    width

:

140px

;

    border

-

radius

:

15px

15px

5px

5px

;

    overflow

:

 hidden

;

}

.

battery 

{

    position

:

 relative

;

    height

:

220px

;

    box

-

sizing

:

 border

-

box

;

    border

-

radius

:

15px

15px

5px

5px

;

    box

-

shadow

:

0

0

5px

2px

 rgba

(

255

,

255

,

255

,

0.22

);

    background

:

#fff;

    z

-

index

:

1

;

&::

after 

{

        content

:

""

;

        position

:

 absolute

;

        left

:

0

;

        right

:

0

;

        bottom

:

0

;

        top

:

80

%;

        background

:

 linear

-

gradient

(

to bottom

,

#7abcff 0%, #00BCD4 44%, #2196F3 100%);

        border

-

radius

:

0px

0px

5px

5px

;

        box

-

shadow

:

0

14px

28px

 rgba

(

33

,

150

,

243

,

0

),

0

10px

10px

 rgba

(

9

,

188

,

215

,

0.08

);

        animation

:

 charging 

10s

 linear infinite

;

        filter

:

 hue

-

rotate

(

90deg

);

}

}

.

g

-

wave 

{

    position

:

 absolute

;

    width

:

300px

;

    height

:

300px

;

    background

:

 rgba

(

255

,

255

,

255

,

.

8

);

    border

-

radius

:

45

%

47

%

44

%

42

%;

    bottom

:

25px

;

    left

:

50

%;

    transform

:

 translate

(-

50

%,

0

);

    z

-

index

:

1

;

    animation

:

 move 

10s

 linear infinite

;

}

.

g

-

wave

:

nth

-

child

(

2

)

{

    border

-

radius

:

38

%

46

%

43

%

47

%;

    transform

:

 translate

(-

50

%,

0

)

 rotate

(-

135deg

);

}

.

g

-

wave

:

nth

-

child

(

3

)

{

    border

-

radius

:

42

%

46

%

37

%

40

%;

    transform

:

 translate

(-

50

%,

0

)

 rotate

(

135deg

);

}

@keyframes

 charging 

{

50

%

{

        box

-

shadow

:

0

14px

28px

 rgba

(

0

,

150

,

136

,

0.83

),

0px

4px

10px

 rgba

(

9

,

188

,

215

,

0.4

);

}

95

%

{

        top

:

5

%;

        filter

:

 hue

-

rotate

(

0deg

);

        border

-

radius

:

0

0

5px

5px

;

        box

-

shadow

:

0

14px

28px

 rgba

(

4

,

188

,

213

,

.

2

),

0

10px

10px

 rgba

(

9

,

188

,

215

,

0.08

);

}

100

%

{

        top

:

0

%;

        filter

:

 hue

-

rotate

(

0deg

);

        border

-

radius

:

15px

15px

5px

5px

;

        box

-

shadow

:

0

14px

28px

 rgba

(

4

,

188

,

213

,

0

),

0

10px

10px

 rgba

(

9

,

188

,

215

,

0.4

);

}

}

@keyframes

 move 

{

100

%

{

        transform

:

 translate

(-

50

%,

-

160px

)

 rotate

(

720deg

);

}

}

OK,到这,上述效果加上数字变化已经算是一个比较不错的效果了。当然上面的效果看上去还是很 CSS 的,就是一眼看到就觉得用 CSS 是可以做到的。

使用强大的 CSS 滤镜实现安卓充电动画效果

那下面这个呢?

用安卓手机的同学肯定不陌生,这个是安卓手机在充电的时候的效果。看到这个我就很好奇,使用 CSS 能做到吗?

经过一番尝试,发现使用 CSS 也是可以很好的模拟这种动画效果:

上述 Gif 录制的效果图是完全使用 CSS 模拟的效果。

完整Demo:https://codepen.io/Chokcoco/pen/vYExwvm

<div

class

=

"g-container"

>

<div

class

=

"g-number"

>

98.7%

</div>

<div

class

=

"g-contrast"

>

<div

class

=

"g-circle"

></div>

<ul

class

=

"g-bubbles"

>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

<li></li>

</ul>

</div>

</div>

html

,

body 

{

    width

:

100

%;

    height

:

100

%;

    display

:

 flex

;

    background

:

#000;

    overflow

:

 hidden

;

}

.

g

-

number 

{

    position

:

 absolute

;

    width

:

300px

;

    top

:

27

%;

    text

-

align

:

 center

;

    font

-

size

:

32px

;

    z

-

index

:

10

;

    color

:

#fff;

}

.

g

-

container 

{

    position

:

 relative

;

    width

:

300px

;

    height

:

400px

;

    margin

:

auto

;

}

.

g

-

contrast 

{

    filter

:

 contrast

(

15

)

 hue

-

rotate

(

0

);

    width

:

300px

;

    height

:

400px

;

    background

-

color

:

#000;

    overflow

:

 hidden

;

    animation

:

 hueRotate 

10s

 infinite linear

;

}

.

g

-

circle 

{

    position

:

 relative

;

    width

:

300px

;

    height

:

300px

;

    box

-

sizing

:

 border

-

box

;

    filter

:

 blur

(

8px

);

&::

after 

{

        content

:

""

;

        position

:

 absolute

;

        top

:

40

%;

        left

:

50

%;

        transform

:

 translate

(-

50

%,

-

50

%)

 rotate

(

0

);

        width

:

200px

;

        height

:

200px

;

        background

-

color

:

#00ff6f;

        border

-

radius

:

42

%

38

%

62

%

49

%

/

45

%;

        animation

:

 rotate 

10s

 infinite linear

;

}

&::

before 

{

        content

:

""

;

        position

:

 absolute

;

        width

:

176px

;

        height

:

176px

;

        top

:

40

%;

        left

:

50

%;

        transform

:

 translate

(-

50

%,

-

50

%);

        border

-

radius

:

50

%;

        background

-

color

:

#000;

        z

-

index

:

10

;

}

}

.

g

-

bubbles 

{

    position

:

 absolute

;

    left

:

50

%;

    bottom

:

0

;

    width

:

100px

;

    height

:

40px

;

    transform

:

 translate

(-

50

%,

0

);

    border

-

radius

:

100px

100px

0

0

;

    background

-

color

:

#00ff6f;

    filter

:

 blur

(

5px

);

}

li 

{

    position

:

 absolute

;

    border

-

radius

:

50

%;

    background

:

#00ff6f;

}

@for

 $i 

from

0

 through 

15

{

    li

:

nth

-

child

(#{

$i

})

{

        $width

:

15

+

 random

(

15

)

+

 px

;

        left

:

15

+

 random

(

70

)

+

 px

;

        top

:

50

%;

        transform

:

 translate

(-

50

%,

-

50

%);

        width

:

 $width

;

        height

:

 $width

;

        animation

:

 moveToTop 

#{random(6) + 3}s ease-in-out -#{random(5000)/1000}s infinite;

}

}

@keyframes

 rotate 

{

50

%

{

        border

-

radius

:

45

%

/

42

%

38

%

58

%

49

%;

}

100

%

{

        transform

:

 translate

(-

50

%,

-

50

%)

 rotate

(

720deg

);

}

}

@keyframes

 moveToTop 

{

90

%

{

        opacity

:

1

;

}

100

%

{

        opacity

:

.

1

;

        transform

:

 translate

(-

50

%,

-

180px

);

}

}

@keyframes

 hueRotate 

{

100

%

{

        filter

:

 contrast

(

15

)

 hue

-

rotate

(

360deg

);

}

}

知识点

拆解一下知识点,最主要的其实是用到了 filter: contrast() 以及 filter: blur() 这两个滤镜,可以很好的实现这种融合效果。

单独将两个滤镜拿出来,它们的作用分别是:

filter: blur():给图像设置高斯模糊效果。

filter: contrast():调整图像的对比度。

但是,当他们“合体”的时候,产生了奇妙的融合现象。

先来看一个简单的例子:

仔细看两圆相交的过程,在边与边接触的时候,会产生一种边界融合的效果,通过对比度滤镜把高斯模糊的模糊边缘给干掉,利用高斯模糊实现融合效果。

当然,这种效果在之前的文章也多次提及过,更具体的,可以看看:

【第1568期】CSS 火焰

你所不知道的 CSS 滤镜技巧与细节

颜色的变换

当然,这里也是可以加上颜色的变换,效果也很不错:

html

,

body 

{

    width

:

100

%;

    height

:

100

%;

    display

:

 flex

;

    background

:

#000;

    overflow

:

 hidden

;

}

.

g

-

number 

{

    position

:

 absolute

;

    width

:

300px

;

    top

:

27

%;

    text

-

align

:

 center

;

    font

-

size

:

32px

;

    z

-

index

:

10

;

    color

:

#fff;

}

.

g

-

container 

{

    position

:

 relative

;

    width

:

300px

;

    height

:

400px

;

    margin

:

auto

;

}

.

g

-

contrast 

{

    filter

:

 contrast

(

15

)

 hue

-

rotate

(

0

);

    width

:

300px

;

    height

:

400px

;

    background

-

color

:

#000;

    overflow

:

 hidden

;

    animation

:

 hueRotate 

10s

 infinite linear

;

}

.

g

-

circle 

{

    position

:

 relative

;

    width

:

300px

;

    height

:

300px

;

    box

-

sizing

:

 border

-

box

;

    filter

:

 blur

(

8px

);

&::

after 

{

        content

:

""

;

        position

:

 absolute

;

        top

:

40

%;

        left

:

50

%;

        transform

:

 translate

(-

50

%,

-

50

%)

 rotate

(

0

);

        width

:

200px

;

        height

:

200px

;

        background

-

color

:

#00ff6f;

        border

-

radius

:

42

%

38

%

62

%

49

%

/

45

%;

        animation

:

 rotate 

10s

 infinite linear

;

}

&::

before 

{

        content

:

""

;

        position

:

 absolute

;

        width

:

176px

;

        height

:

176px

;

        top

:

40

%;

        left

:

50

%;

        transform

:

 translate

(-

50

%,

-

50

%);

        border

-

radius

:

50

%;

        background

-

color

:

#000;

        z

-

index

:

10

;

}

}

.

g

-

bubbles 

{

    position

:

 absolute

;

    left

:

50

%;

    bottom

:

0

;

    width

:

100px

;

    height

:

40px

;

    transform

:

 translate

(-

50

%,

0

);

    border

-

radius

:

100px

100px

0

0

;

    background

-

color

:

#00ff6f;

    filter

:

 blur

(

5px

);

}

li 

{

    position

:

 absolute

;

    border

-

radius

:

50

%;

    background

:

#00ff6f;

}

@for

 $i 

from

0

 through 

15

{

    li

:

nth

-

child

(#{

$i

})

{

        $width

:

15

+

 random

(

15

)

+

 px

;

        left

:

15

+

 random

(

70

)

+

 px

;

        top

:

50

%;

        transform

:

 translate

(-

50

%,

-

50

%);

        width

:

 $width

;

        height

:

 $width

;

        animation

:

 moveToTop 

#{random(6) + 3}s ease-in-out -#{random(5000)/1000}s infinite;

}

}

@keyframes

 rotate 

{

50

%

{

        border

-

radius

:

45

%

/

42

%

38

%

58

%

49

%;

}

100

%

{

        transform

:

 translate

(-

50

%,

-

50

%)

 rotate

(

720deg

);

}

}

@keyframes

 moveToTop 

{

90

%

{

        opacity

:

1

;

}

100

%

{

        opacity

:

.

1

;

        transform

:

 translate

(-

50

%,

-

180px

);

}

}

@keyframes

 hueRotate 

{

100

%

{

        filter

:

 contrast

(

15

)

 hue

-

rotate

(

360deg

);

}

}

容易忽视的点

通过调节 filter: blur() 及 filter: contrast() 属性的值,动画效果其实会有很大程度的变化,好的效果需要不断的调试。当然,经验在其中也是发挥了很重要的作用,说到底还是要多尝试。

最后

本文给出的几个充电动画,效果渐进增强,本文只指出了最核心的知识点。但是在实际输出的过程中有很多小细节是本文没有提及的,感兴趣的同学还是应该点进 Demo 好好看看源码或者自己动手实现一遍。


打赏 点赞(0)
weinxin
投诉&咨询
文章名+链接地址,发送到此微信:tourism52
历史上的今天
03月
26
WML,变量,WML,变量,用于,存储,数据,本节,介绍了, 菜鸟教程

WML 变量

WML 变量 变量 WML 变量用于存储数据,本节介绍了 WML 变量的使用。 当用户在卡片组的卡片之间切换时,我们需要在变量中存储数据。WML 变量对大小写敏感。 通过 Setv...
WMLScript,seed,函数,WMLScript,seed,函数,初始化,带, 菜鸟教程

WMLScript seed() 函数

WMLScript seed() 函数 seed() 函数初始化带有一个数字的随机数生成器,并返回一个空字符串。 语法 n = Lang.seed(number) 成分 描述 n ...
JavaScript 概述 菜鸟教程

JavaScript 概述

JavaScript 概述 什么是 JavaScript? JavaScript 是一种基于对象和事件驱动并具有安全性能的脚本语言 。 JavaScript 官方名称是 ECMAS...
javascript,使用,误区 菜鸟教程

JavaScript 使用误区

JavaScript 使用误区本章节我们将讨论 JavaScript 的使用误区。赋值运算符应用错误在 JavaScript 程序中如果你在 if 条件语句中使用赋值运算符的等号 ...
declare 菜鸟教程

declare

declare(PHP 4, PHP 5)declare 结构用来设定一段代码的执行指令。declare 的语法和其它流程控制结构相似: declare (directi...

评论列表 共有 0 条评论

暂无评论