Sass自动化处理CSS动画实例教程

有一天,Harry Roberts有一段有关于他网站上的代码在twitter求教,如果有可能,在某些方面得到改善。Harry Roberts做的是使用keyframes的carousel动画,所以说使用一些数学计算是有可能得到相应改善。

    “Why do we have to learn algebra, Miss? We’re never going to use it…” —Everyone in my maths class bit.ly/UaM2wf

有什么好主意?

据我所见,Harry Roberts在他的主页上使用了一个carousel动画。可以使用CSS,为什么要使用JavaScript呢,你说对吧。所以他使用CSS动画来制作Carousel动画。这听起来似乎是一个很好的想法,但直到你需要计算keyframe时,你就不会这么认为。

下面是有关于Harry Roberts对Carousel动画做的描述。

滚动Carousel(硬编码,有点让人觉得恶心!)和使用一个小动画(这个动画运动是模糊/动画)。整个Carousel动画需要计算过渡和延迟时间(比如100%):

n * x + (n - 1) * y = 100

其中n是指幻灯片的数量,x是动画在静态时的百分比,y是动画在运动时的百分比。

这个动画有5张幻灯片,根据上面描述,可以得到:

5 * x + (5 - 1) * y = 100

如果知道x和n的值,我们就可以计算出y的值:

(100 - (n * x)) / (n - 1) = y

假设x选择的值为17.5(也就是动画中17.5%位置),我们知道n=5,这样可以计算出y=3.125:

(100 - (5 * 17.5)) / (5 -1) = 3.125

帧从17.5%过渡到3.125%等等,直到100%。

如果我们把x设置为15,那么可以计算出y=6.25:

(100 - (5 * 15)) / (5 -1) = 6.25

如果y运动是从"zero-or-below",这也意味着,我们选择了x值太大。

注意,我们还有一个中间点,也就是在中间过渡帧,这个数可以这们得来:

(a * x) + ((a - 1) * y) + (y / 2)

问题是在n个帧哪一个帧才是中间帧。一般情况是3和4之间:

(3 * 17.5) + ((3 - 1) * 3.125)+ (3.125 / 2) = 60.3125

这的确很混乱。

最终结果是:

@keyframes carousel {
  0% {
    transform: translate3d(0, 0, 0);
    filter: blur(0);
  }
  17.5% {
    transform: translate3d(0, 0, 0);
    filter: blur(0);
  }
  19.0625% {
    filter: blur(2px);
  }
  20.625% {
    transform: translate3d(-20%, 0, 0);
    filter: blur(0);
  }
  38.125% {
    transform: translate3d(-20%, 0, 0);
    filter: blur(0);
  }
  39.6875% {
    filter: blur(2px);
  }
  41.25%   {
    transform: translate3d(-40%, 0, 0);
    filter: blur(0);
  }
  58.75%   {
    transform: translate3d(-40%, 0, 0);
    filter: blur(0);
  }
  60.3125% {
    filter: blur(2px);
  }
  61.875%  {
    transform: translate3d(-60%, 0, 0);
    filter: blur(0);
  }
  79.375%  {
    transform: translate3d(-60%, 0, 0);
    filter: blur(0);
  }
  80.9375% {
    filter: blur(2px);
  }
  82.5%    {
    transform: translate3d(-80%, 0, 0);
    filter: blur(0);
  }
  100%     {
    transform: translate3d(-80%, 0, 0);
    filter: blur(0);
  }
}

清洁CSS动画

之前我考虑过Sass,减少动画代码。从上面的代码块中,我们不难发现,有一些关键帧是相同的。这样我们可以把代码清理清理,让整个动画变得更简单:

@keyframes carousel {
  0%,
  17.5% {
    transform: translate3d(0, 0, 0);
    filter: blur(0);
  }
  19.0625% {
    filter: blur(2px);
  }
  20.625%,
  38.125% {
    transform: translate3d(-20%, 0, 0);
    filter: blur(0);
  }
  39.6875% {
    filter: blur(2px);
  }
  41.25%,
  58.75% {
    transform: translate3d(-40%, 0, 0);
    filter: blur(0);
  }
  60.3125% {
    filter: blur(2px);
  }
  61.875%,
  79.375% {
    transform: translate3d(-60%, 0, 0);
    filter: blur(0);
  }
  80.9375% {
    filter: blur(2px);
  }
  82.5%,
  100% {
    transform: translate3d(-80%, 0, 0);
    filter: blur(0);
  }
}

Sass怎么玩

关键帧通常可以得到优化。因为@keyframes中循环的帧通常很容易产生重复的动画。我们可以试试。

首先,为了保持一致性,我们照常使用Harry的变量名:n,x和y。别忘了它们的含义:

    $n是动画中的帧数
    $x是动画帧的百分比,逻辑上是小于或等于100% / $n
    $y是动画中每一帧的比例

$n: 5;
$x: 17.5%;
$y: (100% - $n * $x) / ($n - 1);

现在我们在@keyframes中做一个循环:

@keyframes carousel {
    @for $i from 0 to $n { // 0, 1, 2, 3, 4
        //Sass动画
    }
}

在循环中,我们使用Harry的公式计算每一对相同的关键帧(比如41.25%和58.75%):

$current-frame: ($i * $x) + ($i * $y);
$next-frame: (($i + 1) * $x) + ($i + $y);

特别声明:小括号完全可以略去,这里只是用它们来让代码保持更干净。

现在,我们使用这些变量来生成关键帧,别忘了在里面插入正确的CSS(有关于更多的Sass内容,可以点击这里):

#{$current-frame, $next-frame} {
  transform: translateX($i * -100% / $frames);
  filter: blur(0);
}

非常简单,不是吗?运行第一个循环之后,编译出CSS代码:

0%, 17.5% {
  transform: translate3d(0%, 0, 0);
  filter: blur(0);
}

剩下的就是Harry说的,在中间帧中添加blur()效果。我们可以使用他的公式计算出:

$halfway-frame: $i * ($x / 1%) + ($i - 1) * $y + ($y / 2);

#{$halfway-frame} {
  filter: blur(2px);
}

这里出错了。

    无效的CSS:我们预期的关键帧,比如10%,可计算出来的是-1.5625%。

正如你所看到,我们最终得到了一个负的关键帧。这在CSS规范中是禁止的,就算在Sass中也认为这是一个错误,所以我们需要确保这种事情不会发生。实际上,只有当$i为0才会发生。因此,有一个简单的方法来阻止这样的事情发生,根据规则输出$i的值:

@if $i > 0 {
  #{$halfway-frame} {
    filter: blur(2px);
  }
}

错误解决了,这是最后的代码:

$n: 5;
$x: 17.5%;
$y: (100% - $n * $x) / ($n - 1);
@keyframes carousel {
  @for $i from 0 to $n {
    $current-frame: ($i * $x) + ($i * $y);
    $next-frame: (($i + 1) * $x) + ($i + $y);
    #{$current-frame, $next-frame} {
      transform: translate3d($i * -100% / $frames, 0, 0);
    }
    $halfway-frame: $i * ($x / 1%) + ($i - 1) * $y + ($y / 2);
    @if $i > 0 {
      #{$halfway-frame} {
        filter: blur(2px);
      }
    }
  }
}

将这一切放在一个mixin中

到目前为止,这一切都好了?Harry的动画代码工作的很好,所以他没有再次计算。如果他想把幻灯片从5张变成4张,或者说希望动画时间更快或更慢,这一切以得重新开始。

目前我们的变量会污染全范围。同样的,如果在其他地方需要Carousel动画,需要重新设置其他变量名,然后将动画内容复制到新的动画中。这绝不是理想的做法。

这就是我们使用mixin的理由。为了让事情更易理解,我们使用实际的变量名来替代这些字母:

    $n换成$frames
    $x换成$static
    $y换成$animating

另外,为了确保它输出不同的动,可以利用mixin多次调用不同的参数。所以我们需要再添加一个参数:动画的名字。

@mixin carousel-animation($frames, $static, $name: 'carousel') {
  $animating: (100% - $frames * $static) / ($frames - 1);
  // Moar Sass
}

由于mixin可以在不同的地方调用,为了阻止选择器包括它,可以使用@at-root确保动画输出是在根级别:

@mixin carousel-animation($frames, $static, $name: 'carousel') {
  $animating: (100% - $frames * $static) / ($frames - 1);
  @at-root {
    @keyframes #{$name} {
      // Animation logic here
    }
  }
}

在实际中,可以这样调用:

@include carousel-animation(
  $frames: 5,
  $static: 17.5%
);

编译出来的CSS:

@keyframes carousel {
  0%, 17.5% {
    transform: translateX(0%);
    filter: blur(0);
  }
  19.0625% {
    filter: blur(2px);
  }
  20.625%, 38.125% {
    transform: translateX(-20%);
    filter: blur(0);
  }
  39.6875% {
    filter: blur(2px);
  }
  41.25%, 58.75% {
    transform: translateX(-40%);
    filter: blur(0);
  }
  60.3125% {
    filter: blur(2px);
  }
  61.875%, 79.375% {
    transform: translateX(-60%);
    filter: blur(0);
  }
  80.9375% {
    filter: blur(2px);
  }
  82.5%, 100% {
    transform: translateX(-80%);
    filter: blur(0);
  }
}

任务完成了。如果我们想在联系页面使用另一个动,可以这样使用:

@include carousel-animation(
  $name: 'carousel-contact',
  $frames: 3,
  $static: 20%
);

是不是十分完美。(^_^)。

总结

这想当的完美。而Harry当初的代码容易阅读,但真的不太容易维护。使用Sass的自动化计算和循环特性,可以变得更佳方便。当然,它也使代码变得更为复杂,但这也使得它易于维护和更新。使用起来也非常的简单。

Sass

// ----
// Sass (v3.4.0.rc.1)
// Compass (v1.0.0.alpha.20)
// ----
/**
 * Generate the carousel animation
 * based on the number of frames
 * and the pourcentage of a frame spent static
 *
 * @param {Number} $n - number of frames
 * @param {Number} $x - percentage of the animation spent static per frame
 * @param {String} $animation-name ('carousel') - animation name
 */
 
@mixin carousel-animation($frames, $static, $animation-name: 'carousel') {
  // Make `$static` a percentage in case it's unitless
  @if unitless($static) {
    $static: percentage($static);
  }
  // Compute the percentage of animation spent animating for each frame
  $animating: (100% - $frames * $static) / ($frames - 1);
  
  // Output the animation at root level
  // to make sure it doesn't crash if called in a selector
  @at-root {
    
    // Create an animation
    @keyframes #{$animation-name} {
      
      // Loop over the frames
      @for $i from 0 to $frames {
        // Compute keyframes
        $current-frame: $i * $static + $i * $animating;
        $next-frame: ($i + 1) * $static + $i * $animating;
        $halfway-frame: $i * $static / 1% + ($i - 1) * $animating + $animating / 2;
        
        // Output halfway styles for blur
        // Avoid a negative keyframes by making sure `$i` is at least `1`
        @if $i > 0 {
          #{$halfway-frame} {
            filter: blur(2px);
          }
        }
        // Output styles for each frame
        #{$current-frame, $next-frame} {
          transform: translateX($i * -100% / $frames);
          filter: blur(0);
        }
      }
    }
  }
}
// Generate animation
@include carousel-animation(5, 17.5%);

CSS

/**
 * Generate the carousel animation
 * based on the number of frames
 * and the pourcentage of a frame spent static
 *
 * @param {Number} $n - number of frames
 * @param {Number} $x - percentage of the animation spent static per frame
 * @param {String} $animation-name ('carousel') - animation name
 */
@keyframes carousel {
  0%, 17.5% {
    transform: translateX(0%);
    filter: blur(0);
  }
  19.0625% {
    filter: blur(2px);
  }
  20.625%, 38.125% {
    transform: translateX(-20%);
    filter: blur(0);
  }
  39.6875% {
    filter: blur(2px);
  }
  41.25%, 58.75% {
    transform: translateX(-40%);
    filter: blur(0);
  }
  60.3125% {
    filter: blur(2px);
  }
  61.875%, 79.375% {
    transform: translateX(-60%);
    filter: blur(0);
  }
  80.9375% {
    filter: blur(2px);
  }
  82.5%, 100% {
    transform: translateX(-80%);
    filter: blur(0);
  }
}

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索css
, 变量
, static
代码
sass css3动画、css3动画实例、css3文字动画效果实例、css3动画实例教程、css3动画运用的实例,以便于您获取更多的相关知识。

时间: 2024-09-19 13:05:38

Sass自动化处理CSS动画实例教程的相关文章

css div 实例教程

css div入门教程了,下面我们来看看各位也是现在流量的布局div css喽,这种布局想对table 布局来讲确实有一定优势哦了,但是在制作与设计方面确实很难了,好了今天我们就来看个实例教程吧,先看看下面的效果. 这是我们的效果图片了,首页是一张背景图片,然后页我们用li标签或标签都可以实现了,好我们先来看看div  css代码吧,然后再讲教程. <h2><img src="images/deliveryservice.jpg"></h2> <

