CSS3 Animation

css3 中的关键帧 @keyframes

@keyframes 规则通过在动画序列中定义关键帧的样式来控制 css 动画序列中的中间步骤

@keyframes identifier {
  from {
    // 等效于 0%
  }
  to {
   // 等效于 100%
  }      
}

 例如:

@keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%;
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}

@keyframes identifier {
  0% { top: 0; left: 0; }
  30% { top: 50px; }
  68%, 72% { left: 50px; }
  100% { top: 100px; left: 100%; }
}

 

css animation 属性是如下属性的简写形式:animation-name, animation-duration, animation-timing-function, animation-delay, animation-iteration-count, animation-direction 和 animation-fill-mode

/* @keyframes duration | timing-function | delay |
   iteration-count | direction | fill-mode | play-state | name */
  animation: 3s ease-in 1s 2 reverse both paused slidein;

/* @keyframes duration | timing-function | delay | name */
  animation: 3s linear 1s slidein;

/* @keyframes duration | name */
  animation: 3s slidein;

 

1、animation-name

animation-name: none | IDENT[,none | IDENT]*;

用来定义一个动画的名称,主要有两个值:IDENT 是有 Keyframes 创建的动画名,或 none (默认值)。多个取值,用逗号隔开

 

2、animation-duration

animation-duration: <time>[,<time>]*

用来指定元素播放动画所持续的时间长,取值数值,单位s 或 ms。默认值 0

 

3、animation-timing-function

animation-timing-function:ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier(<number>, <number>, <number>, <number>) [, ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier(<number>, <number>, <number>, <number>)]* 

同 tansition-timing-function

 

4、animation-delay

animation-delay: <time>[,<time>]*

同 transition-delay

 

5、animation-iteration-count

animation-iteration-count:infinite | <number> [, infinite | <number>]* 

用来指定元素播放动画的循环次数,其中 <number> 取值为数字,默认是 1。infinite 为无限次数循环

 

6、animation-direction

 animation-direction: normal | alternate [, normal | alternate]* 

用来指定元素动画播放的方向,默认值是 normal,表示动画的每次循环都是向前播放;另一个取值是 alternate,表示动画播放在第偶数次向前播放,奇数次反方向播放

 

7、animation-play-state

animation-play-state:running | paused [, running | paused]* 

用来控制元素动画的播放状态,允许播放和暂停

 

8、animation-fill-mode

用来指定动画执行前后如何为目标元素应用样式

demo:文本滑过浏览器窗口

<p class="text">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Distinctio ex amet deleniti, earum ratione assumenda eius laborum nulla minima, unde ullam natus et nostrum labore optio totam laudantium reprehenderit est.</p>
.text{
  animation-name: slidein;
  animation-duration: 3s;
}
@keyframes slidein {
  from{
    margin-left: 100%;
    width: 300%;
  }
  to{
    margin-left: 0%;
    width: 100%;
  }
}

此时,第一帧时,元素的左边距为100%(即位于容器的右边界),宽为300%(即容器宽度的3倍),整个标题位于浏览器窗口右边界之外。第二帧时,元素的左边距为0,宽度为100%,使得动画结束时元素和窗口边界对齐

增加一个帧,让字体变大然后恢复正

@keyframes slidein {
  from{
    margin-left: 100%;
    width: 300%;
  }
  75%{
    margin-left: 25%;
    width: 150%;
    font-size: 300%;
  }
  to{
    margin-left: 0%;
    width: 100%;
  }
}

重复动画

animation-iteration-count 用以指定动画重复的次数,仅仅使用该属性就能使动画重复播放。例如:infinite 可以使动画无限重复

.text{
  animation-name: slidein;
  animation-duration: 3s;
  animation-iteration-count: infinite;
}
@keyframes slidein {
  from{
    margin-left: 100%;
    width: 300%;
  }
  // 75%{
  //   margin-left: 25%;
  //   width: 150%;
  //   font-size: 300%;
  // }
  to{
    margin-left: 0%;
    width: 100%;
  }
}

