您的位置:时时app平台注册网站 > web前端 > 一个栗子上手 CSS3 动画彩世界网址

一个栗子上手 CSS3 动画彩世界网址

2019-10-12 18:46

CSS技艺:逐帧动画抖动实施方案

2017/08/16 · CSS · 动画

初藳出处: 坑坑洼洼实验室   

作者所在的前端共青团和少先队重要从事移动端的H5页面开辟,而团队应用的适配方案是: viewport units rem。具体能够敬仰凹凸实验室的篇章 – 动用视口单位达成适配布局 。

小编前段时间(2017.08.12)接触到的运动端适配方案中,「利用视口单位落到实处适配布局」是最棒的方案。但是使用 rem 作为单位会遭遇以下多少个难点:

  • 微观尺寸(20px左右)定位不准
  • 逐帧动画轻便有震动

率先个难题的常见出以后 icon 绘制进度,可以使用图片或者 svg-icon 消除那几个难题,作者刚烈建议使用 svg-icon,具体理由能够参见:「拥抱Web设计新取向:SVG 七喜s实行应用」。

第1个难点笔者举个例证来分析抖动的缘由和查找实施方案。

打赏扶持本人写出越多好文章,感谢!

任选一种支付情势

彩世界网址 1 彩世界网址 2

1 赞 7 收藏 2 评论

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文书档案</title>
<style>
@keyframes warn {
0% {
transform: scale(0);
opacity: 0.0;
}
25% {
transform: scale(0);
opacity: 0.1;
}
50% {
transform: scale(0.1);
opacity: 0.3;
}
75% {
transform: scale(0.5);
opacity: 0.5;
}
100% {
transform: scale(1);
opacity: 0.0;
}
}
.container {
position: relative;
border: 1px solid #000;
background: #f55e55;
}
.part {
position: relative;
margin: 200px auto;
width: 90px;
height: 90px;
background: #f55e55;
}
/* 爆发动画(向外扩散变大)的圆圈 */
.pulse-max {
position: absolute;
width: 90px;
height: 90px;
background: #fff;
border-radius: 50%;
z-index: 1;
opacity: 0;
-webkit-animation: warn 2s ease-out;
-moz-animation: warn 2s ease-out;
animation: warn 2s ease-out;
animation-delay: 0.2s;
-webkit-animation-iteration-count: infinite;
-moz-animation-iteration-count: infinite;
animation-iteration-count: infinite;
}
.pulse-mid {
position: absolute;
left: 4px;
top: 4px;
width: 82px;
height: 82px;
background: #ff5e39;
border-radius: 50%;
z-index: 1;
opacity: 0;
-webkit-animation: warn 1.8s ease-out;
-moz-animation: warn 1.8s ease-out;
animation: warn 1.8s ease-out;
-webkit-animation-iteration-count: infinite;
-moz-animation-iteration-count: infinite;
animation-iteration-count: infinite;
}
.pulse-min {
position: absolute;
left: 7px;
top: 7px;
width: 76px;
height: 76px;
background: #fff;
border-radius: 50%;
z-index: 1;
opacity: 0;
-webkit-animation: warn 2s ease-out;
-moz-animation: warn 2s ease-out;
animation: warn 2s ease-out;

二个共振的事例

做叁个8帧的逐帧动画,每帧的尺码为:360×540。

JavaScript

.steps_anim { position: absolute; width: 9rem; height: 13.5rem; background: url(//misc.aotu.io/leeenx/sprite/m.png) 0 0 no-repeat; background-size: 45rem 13.5rem; top: 50%; left: 50%; margin: -5.625rem 0 0 -5.625rem; animation: step 1.2s steps(5) infinite; } @keyframes step { 100% { background-position: -45rem; } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.steps_anim {
  position: absolute;
  width: 9rem;
  height: 13.5rem;
  background: url(//misc.aotu.io/leeenx/sprite/m.png) 0 0 no-repeat;
  background-size: 45rem 13.5rem;
  top: 50%;
  left: 50%;
  margin: -5.625rem 0 0 -5.625rem;
  animation: step 1.2s steps(5) infinite;
}
@keyframes step {
  100% {
    background-position: -45rem;
  }
}

观测在主流(手提式有线话机)分辨率下的播放意况:

iPhone 6
(375×667)
iPhone 6
(414×736)
iPhone 5
(320×568)
Android
(360×640)

种种分辨率下,能够见见除了 ip6 别的的三种分辨率都发出了震动。ip6 不抖动的来头是适配方案是宗旨于 ip6 的分辨率订制的。)

关于作者:陈被单

彩世界网址 3

热爱前端,招待沟通 个人主页 · 笔者的稿子 · 19 ·   

彩世界网址 4

</style>

杀鸡取蛋构想一

小编依照「盈亏一致」设计了「化解构想一」:

彩世界网址 5

基于上海体育地方,其实很轻便就联想到二个粗略的方案:不用七喜图(即一帧对应一张图纸)
以此方案确实是能够缓慢解决抖难点,然而作者并不引入应用它,因为它有七个负面包车型客车事物:

  • KB变大与恳求数扩充
  • 多余的 animation 代码

那一个方案很轻巧,这里就不赘述了。

一个尖栗上手 CSS3 动画

2017/05/10 · CSS · 2 评论 · CSS3, 动画

正文作者: 伯乐在线 - 陈被单 。未经小编许可,禁止转发!
接待参加伯乐在线 专栏撰稿人。

这两日混乱的业务相当多,非常多知识都没赶趟计算,是时候总括计算,开启新的篇章~

本篇小说不一一列举CSS3卡通的品质,若须要明白API,可前往MDN 。

在上马栗子前,大家先补补基础知识。

css3动画分类:

  • 补间动画 – 具备连贯性的动画片
  • 逐帧动画 – 使用steps过渡形式贯彻跳跃

animation常用属性及形貌:

animation: name duration timing-function delay iteration-count direction;

1
animation: name duration timing-function delay iteration-count direction;

1. timing-function属性:  

  • ease 规定慢速最初,然后变快,然后慢速甘休的对接效果。
  • ease-in 规定以慢速开端的联网效果。
  • ease-out 规定以慢速停止的连片效果。
  • ease-in-out 规定以慢速开头和完工的衔接效果。
  • linear 动画原原本本的速度是同等的。
  • cubic-bezier(n,n,n,n) 在cubic-bezier函数中友好的值,n取值为0~1
  • steps()

2. delay属性:用于将动画与其余卡通的执行机缘错开,将动画片落到不一样的时间点。这一个个性很好用~

动画原则:

  1. 运动平时有个惯性,所以要先快后有三个慢一点的反弹。
  2. 背景若采纳多少个少于熠熠闪闪,错位闪烁

配合JS使用

slide.addEventListener("webkitAnimationEnd", function() { console.log('eeee') //动画甘休再调用 });

1
2
3
slide.addEventListener("webkitAnimationEnd", function() {
   console.log('eeee') //动画结束再调用
});

稍许景况我们需求保险动画截至后再扩充别的一些相互,可选择该事件监听。


实战练习:

万一我们须要达成二个那样不难的动画片:

彩世界网址 6

精心观望地点的卡通片,大家发掘,它能够由以下3局地组成:

  1. 登场动画——从右往左移动

  2. 左右循环移动

  3. 逐帧动画

兑现格局:

使用3个dom元素,最外层dom实现进场动画,第二层dom完成左右平移,第三层dom达成逐帧动画。

优点:调节和测量试验方便,节省时间。

缺点:dom多。

1. dom结构

<div class="anima_entrance"> <div class="anima_move"> <div class="anima_sprite"></div> </div> </div>

1
2
3
4
5
<div class="anima_entrance">
    <div class="anima_move">
        <div class="anima_sprite"></div>
    </div>
</div>

2. 分析动画产生的光阴轴:

彩世界网址 7

上场动画持续0.6s,只播放三次,左右移动乃至逐帧动画持续2s,循环播放,代码如下:

.anima_entrance { animation: anima_entrance .6s ease-in-out both; } .anima_move { animation: anima_move 2s linear .6s infinite both; } .anima_sprite { animation: anima_sprite 2s step-end .6s infinite both; }

1
2
3
4
5
6
7
8
9
10
11
.anima_entrance {
    animation: anima_entrance .6s ease-in-out both;
}
 
.anima_move {
    animation: anima_move 2s linear .6s infinite both;
}
 
.anima_sprite {
    animation: anima_sprite 2s step-end .6s infinite both;
}

3. 选用steps()达成逐帧动画:

动用下边那张Pepsi-Cola图,通过更改background-position完毕动画切换。

彩世界网址 8

蹬蹬蹬,效果如上面所示,是否很失望

彩世界网址 9

缘由:由于animation暗中认可以ease格局接入,它会在各类关键帧之间插入补间动画,所以动画效果是连贯性的。此时得以选取steps()撤销补间动画。

贴三个图:

彩世界网址 10

  • steps(1,start): 动画一从头就跳到 百分之百直到这一帧(不是漫天周期)结束   == step-start
  • steps(1,end): 保持 0% 的体裁直到这一帧(不是全数周期)结束   == step-end

随之,大家将timing-function改成 step-end,效果如下:

animation: sprite 2s step-end .6s infinite both;

1
animation: sprite 2s step-end .6s infinite both;

彩世界网址 11

出现想要的功用了哈~不错。

一体化的css代码如下:

.anima_entrance { position: absolute; z-index: 3; top: 5.1rem; left: 4.05rem; width: 12.9rem; height: 19.1rem; -webkit-animation: anima_entrance .6s ease-in-out both; animation: anima_entrance .6s ease-in-out both; } .anima_move { width: 218px; height: 382px; position: absolute; z-index: 1; top: 0; left: 42px; -webkit-animation: anima_move 2s linear .6s infinite both; animation: anima_move 2s linear .6s infinite both; } .anima_sprite { width: 218px; height: 382px; background: url(demo.png) no-repeat 0 0; background-size: 25.8rem 19.1rem; -webkit-animation: anima_sprite 2s step-end .6s infinite both; animation: anima_sprite 2s step-end .6s infinite both; } @keyframes anima_entrance { 0% { -webkit-transform: translate3d(18.75rem, 0, 0); transform: translate3d(18.75rem, 0, 0); } 100% { -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } } @keyframes anima_move { 0%, 16%, 42%, 74%, 100% { -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } 29% { -webkit-transform: translate3d(-1rem, 0, 0); transform: translate3d(-1rem, 0, 0); } 87% { -webkit-transform: translate3d(1rem, 0, 0); transform: translate3d(1rem, 0, 0); } } @keyframes anima_sprite { 0%, 16%, 42%, 58%, 74%, 100% { background-position: -12.9rem 0; } 8%, 50%, 66% { background-position: 0 0; } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
.anima_entrance {
    position: absolute;
    z-index: 3;
    top: 5.1rem;
    left: 4.05rem;
    width: 12.9rem;
    height: 19.1rem;
    -webkit-animation: anima_entrance .6s ease-in-out both;
    animation: anima_entrance .6s ease-in-out both;
}
 
.anima_move {
    width: 218px;
    height: 382px;
    position: absolute;
    z-index: 1;
    top: 0;
    left: 42px;
    -webkit-animation: anima_move 2s linear .6s infinite both;
    animation: anima_move 2s linear .6s infinite both;
}
 
.anima_sprite {
    width: 218px;
    height: 382px;
    background: url(demo.png) no-repeat 0 0;
    background-size: 25.8rem 19.1rem;
    -webkit-animation: anima_sprite 2s step-end .6s infinite both;
    animation: anima_sprite 2s step-end .6s infinite both;
}
 
@keyframes anima_entrance {
    0% {
        -webkit-transform: translate3d(18.75rem, 0, 0);
        transform: translate3d(18.75rem, 0, 0);
    }
    100% {
        -webkit-transform: translate3d(0, 0, 0);
        transform: translate3d(0, 0, 0);
    }
}
 
@keyframes anima_move {
    0%, 16%, 42%, 74%, 100% {
        -webkit-transform: translate3d(0, 0, 0);
        transform: translate3d(0, 0, 0);
    }
    29% {
        -webkit-transform: translate3d(-1rem, 0, 0);
        transform: translate3d(-1rem, 0, 0);
    }
    87% {
        -webkit-transform: translate3d(1rem, 0, 0);
        transform: translate3d(1rem, 0, 0);
    }
}
 
@keyframes anima_sprite {
    0%, 16%, 42%, 58%, 74%, 100% {
        background-position: -12.9rem 0;
    }
    8%, 50%, 66% {
        background-position: 0 0;
    }
}

打赏支持本身写出更加多好小说,多谢!

打赏作者

思路同偶然间改换光滑度和圆形的轻重,Infiniti循环

总结

谢谢阅读完本小说的读者。本文是作者的个人观点,希望能帮忙到有相关难题的心上人,假诺本文有不妥之处请不吝指教。


-webkit-animation-iteration-count: infinite;
-moz-animation-iteration-count: infinite;
animation-iteration-count: infinite;
}
.dot {
position: absolute;
left: 20px;
top: 20px;
width: 50px;
height: 50px;
line-height: 50px;
color: #ff5e39;
border-radius: 50%;
background: #fff;
z-index: 999;
text-align: center;
}

方案C的改良

兑现方案C很好地消除了方案A和方案B的短处,可是方案C也可以有它的主题素材:不便利自动化学工业具去管理图片

自动化工具平时是怎么管理图片的?
自动化工具平日是扫描 CSS 文件寻找富有的 url(...) 语句,然后再管理这几个话语指向的图片文件。

如果 可以改用 CSS 的 `background-image` 就可以解决这个问题,不过 `SVG` 不支持 CSS 的 `background-image`。但是,`SVG`有一个扩展标签:`foreignObject`,它允许向 插入 html 代码。在运用它前,先看一下它的相配情况:

彩世界网址 12

iOS 与 Android 4.3 一片深草绿包容情形终于不错,小编实机测验Tencent X5 内核的浏览器包容照旧能够。以下是立异后的方案。

html:

JavaScript

<svg viewBox="0, 0, 360, 540" class="steps_anim"> <foreignObject class="html" width="360" height="540"> <div class="img"></div> </foreignObject> </svg>

1
2
3
4
5
<svg viewBox="0, 0, 360, 540" class="steps_anim">
  <foreignObject class="html" width="360" height="540">
    <div class="img"></div>
  </foreignObject>
</svg>

css:

JavaScript

.steps_anim { position: absolute; width: 9rem; height: 13.5rem; top: 50%; left: 50%; margin: -5.625rem 0 0 -5.625rem; } .html { width: 360px; height: 540px; } .img { width: 1800px; height: 540px; background: url(//misc.aotu.io/leeenx/sprite/m.png) 0 0 no-repeat; background-size: 1800px 540px; animation: step 1.2s steps(5) infinite; } @keyframes step { 100% { background-position: -1800px 0; } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.steps_anim {
  position: absolute;
  width: 9rem;
  height: 13.5rem;
  top: 50%;
  left: 50%;
  margin: -5.625rem 0 0 -5.625rem;
}
.html {
width: 360px;
height: 540px;
}
.img {
width: 1800px;
height: 540px;
background: url(//misc.aotu.io/leeenx/sprite/m.png) 0 0 no-repeat;
background-size: 1800px 540px;
animation: step 1.2s steps(5) infinite;
}
@keyframes step {
  100% {
    background-position: -1800px 0;
  }
}

改正后的方案DEMO:

</head>

施工方案

「盈利和亏空互补」也足以说是「盈利和蚀本分裂」,假设尺寸在缩放后「盈利和亏折一致」那么抖动现象得以化解。

<div class="part">
<div class="pulse-max"></div>
<div class="pulse-mid"></div>
<div class="pulse-min"></div>
<div class="dot">额头</div>
</div>
</div>
</body>
</html>

深入分析抖动

图像由终端(荧屏)突显,而终端则是三个个光点(物理像素)组成的矩阵,换句话说图片也一组光点矩阵。为了便利描述,作者假如终端上的一个光点代表css中的1px。

以下是一张 9px * 3px 的sprite:

彩世界网址 13

每帧的尺码为 3px * 3px,逐帧的取位进程如下:
彩世界网址 14

把 sprite 的 background-size 的宽度取50%,那么极端会怎么管理?
9 / 2 = 4.5
终点的光点都以以自然数的款型出现的,这里供给做取整管理。取整平常是三种方法:round/ceil/floor。假设是 round ,那么 background-size: 5px,sprite 会是以下三种的一个:

情况一 情况二 情况三

理论上,5 / 3 = 1.666...。但实则光点取整后,多个帧的宽窄都不容许非常 1.666...,而是有贰个帧的大幅度降级为 1px(亏),其他五个升幅升级为 2px(盈),作者把这些现象叫做「盈利和耗损互补」。

再看一下盈利和亏损互补后,逐帧的取位进度:

情况一 情况二 情况三

能够看来由于盈利和亏蚀互补导致了四个帧的上升的幅度不雷同,亏的那一帧在动画中的表示便是抖动

作者总括抖动的由来是:sprite在尺寸缩放后,帧与帧之间的盈利和赔本互补现象导致动画抖动

附注:1px 由多少个光点表示是由以终端的 dpr 决定

<body>
<div class="container">

竭泽而渔构想二

把逐帧取位与图像缩放拆分成五个独立的经过,正是作者的「化解构想二」:
彩世界网址 15

达成「构想二」,我首先想到的是选拔 transform: scale(),于是整理了二个落到实处方案A:

.steps_anim { position: absolute; width: 360px; height: 540px; background: url(//misc.aotu.io/leeenx/sprite/m.png) 0 0 no-repeat; background-size: 1800px 540px; top: 50%; left: 50%; transform-origin: left top; margin: -5.625rem 0 0 -5.625rem; transform: scale(.5); animation: step 1.2s steps(5) infinite; } @keyframes step { 100% { background-position: -1800px; } } /* 写断点 */ @media screen and (width: 320px) { .steps_anim { transform: scale(0.4266666667); } } @media screen and (width: 360px) { .steps_anim { transform: scale(0.48); } } @media screen and (width: 414px) { .steps_anim { transform: scale(0.552); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
.steps_anim {
  position: absolute;
  width: 360px;
  height: 540px;
  background: url(//misc.aotu.io/leeenx/sprite/m.png) 0 0 no-repeat;
  background-size: 1800px 540px;
  top: 50%;
  left: 50%;
  transform-origin: left top;
  margin: -5.625rem 0 0 -5.625rem;
  transform: scale(.5);
  animation: step 1.2s steps(5) infinite;
}
@keyframes step {
  100% {
    background-position: -1800px;
  }
}
/* 写断点 */
@media screen and (width: 320px) {
.steps_anim {
transform: scale(0.4266666667);
}
}
@media screen and (width: 360px) {
.steps_anim {
transform: scale(0.48);
}
}
@media screen and (width: 414px) {
.steps_anim {
transform: scale(0.552);
}
}

其一达成方案A存在显明的老毛病:scale 的值供给写过多断点代码。于是小编结全一段 js 代码来改善这么些完成方案B:

css:

.steps_anim { position: absolute; width: 360px; height: 540px; background: url("//misc.aotu.io/leeenx/sprite/m.png") 0 0 no-repeat; background-size: 1800 540px; top: 50%; left: 50%; transform-origin: left top; margin: -5.625rem 0 0 -5.625rem; animation: step 1.2s steps(5) infinite; } @keyframes step { 100% { background-position: -1800px; } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.steps_anim {
  position: absolute;
  width: 360px;
  height: 540px;
  background: url("//misc.aotu.io/leeenx/sprite/m.png") 0 0 no-repeat;
  background-size: 1800 540px;
  top: 50%;
  left: 50%;
  transform-origin: left top;
  margin: -5.625rem 0 0 -5.625rem;
  animation: step 1.2s steps(5) infinite;
}
@keyframes step {
  100% {
    background-position: -1800px;
  }
}

javascript:

// 以下代码放到<head></head>中// <![CDATA[ document.write(" .steps_anim {scale(.5); } "); function doResize() { scaleStyleSheet.innerHTML = ".steps_anim {-webkit-transform: scale(" (document.documentElement.clientWidth / 750) ")}"; } window.onresize = doResize; doResize(); // ]]>

1
2
3
4
5
6
7
8
9
10
11
12
13
// 以下代码放到<head></head>中// <![CDATA[
document.write("
 
.steps_anim {scale(.5); }
 
 
");
function doResize() {
  scaleStyleSheet.innerHTML = ".steps_anim {-webkit-transform: scale(" (document.documentElement.clientWidth / 750) ")}";
}
window.onresize = doResize;
doResize();
// ]]>

经过革新后的方案 CSS 的断点没了,以为是不易了,可是作者感到这一个方案不是个纯粹的营造方案。

笔者们知晓<img> 是足以依靠钦点的尺寸自适应缩放尺寸的,假使逐帧动画也能与 <img> 自适应缩放,那就足以从纯构建角度完成「构想二」。

SVG无独有偶能够解决难点!!!SVG 的表现与 <img>``类似同时能够做动画。以下是我的落成方案C。

html:

JavaScript

<svg viewBox="0, 0, 360, 540" class="steps_anim"> <image xlink:href="//misc.aotu.io/leeenx/sprite/m.png" width="1800" height="540" /> </svg>

1
2
3
<svg viewBox="0, 0, 360, 540" class="steps_anim">
  <image xlink:href="//misc.aotu.io/leeenx/sprite/m.png" width="1800" height="540" />
</svg>

css:

JavaScript

.steps_anim { position: absolute; width: 9rem; height: 13.5rem; top: 50%; left: 50%; margin: -5.625rem 0 0 -5.625rem; image { animation: step 1.2s steps(5) infinite; } } @keyframes step { 100% { transform: translate3d(-1800px, 0, 0); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.steps_anim {
  position: absolute;
  width: 9rem;
  height: 13.5rem;
  top: 50%;
  left: 50%;
  margin: -5.625rem 0 0 -5.625rem;
  image {
   animation: step 1.2s steps(5) infinite;
  }
}
@keyframes step {
  100% {
    transform: translate3d(-1800px, 0, 0);
  }
}

参考资料:



1 赞 4 收藏 评论

彩世界网址 16

本文由时时app平台注册网站发布于web前端,转载请注明出处:一个栗子上手 CSS3 动画彩世界网址

关键词: