动画系列之CSS3动画基础

栏目: CSS · 发布时间: 6年前

内容简介:动画系列之CSS3动画基础

CSS3添加了几个动画效果的属性,通过设置这些属性,可以做出一些简单的动画效果而不需要再去借助JavaScript。

CSS3动画的属性主要分为三类:transform、transition以及animation。

基本内容

  • 动画的基本概念
    • 补间动画
    • 逐帧动画
  • Transform
    • 2D变换
    • 3D变换
    • Tranform过渡控制
  • 可动画的属性
  • Transition
    • 基本属性
    • 为不同属性指定过渡时长
    • 变换多个动画属性
    • 时长的简写
    • 强制开启GPU硬件加速
    • 消除Tansition动画闪屏和文字变虚
  • Animation动画
    • 基本属性
    • 关键帧序列
    • 运动方向
    • 重复次数
    • 播放与暂停
    • 起始状态控制
  • Transition 与 Animation 动画的触发
  • 监听动画结束的事件
    • 确保 transitioned 事件触发
    • 强制重绘触发动画
  • 会引起界面重绘的属性
  • Transition动画应用示例
  • Animation动画应用示例

动画的基本概念

补间动画

过滤动画 具有连贯性的动画,从一个关键帧到另一个关键帧的过滤,Transition 动画属于此类动画

逐帧动画

使用steps过渡的动画,在时间帧上逐帧绘制帧内容,由于是一帧一帧的画,所以逐帧动画具有非常大的灵活性,几乎可以表现任何想表现的内容。与电影相似,适用于表现细腻的动画,如人物动作,3D动画等。

缺点是:制作难度大,需要大量素材,导致最终文件的体积很大。

Transform过渡

位移Translate、旋转Rotate、倾斜Skew、缩放Scale 及矩阵变形Matrix

2D变换

  • 位移:translate(12px, 50%); 单位可指定 px % em rem
  • 缩放:scale(x, y)
  • 斜切:skew(0deg, 0deg)
  • 旋转:rotate(0deg)
  • 矩阵:matrix(0, 0, 0, 0, 0, 0)

3D变换

  • 位移: translateX() / translateY() / translateZ() /translate3d()
  • 缩放: scaleX() / scaleZ() / scaleY() / scale3d(2.5, 1.2, 0.3);
  • 斜切: skewX() / skewY()
  • 旋转: rotate3d(1, 2.0, 3.0, 10deg);
  • 矩阵: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);

触发3D变形的属性

.parent {
 perspective: 300px; 透视点
 perspective-origin: center center; 观察者(消失点)的位置(默认为中心点)
 backface-visibility: visible; 3D元素的背面是否可见(默认是visible)
}

MDN backface-visibility perspective perspective-origin

在子元素上触发3D空间

transform: perspective(600);

一本书平放在面前,看着书感受一下透视感,perspective属性值就是眼睛和书之间的距离,距离越远,数值越大,透视感越小;距离越近,数值越小,透视感越强。

简单易懂的教程示例: CSS3 3D教程

Transform 过渡控制

transform-origin / transform-style

定义过渡原点

transform-origin ( transform-origin-x 、transform-origin-y、transform-origin-z )

默认为元素的中心原点

transform-origin: left top; 左上角
transform-origin: right bottom; 右下角
transform-origin: center bottom; 底部中心
transform-origin: 50% 50%; 中心
transform-origin: 10px 2em;
transform-origin: right 20%;
transform-origin: right 20% 30px;
transform-origin: bottom top 2px;

定义子元素的是扁平化还是三维展示

transform-style: flat | preserve-3d

transform-style: preserve-3d; 用于触发子元素三维展示

可动画的属性

border / color / backgorund / height、width / left、right、top、bottom / padding / margin / opacity / font-size / box-shadow / text-shadow / transform

这里列举了 一些常见的可动画的属性,详情请查看 MDN 可动画的属性列表

Transition

定义过渡动画效果

基本属性

  • transition-property 需要进行过渡属性(只有指定的属性才进行过滤动画) 或者 全部可动画的属性 all
  • transition-delay 延迟时间
  • transition-duration 进行过渡的时间
  • transition-timing-function 指定动画函数

简写

transition: <property> <duration> <timing-function> <delay> ;

为不同属性指定过渡时长

transition-property: opacity, left, top, height;
transition-duration: 3s, 5s, 1s, 2s;

时长的简写

如果有部分属性没有指定时长,则重复前面的时长

transition-property: opacity, left, top, height;
transition-duration: 3s, 5s;
等价于
transition-duration: 3s, 5s, 3s, 5s;

! 为了过渡的流畅性,一般需要指定动画的属性,可以有以下几种指定方式

transition: margin-left 4s;

/* property name | duration | delay */
transition: margin-left 4s 1s;

/* property name | duration | timing function | delay */
transition: margin-left 4s ease-in-out 1s;

/* Apply to 2 properties */
transition: margin-left 4s, color 1s;

/* duration | delay | property name */
transition: 4s 1s color;

变换多个动画属性

.box {
 width: 100px; height: 100px; background-color: #0000FF;
 transition: width 2s, height 2s, background-color 2s, transform 2s;
}
.box:hover { 
 width: 200px; height: 200px; background-color: #FFCCCC; transform: rotate(180deg);
}

强制开启GPU硬件加速

.box { transition: tanslate3d(0,0,0)或 tansition: translateZ(0) }

消除Tansition动画闪屏和文字变虚

.box{ transform-style: preserve-3d; backface-visibility:hidden; }

注意

避免使用会引起重排的属性做动画,如: letf / margin / padding / width / height 等会引起大量重排重绘的属性

Animation动画

可以将从一个CSS样式配置转换到另一个CSS样式配置

动画包括两个部分: 描述动画的样式规则和用于指定动画开始、结束以及中间点样式的关键帧。

优点:简单,性能良好,浏览器可以自动优化

基本属性

动画的实际表现是由 @keyframes 规则实现

  • animation-name 动画的名称(由@keyframes定义)
  • animation-delay 动画延时
  • animation-direction 定义动画完成后,是从初始状态还是从最终状态重复动画
  • animation-duration 动画时长
  • animation-iteration-count 动画重复次数
  • animation-play-state 播放或暂停动画
  • animation-timing-function 设置动画关键帧之间的运动函数
  • animation-fill-mode 指定动画前后如何为元素应用样式

关键帧序列 keyframes

使用 @keyframes 定义动画序列关键帧

简单的动画可以使用 form/to 来定义 开始和结束关键帧

p {
 animation-duration: 3s;
 animation-name: slidein;
}

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

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

复杂的动画可以使用 百分比 更精确的控制

.tada {
 animation-name: tada;
 animation-duration: 3s;
}

@keyframes tada {
 0% {
 transform: scale3d(1, 1, 1);
 }

 10%, 20% {
 transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg);
 }

 30%, 50%, 70%, 90% {
 transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);
 }

 40%, 60%, 80% {
 transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);
 }

 100% {
 transform: scale3d(1, 1, 1);
 }
}

运动方向 animation-direction

animation-direction:normal | alternate | alternate-reverse | reverse

  • normal : 正向运动
  • alternate : 先正向再反向再正再反循环反复
  • alternate-reverse : 先反向再正向再反再正循环反复
  • reverse : 反向运动

重复次数 animation-iteration-count

animation-iteration-count: infinite | <single-animation-iteration-count>

  • infinite : 循环执行
  • single-animation-iteration-count :循环的周期数值(可以是小数)

播放暂停 animation-play-state

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

  • running :运动
  • paused :暂停

起始状态控制 animation-fill-mode

animation-fill-mode: none | forwards | backwards | both

设置元素动画之后的状态

  • none :不应用状态
  • forwards : 应用动画结束帧的状态(结束帧与动画运动次数和方向有关)
  • backwards : 应用动画起始帧的状态 (与动画运动方向有关)
  • both : 应用首帧与结束帧(同时应用 forwards 与 backwrads)

Transition 与 Animation 动画的触发

可以通过伪类 (:link、:visited、:hover、:active、:focus、:checked、:enabled、:disabled) 和 事件触发

如果直接给元素设置 transform ,用户将直接看到元素的最终状态,而不会有动画

通过切换元素设定好的动画类可以很方便的控制 TransitonAnimation 动画

Transiton动画 有入场和出场动画,比如一个元素在 :hover 状态时触发 transiton 动画,在鼠标离开后,动画自动反向播放回到 transition 之前的状态

Transition 通过伪类、事件或一个 Class 切换,可以很方便的实现入场和出场动画, 而 Animation 动画则要通过不同的 Class 来控制入场和出场

监听动画结束的事件

  • Transition动画监听 transitionend 事件
  • Animation动画监听 animationend 事件

简单粗暴的方法: 监听所有可能支持的事件

var transitionEndEventNames = {
 'WebkitTransition' : 'webkitTransitionEnd',
 'OTransition' : 'oTransitionEnd',
 'msTransition' : 'MSTransitionEnd',
 'transition' : 'transitionend'
}