Flash制作卷轴动画实例教程

  用Flash软件制作书法卷轴动画,是考试中必考的试题,本文对Flash制作卷轴动画实例 进行了具体阐述供阅读.大家请仔细阅读下文! 1.新建文档,然后导入图片,在舞台的第一帧拖入图片,调节到合适的大小并按(F8)转化为影片剪辑元件(提示:转化为影片剪辑的目的是为了能够使用模糊滤镜) 2.新建层,复制图层1的第一帧,粘贴到图层2的第一帧,在第二层的第一帧选择影片剪辑元件,在属性栏选择-添加滤镜-模糊(15左右,视舞台大小及图片分辨率),在图层1和图层2的第90帧按F5插入帧(提示:90帧是影片

Fireworks利用滤镜工具制作Gif动画实例教程

gif文件: png文件: R: 看了"小可爱"转的用fireworks插件制作3D的gif动画,实在强大. 介绍这个插件的文章有差不多这样一句话:按下"导出"按钮,可能有类似死机现象,但是只要耐心等待,总会输出gif. 晕,我家里的机是n年前的老牌货,看来要另想办法了. 乱碰乱撞之下,意想不到的事情发生了----- 1. 新建一个150*100px大小的画布, 用"星型工具"画一个四叶草图案,为它加一个"纯色阴影滤"镜. 按

css3 loading: 3款漂亮的CSS3 Loading动画实例教程

HTML第1个例子中的HTML标记非常简单,我们在页面上创建了一个ul列表标记,并在其内部创建了几个div来控制它的总体进度动画,代码如下: 12345678910111213141516171819202122 <ul id="progress">    <li>    <div id="layer1" class="ball"></div> <!-- layer1 control dela

flash羽化遮罩动画实例教程

  一.打开flash软件 二.新建文档,参数默认 三.导入两张图片到库 四.在默认图层从库中拖入一张图片对齐场景作为背景锁住该层 五.添加一个图层,从库中再拖入一张图片对齐场景 模糊遮罩及其制作简介 1.右键点击图片转化为影片剪辑元件 2.选中该剪辑,打开属性面板给它实例名"p1c",在"运用位图缓存"的前面打上勾,锁住该图层 六.再添加一个图层,用椭圆工具无笔触颜色填充颜色任意画一个10*10的圆 1.选中圆居中对齐 2.右键点击圆转化为影片剪辑 3.选中这个圆

Flash设计制作可爱的小兔子跷跷板动画实例教程

  这个Flash实例制作了两只可爱的小兔子玩跷跷板的动画,主要用到椭圆工具.渐变填充和任意变形工具等,操作简单易懂,适合练习. 制作步骤: 1.新建一个默认大小的Flash文档.先画天空背景,用矩形工具画一个矩形,在对齐面板中按下"相对于舞台",再点"匹配宽和高"按钮,最后点"垂直中齐"和"水平中齐"按钮.与舞台对齐之后给矩形设置如下从白色到天蓝色的渐变,方式为"线性". 图1 2.草地.画一个草绿色的矩

Flash设计制作晶莹剔透的沙漏反转动画实例教程

  本教程主要使用Flash制作晶莹剔透的沙漏流动动画教程,效果做的非常的漂亮,喜欢的朋友让我们一起来学习吧. 先看看效果图 下面是教程

3款漂亮的CSS3 Loading动画实例教程

   HTML 第1个例子中的HTML标记非常简单,我们在页面上创建了一个ul列表标记,并在其内部创建了几个div来控制它的总体进度动画,代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <ul id="progress">     <li>     <div id="layer1" class="ball"></div>

WP8.1下用程序生成Gif动画实例教程

Gif文件编码方法 先简单介绍一下编码的方法. 1.调用BitmapEncoder.CreateAsync静态方法实例化编码器,要创建GIF编码器,可以在调用方法时,指定表示GIF编码器的GUID,这个GUID不用特意去记,因为访问BitmapEncoder.GifEncoderId静态属性就能得到. 2.调用SetPixelData方法设置当前帧的图像数据.注意,编码器对象在创建实例后,默认处于第一帧,因此对于设置第一张图片的数据时,可以直接调用SetPixelData方法. 3.从第二帧开始