使用CSS3动画构建出色的应用

今天的HTML5应用程序可以提供真棒由于新的CSS3规范的经验。 其中之一是CSS3动画 它可以帮助你在HTML元素构建丰富的动画。 这可以提供有趣的反馈给用户,并实现了快速和流体的UI。 由于这些新的动画是大部分时间硬件加速由GPU,他们肯定提高新一代的HTML5应用程序的质量吧。

据上的“CSS动画模块级别3”规范W3C网站定义动画 CSS3动画介绍,其指定的值即CSS属性将接管给定时间间隔。 该规范的扩展,CSS过渡

由于CSS3动画是一个扩展到CSS3过渡 ,你应该先读我的同事大卫Catuhe对转换这里的文章: 介绍CSS3过渡

我们将在本文中看到一个有趣的演示突出CSS3动画,如何建立简单的动画及如何处理回退在JavaScript中的潜力:

  1. CSS3动画
  2. 浏览器的支持
  3. CSS3动画的JavaScript库的后备
  4. 结论

让我们快速地证明什么CSS3动画第一次启动。 这里是一个星球大战AT-AT的样品动画它使用CSS3动画到运输的动画部分(而这将回落到JavaScript的,如果你的浏览器不支持CSS3动画):

style="border-width: 0px; border-style: solid; border-color: #ffffff;" src="http://david.blob.core.windows.net/html5/css3atat/index.htm" scrolling="no" width="716" height="570"/>

你可以在这里也测试该样品在一个单独的窗口: http://david.blob.core.windows.net/html5/css3atat/index.htm

注:此样品已经成功地与本地的动画在IE10 PP3 / PP4,铬15测试,火狐8的iPad 2,并在IE9桌面和移动(Windows手机)JS回退。 对于未知的原因,它的行为怪异的方式歌剧11.50之下,但正常工作与11.60。 此外,我们可爱的博客平台是时间通过元标记迫使IE9渲染引擎最。 迫使它回到了IE10的标准模式,按下F12键,改变“文档模式”回IE10的价值。 否则,查看在单独的窗口演示。

该样本是根据所做的工作真棒安东尼Calzadilla 您可以检查自己的网站在这里等不可思议的演示: http://www.anthonycalzadilla.com 我是一个巨大的风扇我TWITTY傻瓜使用SVG和CSS3动画例如样品。

CSS3动画

介绍

让我们对你能玩到打造动画第一次审查。 CSS3动画作品基本上作为CSS3过渡相同的值。

他们来了:

  • 颜色 :红色通过,绿色,蓝色和alpha分量内插的(治疗各为一个数字,见下文)
  • 长度 :插值为实数。
  • 百分比 :插为实数。
  • 整数 :通过离散步骤(整数)内插。 的内插发生在实数空间中,并使用地板被转换为整数()。
  • 数量 :插值为实(浮点)数。
  • 转换列表 :看到CSS变换规格: http://www.w3.org/TR/css3-2d-transforms/
  • 矩形 :通过在x,y,宽度和高度的部件(每个处理为数字)内插。
  • 能见度 :通过离散步骤内插。 插值发生在0和1之间的实数空间,其中1为“可见”和所有其他值都“隐藏”。
  • 阴影 :经由彩色,x,y和模糊部件内插的(将它们视为颜色和数字在适当情况下)。 的情况下有,较短的列表在与阴影,其颜色是透明的,所有的长度(X,Y,模糊)0结束填充阴影的列表。
  • 梯度 :经由每个止挡件的位置和颜色内插。 它们必须具有相同的类型(径向或直链)和相同数量的止挡,以进行动画处理。
  • 漆服务器 (SVG):梯度梯度和颜色至颜色:仅之间支持插值。 然后他们的工作同上。
  • 空间分隔的上面所列内容 :如果列表中有相同数量的项目,列表中的每个项目使用上述规则插值。 否则,没有插值。
  • 速记属性 :如果一个速记的所有部件可以是动画,则就如同每个属性被单独指定执行内插。