var animationEndEventNames = {
 'WebkitAnimation' : 'webkitAnimationEnd',
 'OAnimation' : 'oAnimationEnd',
 'msAnimation' : 'MSAnimationEnd',
 'animation' : 'animationend'
}


function getEventNames(nameMap){
 retunr Object.keys(nameMap).map(v=>nameMap[v]).join(' ');
}

var animationEndEventName = getEventNames(transitionEndEventNames);
var transitionEndEventName = getEventNames(animationEndEventNames);

oDiv.addEventListener( transitionEndEventName, callbackFn )
oDiv.addEventListener( animationEndEventName, callbackFn )

只监听受支持的事件

通过检测 body.style 中是否有相关属性来获取受支持的属性名称

var transEndEventNames = {
 WebkitTransition: 'webkitTransitionEnd',
 MozTransition: 'transitionend',
 OTransition: 'oTransitionEnd otransitionend',
 transition: 'transitionend'
};

var animEndEventNames = {
 WebkitAnimation: 'webkitAnimationEnd',
 MozAnimation: 'animationend',
 OAnimation: 'oAnimationEnd oanimationend',
 animation: 'animationend'
};

var elStyle = (document.body || document.documentElement).style;

function getSupportName(nameMap){
 var keys = Object.keys(nameMap).filter(v=>elStyle[v] !== undefined);
 return nameMap[keys[0]];
}

var transitionEnd = getSupportName(transEndEventNames);
var animationEnd = getSupportName(animEndEventNames);

oDiv.addEventListener( transitionEnd, callbackFn )
oDiv.addEventListener( animationEnd, callbackFn )

注意

  • 当属性值没有发生变化或没有绘制行为发生,transitionend 事件不会被触发
  • 如果有多个属性进行transtion动画,则会触发多次 transitierend 事件

确保 transitioned 事件触发

结合jQuery 确保 transitioned 事件能被触发

$.fn.emulateTransitionEnd = function(duration){
 var called = false, $el = this;
 $(this).once('webkitTransitionEnd', function(){ called = true; });
 var callback = function(){ if (!called) $($el).trigger('webkitTransitionEnd'); };
 setTimeout(callback, duration);
};

使用

$(this).one('webkitTransitionEnd', callback);
$(this).emulateTransitionEnd(options.duration + 50);
$(this).css(properties);

原理:同时给 元素 绑定两个 webkitTransitionEnd 事件和一个 setTimeout ,如果 webkitTransitionEnd 能正确触发,则 calledtruesetTimeout 中回调内的代码则不执行

强制重绘触发动画

给一个 display:none 元素添加 Transition 动画时,先要将 display 设置为 block ,同时应用 Transition 动画,但是两套css执行的时间间隔太近,浏览器会尝试优化css属性的变化,直接表现为transition最终的状态,无法显示动画效果,为了避免这种情况,可以在将 display 设置为 block 时,同时强制浏览器对css进行重绘,触发 transition 动画(一般获取一次元素的 offsetHeight 属性即可)。

会引起界面重绘的属性

  1. offsetTop, offsetLeft, offsetWidth, offsetHeight
  2. scrollTop/Left/Width/Height
  3. clientTop/Left/Width/Height
  4. width,height
  5. 请求了getComputedStyle()

当请求上面的一些属性的时候,浏览器为了给你最精确的值,需要flush队列,因为队列中可能会有影响到这些值的操作。

结合 jQuery 添加一个强制重绘的方法:

$.fn.redraw = function(){
 $(this).each(function(){
 var redraw = this.offsetHeight;
 });
};

使用

$('.element').css({left: '10px'})
 .redraw()
 .transition({left: '20px'});

这种方法在大多数浏览器都有效,但在个别 Andorid默认浏览器上偶尔还是会失效。这时就只能使用定时器或者增加class了。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

水平营销

水平营销

[美] 菲利普·科特勒、费尔南多・德・巴斯 / 陈燕茹 / 中信出版社 / 2005-1 / 25.00元

《水平营销》阐明了相对纵向营销而言的的水平营销的框架和理论。引入横向思维来作为发现新的营销创意的又一平台,旨在获得消费者不可能向营销研究人员要求或建议的点子。而这些点子将帮助企业在产品愈加同质和超竞争的市场中立于不败之地。 《水平营销》提到: 是什么创新过程导致加油站里开起了超市? 是什么创新过程导致取代外卖比萨服务的冷冻比萨的亮相? 是什么创新过程导致巧克力糖里冒出了玩具......一起来看看 《水平营销》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器