来回运动

animation-direction 属性为 alternate 时,可以使标题来回滑动,避免每次动画开始时总是调回开始位置显得很怪异

.text{
  animation-name: slidein;
  animation-duration: 3s;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}
@keyframes slidein {
  from{
    margin-left: 100%;
    width: 300%;
  }
  // 75%{
  //   margin-left: 25%;
  //   width: 150%;
  //   font-size: 300%;
  // }
  to{
    margin-left: 0%;
    width: 100%;
  }
}

使用动画事件

利用动画事件可以更好的控制动画和信息。这些事件由 AnimationEvent对象表示,可探测动画何时开始结束和开始新的循环。每个事件包括动画发生的时间和触发事件的动画名称。

我们将修改滑动文本示例,输出每个动画事件出现时的信息。

.slidein {
  -moz-animation-duration: 3s;
  -webkit-animation-duration: 3s;
  animation-duration: 3s;
  -moz-animation-name: slidein;
  -webkit-animation-name: slidein;
  animation-name: slidein;
  -moz-animation-iteration-count: 3;
  -webkit-animation-iteration-count: 3;
  animation-iteration-count: 3;
  -moz-animation-direction: alternate;
  -webkit-animation-direction: alternate;
  animation-direction: alternate;
}
    
@-moz-keyframes slidein {
  from {
    margin-left:100%;
    width:300%
  }
      
  to {
    margin-left:0%;
    width:100%;
  }
}

@-webkit-keyframes slidein {
  from {
    margin-left:100%;
    width:300%
  }
  
  to {
   margin-left:0%;
   width:100%;
 }
}

@keyframes slidein {
  from {
    margin-left:100%;
    width:300%
  }
  
  to {
   margin-left:0%;
   width:100%;
 }
}

(1)、添加动画事件监听器

我们使用JavaScript代码监听所有三种可能的动画事件,setup()方法设置事件监听器,当文档第一次加载完成时执行该方法

var e = document.getElementById("watchme");
e.addEventListener("animationstart", listener, false);
e.addEventListener("animationend", listener, false);
e.addEventListener("animationiteration", listener, false);

e.className = "slidein";

以上是非常标准的代码写法,setup()最后设置动画元素的class为slidein,启动动画。

为什么这样做?因为animationstart事件在动画一开始时就被触发,在我们的示例中,该事件在我们的代码执行前就被触发,所以我们自己通过设置元素的的class来启动动画。

(2)、接收事件

事件传递给listener()函数,代码如下所示

function listener(e) {
  var l = document.createElement("li");
  switch(e.type) {
    case "animationstart":
      l.innerHTML = "Started: elapsed time is " + e.elapsedTime;
      break;
    case "animationend":
      l.innerHTML = "Ended: elapsed time is " + e.elapsedTime;
      break;
    case "animationiteration":
      l.innerHTML = "New loop started at time " + e.elapsedTime;
      break;
  }
  document.getElementById("output").appendChild(l);
}

通过event.type来判断发生的是何种事件,然后添加对应的注解到<ul>中。

HTML代码:

<div>
    <h1 id="watchme">Watch me move</h1>
    <p class="text">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Distinctio ex amet deleniti, earum ratione assumenda eius laborum nulla minima, unde ullam natus et nostrum labore optio totam laudantium reprehenderit est.</p>
    <ul id="output"></ul>
</div>

 

 

注意以上时间非常接近预期时间,但不是完全相等。也要注意在最后一个周期完成后,不会触发animationiteration事件,而触发animationend事件。

 

参考文档:

https://developer.mozilla.org/zh-CN/docs/Web/CSS/animation

http://www.w3cplus.com/content/css3-animation

posted @ 2018-09-04 20:26  rogerwu  阅读(324)  评论(0编辑  收藏  举报