easy-animation | Animation for Sass
最近因为项目缘故,勾搭上了Sass。
其实在折腾Sass之前,也有简单用过一下Less。但碍于Less提供的一些API实在让人觉得有点多余,用着就是不顺手,最后就不了了之啦。
Sass之所以用起来舒服和顺手,很大程度上是因为Compass的存在。Compass提供的足够丰富的API,简直让你觉得写CSS是一种享受。
不过...
Compass居然不支持animation!对,没错,就是CSS3那个做来做动画的animation!(至少我翻了好久的Compass文档也没找到...)
或许你会吐槽说:“啧,自己用Sass的@mixin封装一个animation的方法就搞定啦!”
恩,我一开始也是这么想的,然后我也这么做了...
———— 正文分割线 ————
作为一个Sass新手,我想要一个animation的@mixin时,必然是:
/* animation.scss */
@mixin animation($duration, $name, $count, $function) {
-webkit-animation-duration: $duration;
-webkit-animation-name: $name;
-webkit-animation-iteration-count: $count;
-webkit-animation-timing-function: $function; -moz-animation-duration: $duration;
-moz-animation-name: $name;
-moz-animation-iteration-count: $count;
-moz-animation-timing-function: $function; -ms-animation-duration: $duration;
-ms-animation-name: $name;
-ms-animation-iteration-count: $count;
-ms-animation-timing-function: $function; -o-animation-duration: $duration;
-o-animation-name: $name;
-o-animation-iteration-count: $count;
-o-animation-timing-function: $function; animation-duration: $duration;
animation-name: $name;
animation-iteration-count: $count;
animation-timing-function: $function;
}
恩,这样貌似就达到了用Sass实现了animation的目的啦。
然后我们再优化一下代码:
/* animation.scss */
@mixin animation($name, $duration, $function: ease, $delay: 0s, $count: infinite) {
-webkit-animation: $name $duration $function $delay $count;
-moz-animation: $name $duration $function $delay $count;
-ms-animation: $name $duration $function $delay $count;
-o-animation: $name $duration $function $delay $count;
animation: $name $duration $function $delay $count;
}
这样看,代码优雅多了(自我感觉良好~)。
文章这样就结束了?坑爹吗?!
当然不是!想用animation做动画,自然还要把@keyframes也用上。按照上面的思路,继续用@mixin封装一下相关css代码:
/* keyframes.scss */
@mixin keyframes($animationName) {
@-webkit-keyframes $animationName {
@content;
} @-moz-keyframes $animationName {
@content;
} @-ms-keyframes $animationName {
@content;
} @-o-keyframes $animationName {
@content;
} @keyframes $animationName {
@content;
}
}
看起来貌似一切都妥妥的。
配合上Compass愉快的投入生产:
/* demo1.scss */
@import "compass";
@import "animation.scss";
@import "keyframes.scss"; .circle {
@include animation(circle, 1s, linear);
}
@include keyframes(circle) {
0% {
opacity:;
@include translate(100px, 0);
}
100% {
opacity:;
@include translate(0, 0);
}
}
这样写Sass,真的很简洁很舒服。忍不住打开编译生成的css文件一看,差点哭了出来:
/* demo1.css */
.circle {
-webkit-animation: circle 1s linear 0s infinite;
-moz-animation: circle 1s linear 0s infinite;
-ms-animation: circle 1s linear 0s infinite;
-o-animation: circle 1s linear 0s infinite;
animation: circle 1s linear 0s infinite;
} @-webkit-keyframes circle {
0% {
opacity:;
-webkit-transform: translate(100px, 0);
-moz-transform: translate(100px, 0);
-ms-transform: translate(100px, 0);
-o-transform: translate(100px, 0);
transform: translate(100px, 0);
}
100% {
opacity:;
-webkit-transform: translate(0, 0);
-moz-transform: translate(0, 0);
-ms-transform: translate(0, 0);
-o-transform: translate(0, 0);
transform: translate(0, 0);
}
} @-moz-keyframes circle {
0% {
opacity:;
-webkit-transform: translate(100px, 0);
-moz-transform: translate(100px, 0);
-ms-transform: translate(100px, 0);
-o-transform: translate(100px, 0);
transform: translate(100px, 0);
}
100% {
opacity:;
-webkit-transform: translate(0, 0);
-moz-transform: translate(0, 0);
-ms-transform: translate(0, 0);
-o-transform: translate(0, 0);
transform: translate(0, 0);
}
} @-ms-keyframes circle {
0% {
opacity:;
-webkit-transform: translate(100px, 0);
-moz-transform: translate(100px, 0);
-ms-transform: translate(100px, 0);
-o-transform: translate(100px, 0);
transform: translate(100px, 0);
}
100% {
opacity:;
-webkit-transform: translate(0, 0);
-moz-transform: translate(0, 0);
-ms-transform: translate(0, 0);
-o-transform: translate(0, 0);
transform: translate(0, 0);
}
} @-o-keyframes circle {
0% {
opacity:;
-webkit-transform: translate(100px, 0);
-moz-transform: translate(100px, 0);
-ms-transform: translate(100px, 0);
-o-transform: translate(100px, 0);
transform: translate(100px, 0);
}
100% {
opacity:;
-webkit-transform: translate(0, 0);
-moz-transform: translate(0, 0);
-ms-transform: translate(0, 0);
-o-transform: translate(0, 0);
transform: translate(0, 0);
}
} @keyframes circle {
0% {
opacity:;
-webkit-transform: translate(100px, 0);
-moz-transform: translate(100px, 0);
-ms-transform: translate(100px, 0);
-o-transform: translate(100px, 0);
transform: translate(100px, 0);
}
100% {
opacity:;
-webkit-transform: translate(0, 0);
-moz-transform: translate(0, 0);
-ms-transform: translate(0, 0);
-o-transform: translate(0, 0);
transform: translate(0, 0);
}
}
可以看到,每一个@keyframes里面,都重复输出了一套完整兼容的transform。虽然这样的代码不会出现任何异常,但作为一个稍稍有点洁癖的程序员,估计都无法忍受这样的效果。
随后想了几个解决方法,都不能很好的解决。主要被以下几个问题困扰着:
- @keyframes所配置的属性,有可能带浏览器的prefix(-webkit-transform),也有可能不带(opacity )。
- 如何才能对不同prefix的@keyframes输出对应的属性。如@-webkit-keyframes能对应上-webkit-transform,而opacity这类非私有的属性则不带上prefix。
- 每一个@keyframes对应的配置属性,都是通过@content来传值的。翻查了一下Sass的文档,也没看到哪里有提及到访问@content的方式。
Google了一下相关信息,也没找到现成的animation for sass的方法。
幸亏最后在stackoverflow上发现了一个有趣的问题→_→传送门。
提问人和我遇到了类似的情况,也是卡在了@keyframes的私有属性输出的问题。十分幸运的是,在问题下面的回答中,发现了Bourbon这个Sass的库。
Bourbon所封装的@keyframes方法,就很好的解决了我上面遇到的问题。
忍不住看了一下它的源码,实现思路很妙。还帮助我更好的弄清了Compass中experimental的实现思路。
考虑到Compass和Bourbon没有相互依赖的关系,同时使用会出现变量污染的问题。最后根据Bourbon的实现思路,重构了这么一个叫做 easy-animation 的动画工具集。
/* easy-animation.scss */ // easy-animation
// Author: Maple Jan
// Date: 2014-04-11 // Support browser's private prefix.
$ea-prefix-for-webkit: true !default;
$ea-prefix-for-mozilla: true !default;
$ea-prefix-for-microsoft: true !default;
$ea-prefix-for-opera: true !default;
$ea-prefix-for-spec: true !default; // required for keyframe mixin // Disable all browser's private prefix.
@mixin ea-disable-prefix-for-all() {
$ea-prefix-for-webkit: false;
$ea-prefix-for-mozilla: false;
$ea-prefix-for-microsoft: false;
$ea-prefix-for-opera: false;
$ea-prefix-for-spec: false;
} // Example usage:
// @include ea-transition(all 2s ease 0s);
@mixin ea-transition($value, $prefixs: webkit moz ms o spec) {
@each $prefix in $prefixs {
@if $prefix == webkit {
@if $ea-prefix-for-webkit {
-webkit-transition: $value;
}
}
@else if $prefix == moz {
@if $ea-prefix-for-mozilla {
-moz-transition: $value;
}
}
@else if $prefix == ms {
@if $ea-prefix-for-microsoft {
-ms-transition: $value;
}
}
@else if $prefix == o {
@if $ea-prefix-for-opera {
-o-transition: $value;
}
}
@else if $prefix == spec {
@if $ea-prefix-for-spec {
transition: $value;
}
}
@else {
@warn "Unrecognized prefix: #{$prefix}";
}
}
} // Example usage:
// @include ea-transform(scale(1));
@mixin ea-transform($value, $prefixs: webkit moz ms o spec) {
@each $prefix in $prefixs {
@if $prefix == webkit {
@if $ea-prefix-for-webkit {
-webkit-transform: $value;
}
}
@else if $prefix == moz {
@if $ea-prefix-for-mozilla {
-moz-transform: $value;
}
}
@else if $prefix == ms {
@if $ea-prefix-for-microsoft {
-ms-transform: $value;
}
}
@else if $prefix == o {
@if $ea-prefix-for-opera {
-o-transform: $value;
}
}
@else if $prefix == spec {
@if $ea-prefix-for-spec {
transform: $value;
}
}
@else {
@warn "Unrecognized prefix: #{$prefix}";
}
}
} // Example usage:
// @include ea-animation(wrap_s0_p1, 2s, ease, 0s, infinite);
@mixin ea-animation($name, $duration, $function: ease, $delay: 0s, $count: infinite) {
-webkit-animation: $name $duration $function $delay $count;
-moz-animation: $name $duration $function $delay $count;
-ms-animation: $name $duration $function $delay $count;
-o-animation: $name $duration $function $delay $count;
animation: $name $duration $function $delay $count;
} // Example usage:
// @include ea-keyframes(wrap_s0_p1) {
// 0% {
// opacity:;
// @include ea-transform(scale(1));
// }
// 50% {
// opacity: 0.8;
// @include ea-transform(scale(0.8));
// }
// 100% {
// opacity:;
// @include ea-transform(scale(1));
// }
// }
@mixin ea-keyframes($name) {
$_ea-prefix-for-webkit: $ea-prefix-for-webkit;
$_ea-prefix-for-mozilla: $ea-prefix-for-mozilla;
$_ea-prefix-for-microsoft: $ea-prefix-for-microsoft;
$_ea-prefix-for-opera: $ea-prefix-for-opera;
$_ea-prefix-for-spec: $ea-prefix-for-spec; @if $_ea-prefix-for-webkit {
@include ea-disable-prefix-for-all();
$ea-prefix-for-webkit: true;
@-webkit-keyframes #{$name} {
@content;
}
}
@if $_ea-prefix-for-mozilla {
@include ea-disable-prefix-for-all();
$ea-prefix-for-mozilla: true;
@-moz-keyframes #{$name} {
@content;
}
}
@if $_ea-prefix-for-microsoft {
@include ea-disable-prefix-for-all();
$ea-prefix-for-microsoft: true;
@-ms-keyframes #{$name} {
@content;
}
}
@if $_ea-prefix-for-opera {
@include ea-disable-prefix-for-all();
$ea-prefix-for-opera: true;
@-o-keyframes #{$name} {
@content;
}
}
@if $_ea-prefix-for-spec {
@include ea-disable-prefix-for-all();
$ea-prefix-for-spec: true;
@keyframes #{$name} {
@content;
}
} $ea-prefix-for-webkit: $_ea-prefix-for-webkit;
$ea-prefix-for-mozilla: $_ea-prefix-for-mozilla;
$ea-prefix-for-microsoft: $_ea-prefix-for-microsoft;
$ea-prefix-for-opera: $_ea-prefix-for-opera;
$ea-prefix-for-spec: $_ea-prefix-for-spec;
}
十分简洁优雅的使用:
/* demo2.scss */
@import "easy-animation.scss";
.pen {
@include ea-animation(pen, 1s, linear);
}
@include ea-keyframes(pen) {
0% {
opacity:;
@include ea-transform(translate(100px, 0));
}
100% {
opacity:;
@include ea-transform(translate(0, 0));
}
}
生成的CSS:
/* demo2.css */
.pen {
-webkit-animation: pen 1s linear 0s infinite;
-moz-animation: pen 1s linear 0s infinite;
-ms-animation: pen 1s linear 0s infinite;
-o-animation: pen 1s linear 0s infinite;
animation: pen 1s linear 0s infinite;
} @-webkit-keyframes pen {
0% {
opacity:;
-webkit-transform: translate(100px, 0);
}
100% {
opacity:;
-webkit-transform: translate(0, 0);
}
} @-moz-keyframes pen {
0% {
opacity:;
-moz-transform: translate(100px, 0);
}
100% {
opacity:;
-moz-transform: translate(0, 0);
}
} @-ms-keyframes pen {
0% {
opacity:;
-ms-transform: translate(100px, 0);
}
100% {
opacity:;
-ms-transform: translate(0, 0);
}
} @-o-keyframes pen {
0% {
opacity:;
-o-transform: translate(100px, 0);
}
100% {
opacity:;
-o-transform: translate(0, 0);
}
} @keyframes pen {
0% {
opacity:;
transform: translate(100px, 0);
}
100% {
opacity:;
transform: translate(0, 0);
}
}
以上.
本文链接:http://www.cnblogs.com/maplejan/p/3659830.html
本文作者:Maple Jan
参考资料:
easy-animation | Animation for Sass的更多相关文章
- Android动画之二:View Animation
作为一个博客<Android其中的动画:Drawable Animation>.android动画主要分为三大部分.上一篇博客已经解说Drawable Animation的使用方法,即逐帧 ...
- Android动画三部曲之中的一个 View Animation & LayoutAnimation
转载请注明出处:http://blog.csdn.net/crazy1235/article/details/50612827 本篇文章对android的Tween动画和帧动画以及布局动画进行总结. ...
- Android Animation动画详解(二): 组合动画特效
前言 上一篇博客Android Animation动画详解(一): 补间动画 我已经为大家介绍了Android补间动画的四种形式,相信读过该博客的兄弟们一起都了解了.如果你还不了解,那点链接过去研读一 ...
- 虾扯蛋:Android View动画 Animation不完全解析
本文结合一些周知的概念和源码片段,对View动画的工作原理进行挖掘和分析.以下不是对源码一丝不苟的分析过程,只是以搞清楚Animation的执行过程.如何被周期性调用为目标粗略分析下相关方法的执行细节 ...
- Android动画效果之Tween Animation(补间动画)
前言: 最近公司项目下个版本迭代里面设计了很多动画效果,在以往的项目中开发中也会经常用到动画,所以在公司下个版本迭代开始之前,抽空总结一下Android动画.今天主要总结Tween Animation ...
- 弄清 CSS3 的 transition 和 animation
弄清 CSS3 的 transition 和 animation transition transition 属性是 transition-property, transition-duration, ...
- 构造自己的动画函数:animation,stop功能的实现
最近做一个广告项目,里面涉及很多动画效果,由于不能使用jquery,所以只能构建自己的动画方法. 数据结构: elem是DOM对象,给它设置一个属性对象,用来记录elem的动画对象,比如'left', ...
- 安卓中級教程(8):pathbutton中的animation.java研究(1)
src/geniuz/myPathbutton/myAnimations.java package geniuz.myPathbutton; import java.util.ArrayList; i ...
- 老司机带你走进Core Animation
为什么时隔这么久我又回来了呢? 回来圈粉. 开玩笑的,前段时间ipv6被拒啊,超级悲剧的,前后弄了好久,然后需求啊什么的又超多,所以写好的东西也没有时间整理.不过既然我现在回来了,那么这将是一个井喷的 ...
- android 补间动画和Animation
介绍: 补间动画是一种设定动画开始状态.结束状态,其中间的变化由系统计算补充.这也是他叫做补间动画的原因. 补间动画由Animation类来实现具体效果,包括平移(TranslateAnimation ...
随机推荐
- NTP同步网络时间
为什么要同步网络时间呢,这是由于树莓派没有RTC和后备电池,不能像PC机那样关机之后仍可以走时. NTP对时步骤: 1 安装ntpdate sudo apt-get install ntpdate s ...
- 正确的姿势解决IE弹出证书错误页面
在遇到IE证书问题时,正确的解法是安装证书到受信任的储存区 1.继续浏览此网站 2.进入页面后,点击地址栏的证书错误,查看证书 3.安装,设置安装到受信任的颁发机构 4.OK
- maven执行"mvn clean package" 命令报错
昨天利用mvn打包,执行程序'mvn clean package' 命令,发现打包失败 问题描述 具体看代码 发信tomcat下的log 清除不掉.为什么呢?忽然想起来我的项目服务还起着,于是我把服务 ...
- IbatisNet连接oracle 报错
提示什么 connect oracle 1.5.0.xxxx 将你本机的oracle 客户端版本重装换成32位即可
- Mysql向数据库插入数据时,判断是否存在,若不存在就插入数据
表中一定要有主键 : select :id,此处的id位置处必须是主键 insert into table_name(id, name, password) select :id, :name, : ...
- Tomcat8.0配置JNDI多数据源
jndi配置 :此种配置需要在Tomcat的server.xml中和context.xml中配置数据源,在项目中引用. 需要在tomcat下加入数据库连接的jar包,相关包(ojdbc14;c3p0数 ...
- 【转】关于在linux下清屏的几种技巧
在windows的DOS操作界面里面,清屏的命令是cls,那么在linux 里面的清屏命令是什么呢?下面笔者分享几种在linux下用过的清屏方法. 1.clear命令.这个命令将会刷新屏幕,本质上只是 ...
- java多线程 -- 原子量 变量 CAS
多线程原子性问题的产生和解决 原子变量:在 java.util.concurrent.atomic 包下提供了一些原子变量. 1. volatile 保证内存可见性,可以查看atomic中变量是使用v ...
- Android Studio怎么文件添加到收藏和打开收藏夹
http://jingyan.baidu.com/article/1709ad809e608b4634c4f0b9.html 在使用Android studio编写的代码的过程中,有时会碰到有一些文件 ...
- supervisor "unix:///var/run/supervisor/supervisor.sock no such file" 解决方法
如果是没有开启 supervisord 服务的情况下出现这种报错,可以先 systemctl start supervisor 试试, 如果不是,那就 sudo touch /var/run/supe ...