而下面的属性必须为动画支持:

  • 背景色( 颜色
  • 背景图像( 仅梯度
  • 背景位置( 百分比和长度
  • 底部边框( 彩色
  • 边界底部宽度( 长度
  • 边框颜色( 彩色
  • 左边框( 彩色
  • 左边框宽度( 长度
  • 右边框( 彩色
  • 右边框宽度( 长度
  • 边界间隔( 长度
  • 边框顶部( 彩色
  • 边框顶宽度( 长度
  • 边界宽度( 长度
  • 底部( 长度和百分比
  • 色( 颜色
  • 作物( 矩形
  • 字体大小( 长度和百分比
  • 字体重量( 数量
  • 网格状*( 各种
  • 高度( 长度和百分比
  • 左( 长度和百分比
  • 字母间距( 长度
  • 线高度( 数量,长度和百分比
  • 边距( 长度
  • 利润率左( 长度
  • 余量-右( 长度
  • 边距( 长度
  • 最大高度( 长度和百分比
  • 最大宽度( 长度和百分比
  • 最小高度( 长度和百分比
  • 最小宽度( 长度和百分比
  • 不透明度( 号码
  • 轮廓色( 颜色
  • 轮廓偏移( 整数
  • 轮廓宽度( 长度
  • 填充底部( 长度
  • 填充左( 长度
  • 填充-右( 长度
  • 填充顶( 长度
  • 右( 长度和百分比
  • 文本缩进( 长度和百分比
  • 文字阴影( 影子
  • 顶( 长度和百分比
  • 垂直对齐( 关键字,长度和百分比
  • 能见度( 能见度
  • 宽度( 长度和百分比
  • 字间距( 长度和百分比
  • z索引( 整数
  • 变焦( 数字

SVG

在SVG规范真:当它们被定义为SVG 动画对象的属性是动画http://www.w3.org/TR/SVG/struct.html 但在这里这篇文章是写的时候,我没能CSS3动画直接在SVG元素在任何最新的浏览器版本的结合。 那么今天的网络上的样本正在做一个小窍门:他们是嵌入SVG的资源投入到由CSS3动画不同的DIV像我TWITTY傻瓜样品。

声明

要声明在CSS文件中的动画,这里是你需要写的那种通用代码:

@keyframes name_of_the_animation {

  from {

    property_to_animate: initial_value;

  }

  50% {

    property_to_animate: intermediate_value;

  }

  to {

    property_to_animate: final_value;

  }

}

这也可以写成这样:

@keyframes name_of_the_animation {

  0% {

    property_to_animate: initial_value;

  }

  50% {

    property_to_animate: intermediate_value;

  }

  100% {

    property_to_animate: final_value;

  }

}

此动画定义声明3层的步骤0,50 100%。 你应该至少设置一个 (或0%)和一个或100%)的步骤,以建立正确的动画(最小2步因而)。 一旦这样做,你可以添加尽可能多的关键帧,只要你愿意从0到100%的处理正是你的动画的各个步骤。

一旦定义声明,您可以使用经典的CSS3选择它影响到的元素,你也需要配置动画选项。 这里的那种通用模块,你会看到:

#id_of_the_html_element {

    animation-name: name_of_the_animation;

    animation-duration: number_of_seconds s;

    animation-iteration-count: number | infinite;

}

为了更好的理解,让我们回顾一个真实的样品。 首先,作为CSS3动画规范仍然处于草案阶段,你需要使用相应的供应商前缀。 让我们使用IE10作为与-MS前缀然后一个样本。 现在让我们来看看我们的AT-AT的头部移动。

这里的动画声明:

@-ms-keyframes rotate-skull {

    0% {

        -ms-transform: rotate(0deg)

    }

    25% {

        -ms-transform: rotate(15deg)

    }

    50% {

        -ms-transform: rotate(-5deg)

    }

    55% {

        -ms-transform: rotate(0deg)

    }

    75% {

        -ms-transform: rotate(-10deg)

    }

    100% {

        -ms-transform: rotate(0deg)

    }

}

我们有6个步骤(0,25,50,55,75 100%)对CSS3 2D工作通过改变旋转的值的变换属性。

动画经该CSS规则适用于:

#skull

{

    -ms-animation-name: rotate-skull;

    -ms-animation-duration: 7s;

    -ms-animation-iteration-count: infinite;

}

我们瞄准<div>具有“元素id= skull ”我们正在申请命名为“动画rotate-skull ”就可以了。 动画将在7秒内完成并播放的无数次。

这是,如果你的浏览器支持CSS3动画的生存结果:

style="border: #ffffff 0px solid;" src="http://david.blob.core.windows.net/html5/css3atat/AnimSkullATAT.htm" scrolling="no" width="400" height="200"/>

我们也可以写在使用动画速记属性更短的方式这条规则:

#skull {

    -ms-animation: rotate-skull 7s infinite;

}

该动画将尽快应用的匹配规则触发。 然后,您可以播放或者简单地通过JavaScript或通过CSS3动画停止使用受影响的标签类的发挥。

非线性动画

如果你想非线性动画的“动画定时功能”属性都可以使用。 你甚至可以在每个关键帧中混合的定时功能类型。

基本上,CSS3动画将使用三次Bezier曲线通过在其持续时间计算不同的速度平滑的动画。

将支持以下功能:

  • 线性 :恒速
  • 立方贝塞尔 :速度将根据一个三次Bezier曲线由两个控制点定义来计算:P0和P1(所以你将必须定义4个值这里:P0X,P0y及P1X,P1Y。
  • 难易程度 :速度将与立方贝塞尔来计算(0.25,0.1,0.25,1)
  • 易于在 :速度将与立方贝塞尔来计算(0.42,0,1,1)
  • 易于INOUT:速度将与立方贝塞尔来计算(0.42,0,0.58,1)
  • 缓解出 :速度将与立方贝塞尔来计算(0,0,0.58,1)

下面是写一个仿真工具大卫Catuhe使用纯JavaScript显示每个计时功能的影响:

style="border: #ffffff 0px solid;" src="http://www.catuhe.com/msdn/transitions/easingfunctions.htm" width="1000" height="650"/>

注:该工具使用在线SVG的火狐,Chrome,歌剧11.60和IE9 / 10支持。 这将无法正常歌剧11.50和Safari浏览器在iPad上这样的工作。

这是使用SVG一个真棒工具。 你甚至可以用鼠标玩上的自定义功能来编辑曲线。 如果您想了解更多关于这个工具,请再看看大卫的文章。

如果你的浏览器支持CSS3动画,让我们现在看到一个简单的演示使用缓动函数,包含动画的动画精灵与CSS3 在画布标记

这是将在本演示中使用的CSS3动画代码:

@-ms-keyframes demo {

    from {

    -ms-animation-timing-function: ease;

    -ms-transform: translateX(0px);

    }

    50% {

    -ms-animation-timing-function: ease-in;

    -ms-transform: translateX(300px);

    }

    to {

    -ms-animation-timing-function: ease-inout;

    -ms-transform: translateX(900px);

    }

}

#testCanvas

{

    -ms-animation-delay: 0s;

    -ms-animation-duration: 6s;

    -ms-animation-iteration-count: infinite;

    -ms-animation-name: demo;

}

除了所有的供应商前缀的变化,以确保它的工作原理也是谷歌Chrome和Mozilla Firefox浏览器。 而这里的生活输出:

style="border: #ffffff 0px solid;" src="http://david.blob.core.windows.net/html5/css3animcanvas/sprites.htm" width="1000" height="90"/>

如果你的浏览器不支持CSS3动画,但支持的画布,精灵的运行动画应该被显示,但该角色会不会通过屏幕的宽度移动。

注:如果您想了解更多关于帆布和精灵动画,你可以看看这篇文章: HTML5游戏:动画精灵在画布与EaselJS

延迟

在“动画延迟”属性只允许应用后,动画开始执行一段时间。

活动

3个事件可能在动画过程中得到提升。 它们被命名为“动画开始 ”,“动画结束 ”和“动画迭代 ”。 根据您的浏览器中,正确的名称将是例如:

  • :webkitAnimationEnd
  • 火狐:mozAnimationEnd
  • Internet Explorer中:MSAnimationEnd

本次活动将让你的以下细节:

  • animationName:其引发事件的动画名称
  • elapsedTime:的时间量的动画已经运行,以秒

下面是IE10的用法示例:

elementToAnimate.addEventListener("MSAnimationEnd", function () {

    alert("the end !");

}, false);

更多关于CSS3动画

CSS3动画是2个主要原因真正有用:

  • 硬件加速:CSS3动画大部分由GPU直接处理的时间,并可能产生更平滑的结果。 那么这可能是用于移动设备的一个非常有趣的方法。
  • 代码和设计之间更好的分离 :我知道有这一点,但与大卫一些争论,我们认为,开发商不应该知道设计尽可能相关的动画或什么的。 以同样的方式设计师/艺术家一定不知道的JavaScript。 CSS3报价则这种可能性,并可以让设计师用他们的经典工具生成的元素相应的动画工作,屏风等之间

为了突出这种性能的重要性,下面的HTML5游戏我写了使用全画幅的<canvas>: HTML5平台游戏在IE9 / IE10 60 fps的在我的电脑上一台iPad 2运行,但在10 fps的最高。这是因为它的CPU是更有限的,iPad是目前不是硬件加速<画布>。 使用CSS3过渡/动画以动画几个较小的<canvas>元素可以为这个游戏一个巨大的性能提升。 想想看,当你针对移动设备!

浏览器的支持

由于平台预览版3中可用的IE10 的Windows开发者预览版 ,我们提供支持CSS3动画。 而且,你可以通过产生以下报告中看到caniuse.com的CSS3动画现在支持在多种浏览器:

使用CSS3动画构建出色的应用

但作为规范尚未完成( 工作草案 ),您必须使用供应商的前缀,如-ms-,-moz-,-webkit-,-O-做一个跨浏览器兼容的应用程序。

但问题可能是:如何处理那些不支持这一新功能的浏览器?

第一个选项是不需要做任何事情。 感谢优雅降级的美丽,你可以只让用户只看到静态图像,如果你已经工作正常。 例如,这是安东尼的这2个原始样本的情况: 我TWITTY傻瓜! 纯CSS3 AT-AT步行者 当IE9的注视下,它看起来像我们只有静态图像。 当在IE10的注视下,同样的代码显示了不错的动画。 那么IE10用户将获得一个增强版本,而IE9仍然能够查看和使用正确的网站。 更现代的浏览器,越直观的奖金也就越多。

第二个选项是通过JS库像Modernizr的检测功能,并尝试通过一个JavaScript库,会模仿动画将提供相同的动画。 这就是我们通常所说的后备机制。 不幸的是,我还没有发现今天的作业和完整的JS库,它可以代替CSS3动画时浏览器不支持。

然后我写了一个样本JS库或多或少专为AT-AT样本。

CSS3动画的JavaScript库的后备

动画无非一系列通过经由关键帧所定义的特定持续时间分离转换。 然后我再用大卫Catuhe在他的过渡帮手建库的概念。 我让你回顾他的文章,以检查的代码背后的概念的基础。

在我的身边,我已经加入了一些支持,以动画CSS3 2D到关键帧变换旋转和平移的值和方式进行迭代。

以下是你需要审查库的主要组成部分:

// Animation object

// It need the HTML targeted element, the name of the animation, its duration & iteration count and

// the keyframes contained in an array object

// View the animation simply as a sequence of transitions played a certain number of times

ANIMATIONSHELPER.animation = function (target, name, duration, iterationcount, keyframes) {

    // saving the properties values

    this.name = name;

    this.duration = duration;

    this.iterationcount = iterationcount;

    this.target = target;

    var elapsedtime = 0;

    var keyframeduration = 0;

    var elapsedtime = 0;

    // Transforming the percentage of each keyframe into duration value

    for (var i = 0; i < keyframes.length; i++) {

        keyframeduration = ((keyframes[i].percentage * duration) / 100) - elapsedtime;

        keyframes[i].duration = keyframeduration;

        elapsedtime += keyframeduration;

    }

    this.currentTransition = { isPlaying: false };

    this.keyframes = keyframes;

    this.keyframesCount = keyframes.length;

    this.currentKeyFrameIndex = 0;

    // The nextTransition() function return the next transition to run

    // based on the current keyframe to play

    this.nextTransition = function (keyframe, ease, customEaseP1X, customEaseP1Y, customEaseP2X, customEaseP2Y) {

        var properties = [];

        var finalValues = [];

        var transition;

        // Compared to the original TRANSITIONSHELPER of David Catuhe

        // We need a specific code to play with the CSS3 2D Transform properties values

        if (keyframe.propertyToAnimate === "transform") {

            for (var i = 0; i < keyframe.transformType.length; i++) {

                properties.push(keyframe.transformType[i].type);

                if (keyframe.transformType[i].type == "rotate") {

                    finalValues.push({ deg: keyframe.transformType[i].value1 });

                }

                else {

                    finalValues.push({ x: keyframe.transformType[i].value1, y: keyframe.transformType[i].value2 });

                }

            }

            // Create a new transition

            transition = {

                name: this.name + this.currentKeyFrameIndex,

                target: this.target,

                properties: properties,

                finalValues: finalValues,

                originalValues: ANIMATIONSHELPER.extractValues(target.style[ANIMATIONSHELPER.currentTransformProperty], this.name),

                duration: keyframe.duration,

                startDate: (new Date).getTime(),

                currentDate: (new Date).getTime(),

                ease: ease,

                customEaseP1X: customEaseP1X,

                customEaseP2X: customEaseP2X,

                customEaseP1Y: customEaseP1Y,

                customEaseP2Y: customEaseP2Y,

                isPlaying: true,

                type: "transform"

            };

            return transition;

        }

        // If it's a classic property to animate, we're using more or less the TRANSITIONSHELPER as-is

        else {

            return TRANSITIONSHELPER.transition(this.target, keyframe.propertyToAnimate, keyframe.value, keyframe.duration, TRANSITIONSHELPER.easingFunctions.linear);

        }

    };

    // each animation object has a tick function

    // that will be called every 17 ms (to target 60 fps)

    // This ticker is monitoring the current state of the transition and

    // create a new transition as soon as the old one is finished/dead

    this.tick = function () {

        if (this.iterationcount > 0) {

            if (!this.currentTransition.isPlaying) {

                this.currentTransition = this.nextTransition(this.keyframes[this.currentKeyFrameIndex], ANIMATIONSHELPER.easingFunctions.linear);

                // We're using our own global ticker only for the 2D transformations

                // Otherwise, we're using the one from the TRANSITIONSHELPER library

                if (this.currentTransition.type === "transform") {

                    ANIMATIONSHELPER.currentTransitions.push(this.currentTransition);

                }

                this.currentKeyFrameIndex++;

                // We've reached the last keyframe (100%). We're starting back from the beginning

                if (this.currentKeyFrameIndex >= this.keyframesCount) {

                    this.currentKeyFrameIndex = 0;

                    this.iterationcount--;

                }

            }

        }

    };

};

代码的第一部分是通过每个关键帧迭代来计算由每个百分比指定的确切持续时间。 然后我们定义一个nextTransition()将动态地构建下一个转换功能的发挥基于当前索引到关键帧集合。 最后,我们已经有了一个tick()函数,将监视应用过渡的当前状态。 一旦过渡完成后或死的,它要求下一个过渡,把它推到过渡的堆栈播放和移动指标。

这种tick()函数被调用感谢这个代码:

ANIMATIONSHELPER.launchAnimation = function (animation) {

    // Launching the tick service if required

    if (ANIMATIONSHELPER.tickIntervalID == 0) {

        ANIMATIONSHELPER.tickIntervalID = setInterval(ANIMATIONSHELPER.tick, 17);

    }

    // Little closure to launch the tick method on the appropriate animation instance

    setInterval(function () { animation.tick(); }, 17);

};

最后,我们有这样的代码,可以帮助我们构建关键帧:

// Object to build a new generic keyframe (not working on the CSS3 2D Transform properties thus)

ANIMATIONSHELPER.keyframe = function (percentage, propertyToAnimate, value) {

    this.percentage = percentage;

    this.propertyToAnimate = propertyToAnimate;

    this.value = value;

};

//Objects to build specific rotation keyframes

ANIMATIONSHELPER.rotationkeyframe = function (percentage, value) {

    this.percentage = percentage;

    this.propertyToAnimate = "transform";

    this.transformType = [];

    this.transformType.push(new ANIMATIONSHELPER.transformType("rotate", value));

};

为了突出它的使用,我们将重新创建与此库以前单纯的CSS3动画头骨样本:

// number of times you'd like the animations to be run

var iterationsNumber = 100;

var skullElement = document.getElementById("skull");

var keyframes = [];

keyframes.push(new ANIMATIONSHELPER.rotationkeyframe(25, 15));

keyframes.push(new ANIMATIONSHELPER.rotationkeyframe(50, -5));

keyframes.push(new ANIMATIONSHELPER.rotationkeyframe(55, 0));

keyframes.push(new ANIMATIONSHELPER.rotationkeyframe(75, -10));

keyframes.push(new ANIMATIONSHELPER.rotationkeyframe(100, 0));

var animation1 = new ANIMATIONSHELPER.animation(skullElement, "rotate-skull", 7000,

                            iterationsNumber, keyframes);

ANIMATIONSHELPER.launchAnimation(animation1, ANIMATIONSHELPER.easingFunctions.linear);

而这里的是,现在将在每一个浏览器工作支持CSS3 2D转换的结果:

style="border: #ffffff 0px solid;" src="http://david.blob.core.windows.net/html5/css3atat/indexSkullJS.htm" scrolling="no" width="400" height="200"/>

最后,在本文的开头演示了第一个示例使用Modernizr的检查CSS3动画的支持。 如果不是这种情况,它加载,将模仿文件master.css,MOZ-master.css&MS-master.css定义的关键帧的代码:

// Checking if CSS3 animations is supported

if (!Modernizr.cssanimations) {

// if so, we can use our JS fallback library

    supportElement.innerHTML = "CSS3 Animations <strong>are not supported</strong>";

    LoadJSAnimationsFallback();

}

else {

    // if CSS3 animation is supported, we have nothing to do.

    // The *master.css stylesheets will be automatically applied & used.

    supportElement.innerHTML = "CSS3 Animations <strong>are supported</strong>";

}

所述LoadJSAnimationsFallback()函数被定义成jsfallback-master.js简单地包含所有关键帧的声明和需要模仿由Anthony在纯CSS3创建的行为19级的动画。 在这种方法中,设计人员则需要重写使用库中的所有规则。 另一种方法可以解析使用XHR调用CSS文件之一,动态创建的JavaScript调用库。 这需要你几乎需要重新实现CSS3动画规范在JavaScript中更多的工作!

您现在有建立一个后备机制,以支持更多的浏览器,而开始使用最新的CSS3规范方式的点子。

您也可以下载文件为主要样本的位置: http://david.blob.core.windows.net/html5/css3atat/CSS3ATATNonMinified.zip

它包含animationsHelper.js的unminified版本,transitionsHelper.js,jsfallback-master.js JavaScript文件以及各种CSS3 declinaison文件的主要供应商的前缀。

结论

CSS3动画是一个强大的技术来推动HTML5应用到新的水平。 它提供了有趣的场景。 设计人员可以使用它,而不需要开发者创造出新一代具有平滑和流畅的动画UI屏幕。 因为它的硬件加速的大部分时间,开发商也应注意此规范。 最后,双方有可能合作。 设计师可以在一系列预定义的动画覆盖大多数情况下的工作。 然后,开发人员可以创建一个将实现这些动画的JavaScript库。 这个库可以在一个透明的方式提供2个实现:一个动态生成CSS3的对飞或对旧版浏览器的回退。

进一步展望

其他有用的帖子:

如果你喜欢阅读这篇文章,你一定会喜欢可学习 ; 将所学的大师新鲜的技能和技巧。 会员得到所有SitePoint的电子书和互动式在线课程的即时访问,就像学习CSS3

From: https://www.sitepoint.com//build-awesome-apps-with-css3-animations/