• 制作炫酷的专题页面


        很多时候,我们需要一些炫酷的动画效果,让页面更加吸引用户的眼球,现有比较好用的JS动画库有:velocity和GSAP(支持falsh和js)。今天这里主要学习的是velocity配合css3动画,快速打造属于你的专题页面。
        PS:发现各种炫酷的效果都是由这些简单的动作通过组合实现的,发现最终效果和动画的设计者有很大关系,鄙人就属于那种不怎么懂设计的人,这里只是抛砖引玉。
     
        虽然我今天不准备详细介绍GSAP这个动画库,但是还有有必要把相关资源的入口放在这里,供想要了解的 同学进行深入的 学习。
        最好的学习就是查看官方API文档,其次结合场景才会出现的问题,可以交流一下应该就可以解决。
     
        废话不多说了,进入今天的正题。
     
        基础技能
     
        velocity功能    
        包含$.animate()所有功能,并且包含切换、转换、循环、缓动、CSS切换、scroll功能,从效率角度来说,比CSS更高。
        
        兼容性
        支持IE8+,chrome、firefox、android、ios(可以配置mobileMA,提升手机访问效果)
     
        默认配置
        可以使用$.Velocity.defaults进行查看管理。
     
        注:关于配置的使用说明,可以参考官方文档说明。其中begin、complete监听动画状态
       
        调用方式
        支持两种书写方式
    • 第一种:
       
     /**
      * @param {Object|String} 需要改变css属性最终状态值或者是注册动画
      * @param {Object} 动画基本配置,可以查看默认配置
      */
    $element.velocity(properties, options) 
    

      

        
    • 第二种
        
    /**
     * @param {Object} 操作元素,可以是原生对象,也可以是包装对象 
     * @param {Object|String} 需要改变css属性最终状态值或者是注册动画
     * @param {Object} 动画基本配置,可以查看默认配置
     */
    $.Velocity($element, properties, options);
    

      

     
        另:所有的属性值都可以是函数,返回最终的值
     
        提升技能
        
        自定义动画效果
        velocity提供了注册自定义动画的方法,方便使用者自定义,并进行方便多次使用
        
    $.Velocity.RegisterEffect(name, {
    	defaultDuration: duration,
    	calls: [ 
    		[ { property: value }, durationPercentage, { options } ],
    		[ { property: value }, durationPercentage, { options } ]
    	],
    	reset: { property: value, property: value }
    
    });
    

      

        来一个简单的例子:
       
     $.Velocity.RegisterEffect("callout.pulse", {
    	defaultDuration: 900,
    	calls: [
    		[ { scaleX: 1.1 }, 0.50 ],
    		[ { scaleX: 1 }, 0.50 ]
    	]
    });
    

      

        注册一个callout.pulse方法,如何进行使用呢?可以参照基础技能中的调用方式,这里使用其中一种方式
        $elements.velocity('callout.pulse'); //相当于是properties参数值
     
        UI pack--动画包
        官方提供一些动画包,可以直接进行使用,也可以通过自定义注册动画,然后进行使用。
        现有的的动画效果有:
        
    callout.bounce,callout.shake,callout.flash,callout.pulse,callout.swing,callout.tada,transition.fadeIn,transition.fadeOut,transition.flipXIn,transition.flipXOut,transition.flipYIn,transition.flipYOut,transition.flipBounceXIn,transition.flipBounceXOut,transition.flipBounceYIn,transition.flipBounceYOut,transition.swoopIn,transition.swoopOut,transition.whirlIn,transition.whirlOut,transition.shrinkIn,transition.shrinkOut,transition.expandIn,transition.expandOut,transition.bounceIn,transition.bounceOut,transition.bounceUpIn,transition.bounceUpOut,transition.bounceDownIn,transition.bounceDownOut,transition.bounceLeftIn,transition.bounceLeftOut,transition.bounceRightIn,transition.bounceRightOut,transition.slideUpIn,transition.slideUpOut,transition.slideDownIn,transition.slideDownOut,transition.slideLeftIn,transition.slideLeftOut,transition.slideRightIn,transition.slideRightOut,transition.slideUpBigIn,transition.slideUpBigOut,transition.slideDownBigIn,transition.slideDownBigOut,transition.slideLeftBigIn,transition.slideLeftBigOut,transition.slideRightBigIn,transition.slideRightBigOut,transition.perspectiveUpIn,transition.perspectiveUpOut,transition.perspectiveDownIn,transition.perspectiveDownOut,transition.perspectiveLeftIn,transition.perspectiveLeftOut,transition.perspectiveRightIn,transition.perspectiveRightOut
    

      

        具体效果可以查看最下面的例子。
     
        自定义动画队列
        官方提供了执行动画队列的方法,$.Velocity.RunSequence(animationArr);其中animationArr是动画数组,数组的每个元素是一个元素动画效果,具体例子如下:
        
    var mySequence = [
    	 { elements: $element1, properties: { translateX: 100 }, options: { duration: 1000 } },
    	 { elements: $element2, properties: { translateX: 200 }, options: { duration: 1000, sequenceQueue: false },
    	 { elements: $element3, properties: { translateX: 300 }, options: { duration: 1000?}
    ];
    $.Velocity.RunSequence(mySequence);
    //默认队列动画是按照顺序执行的,可以通过设置sequenceQueue改变当前元素执行时机。默认是true,当为true时,指的是按照顺序执行,如果设置成false指的是,可以和上一个元素动画同时执行
    

      

        
        支持promise
        引入官方推荐的bluebird和when,即可采用如下使用方式:
       
     $element.velocity(properties, options).then(); //需要注意是的是无线循环和队列不支持该形式
    

      

     
       终极技能
     
        配合css3动画,达到最佳效果
     
     
        友情提示:
        velocity在进场和出场动画方面优势比较大,css3在循环动画上优势比较大。当然万恶的IE兼容问题    
     
        基于上面所讲到的,实现了一个基于jquery、velocity、animation.css实现的动画,仅供参考
        
    /**
     * 动画处理
     * author: 黑MAO
     */
    $(function() {
    	'use strict';
    	
    	/****内部方法开始****/
    	/**
    	 * css动画执行函数
    	 * @param {Object} 目标元素
    	 * @param {String} 初始class
    	 * @param {String} 动画类型
    	 * @param {Number} 动画时长
    	 * @param {Number} 动画延迟
    	 * @param {Number} 循环次数
    	 */
    	var timer;
    	function _cssRun(targetEl, className, animation, duration, delay, loop) {
    		duration = duration*1 || 1000;
    		delay = delay*1 || 0;
    		loop = (loop || loop == 0) ? loop*1 : 1;
    		
    		if(loop < 1) {
    			loop = 'infinite';
    		}
    		$(targetEl).removeClass();
    		$(targetEl).addClass(className).addClass(animation);
    		$(targetEl).css({
    			'animation-duration': duration+'ms',
    			'animation-delay': delay+'ms',
    			'animation-iteration-count': loop+''
    		});
    		if(loop != 'infinite') {
    			clearTimeout(timer);
    			timer = setTimeout(function() {
    				$(targetEl).removeClass(animation);
    			}, duration*loop + delay);
    		}
    		
    	}
    	/**
    	 * 监听select变化方法
    	 * @param {Object} 目标元素
    	 * @param {Object} 操作元素集合
    	 * @param {String} 初始class
    	 * @param {String} 动画类型 ["css", "js"]
    	 */
    	function _changeFunc(targetEl, opElementObj, className, animationType) {
    		var animation = $(opElementObj.animationEl).val();
    		var duration = $(opElementObj.durationEl).val();
    		var delay = $(opElementObj.delayEl).val();
    		var loop = $(opElementObj.loopEl).val();
    		if(animationType == "css") {
    			_cssRun(targetEl, className, animation, duration, delay, loop);
    		}else {
    			var ras = new Ras();
    			if(animation) {
    				ras.run(targetEl, 'stop');
    				ras.run(targetEl, animation, {duration: duration, delay: delay, stagger: 200, drag: true});
    			}
    		}
    	}
    	/**
    	 * 初始化动画
    	 * @param {Array} 动画数组 
    	 * @param {Object} 操作元素对象
    	 * @param {Object} 目标元素
    	 * @param {Number} 动画延迟
    	 * @param {String} 需要显示的动画类型 ["show", "hide", "normal", "all"]
    	 * @param {String} 动画类型 ["css", "js"]
    	 */
    	function _initAnimation(animationArr, opElementObj, targetEl, type, animationType) {
    		var conf = opElementObj;
    		var className = $(targetEl).attr("class");
    		
    		$(conf.animationEl).prepend('<option value="" diabled="disabled">选择动画类型</option>');
    		$(animationArr).each(function(key, val) {
    			var isShow = false;
    			switch(type) {
    				case "show":
    					if(val.indexOf('In') > 0) {
    						isShow = true;
    					}
    					break;
    				case "hide":
    					if(val.indexOf('Out') > 0) {
    						isShow = true;
    					}
    					break;
    				case "normal":
    					if(val.indexOf('Out') == -1 && val.indexOf('In') == -1) {
    						isShow = true;
    					}
    					break;
    				default:
    					isShow = true;
    					break;
    			}
    			isShow && $(conf.animationEl).append('<option value="'+val+'">'+val+'</option>');
    		});
    		$(conf.animationEl).on('change', function() {
    			_changeFunc(targetEl, conf, className, animationType);
    		});
    		$(conf.durationEl).on('change', function() {
    			_changeFunc(targetEl, conf, className, animationType);
    		});
    		$(conf.delayEl).on('change', function() {
    			_changeFunc(targetEl, conf, className, animationType);
    		});
    		$(conf.loopEl).on('change', function() {
    			_changeFunc(targetEl, conf, className, animationType);
    		});
    	}
    	
    	/****内部方法结束****/
    
    	function Ras(opts) {
    		var conf = {
    			beforeIndex : 0, //上一页序列号
    			currentIndex : 0, //当前页序列号
    			playing : true, //是否在运行
    			downward : true, //是否向下滚动
    			imgList: [], //页面内图片列表
    			quenes: { 
    				show: [], //页面显示列表
    				hide: [] //页面隐藏列表
    			},
    			navFunc: null, //导航回调函数
    			cssAnimationExtra: [], //css动画扩展
    			jsAnimationExtra: [] //js动画扩展
    		};
    		
    		this.conf = $.extend(conf, opts);
    	}
    	//对外暴漏
    	window.Ras = Ras;
    	
    	$.extend(Ras.prototype, {
    		init: function() {
    			var self = this;
    			var conf = this.conf;
    			//绑定键盘和鼠标事件
    			var quenes = conf.quenes;
    			var showList = conf.quenes.show;
    			var hideList = conf.quenes.hide;
    			var senceNum = showList.length;
    			$(document).on('mousewheel keyup',function(e){
    				if( !conf.playing ){
    					conf.playing = true;
    					if( e.keyCode && (e.keyCode==39||e.keyCode==40)){
    						conf.downward = true;
    					}
    					if( e.keyCode && (e.keyCode==37||e.keyCode==38) ){
    						conf.downward = false;
    					}
    					if( e.deltaY){
    						conf.downward = e.deltaY<0?true:false;
    					}
    					if( e.keyCode == 37 || e.keyCode == 38 || e.keyCode == 39 || e.keyCode == 40 || e.deltaY ){
    						conf.beforeIndex = conf.currentIndex;
    						conf.currentIndex = conf.downward ?conf.currentIndex + 1:conf.currentIndex - 1;
    						conf.currentIndex = conf.currentIndex>=senceNum?0:conf.currentIndex;
    						conf.currentIndex = conf.currentIndex<0?senceNum-1:conf.currentIndex;
    						conf.navFunc && conf.navFunc(conf.currentIndex);
    						self.show(hideList[conf.beforeIndex], showList[conf.currentIndex], function() {
    							conf.playing = false;
    						});
    					}
    				}
    				return false;
    			});
    			
    			//处理图片预加载
    			var imgList = conf.imgList;
    			imgList.length && self.imgLoader(imgList);
    			
    			//默认显示第一屏
    			self.show(null, showList[0], function() {
    				conf.playing = false;
    			});
    		},
    		/**
    		 * 初始化CSS动画
    		 * @param {Object} 联动元素集合
    		 * @param {Object} 目标元素
    		 * @param {String} 选项类型 ["show", "hide", "normal", "all"]
    		 */
    		initCssAnimation: function(opElementObj, targetEl, type) {
    			var conf = this.conf;
    			var animationStr = 'bounce,pulse,rubberBand,shake,swing,tada,bounceIn,bounceInDown,bounceInLeft,bounceInRight,bounceInUp,bounceOut,bounceOutDown,bounceOutLeft,bounceOutRight,bounceOutUp,fadeIn,fadeInDown,fadeInDownBig,fadeInLeft,fadeInLeftBig,fadeInRight,fadeInRightBig,fadeInUp,fadeInUpBig,fadeOut,fadeOutDown,fadeOutDownBig,fadeOutLeft,fadeOutLeftBig,fadeOutRight,fadeOutRightBig,fadeOutUp,fadeOutUpBig,flip,flipInX,flipInY,flipOutX,flipOutY,lightSpeedOut,rotateIn,rotateInDownLeft,rotateInDownRight,rotateInUpLeft,rotateInUpRight,rotateOut,rotateOutDownLeft,rotateOutDownRight,rotateOutUpLeft,rotateOutUpRight,hinge,rollIn,rollOut,zoomIn,zoomInDown,zoomInLeft,zoomInRight,zoomInUp,zoomOut,zoomOutDown,zoomOutLeft,zoomOutRight,zoomOutUp,slideInDown,slideInLeft,slideInRight,slideInUp,slideOutDown,slideOutLeft,slideOutRight,slideOutUp,magic,openDownLeft,openDownRight,openUpLeft,openUpRight,openDownLeftRetourn,openDownRightRetourn,openUpLeftRetourn,openUpRightRetourn,openDownLeftOut,openDownRightOut,openUpLeftOut,openUpRightOut,perspectiveDown,perspectiveLeft,perspectiveRight,perspectiveUp,perspectiveDownRetourn,perspectiveLeftRetourn,perspectiveRightRetourn,perspectiveUpRetourn,puffIn,puffOut,rotateDown,rotateLeft,rotateRight,rotateUp,slideDown,slideLeft,slideRight,slideUp,slideDownRetourn,slideLeftRetourn,slideRightRetourn,slideUpRetourn,swap,twisterInDown,twisterInUp,vanishIn,vanishOut,swashOut,swashIn,foolishOut,holeOut,tinRightOut,tinLeftOut,tinUpOut,tinDownOut,tinRightIn,tinUpIn,tinDownIn,bombRightOut,bombLeftOut,boingInUp,boingOutDown,spaceOutUp,spaceOutRight,spaceOutLeft,spaceInUp,spaceInRight,spaceInDown,spaceInLeft,boomIn,circleRotate';
    			var animationArr = animationStr.split(',');
    			var arr = [];
    			$.merge(arr, animationArr, conf.cssAnimationExtra);
    			arr = $.unique(arr);
    			_initAnimation(arr, opElementObj, targetEl, type, 'css');
    		},
    		/**
    		 * 初始化JS动画
    		 * @param {Object} 联动元素集合
    		 * @param {Object} 目标元素
    		 * @param {String} 选项类型 ["show", "hide", "normal", "all"]
    		 */
    		initJsAnimation: function(opElementObj, targetEl, type) {
    			var conf = this.conf;
    			var animationStr = 'callout.bounce,callout.shake,callout.flash,callout.pulse,callout.swing,callout.tada,transition.fadeIn,transition.fadeOut,transition.flipXIn,transition.flipXOut,transition.flipYIn,transition.flipYOut,transition.flipBounceXIn,transition.flipBounceXOut,transition.flipBounceYIn,transition.flipBounceYOut,transition.swoopIn,transition.swoopOut,transition.whirlIn,transition.whirlOut,transition.shrinkIn,transition.shrinkOut,transition.expandIn,transition.expandOut,transition.bounceIn,transition.bounceOut,transition.bounceUpIn,transition.bounceUpOut,transition.bounceDownIn,transition.bounceDownOut,transition.bounceLeftIn,transition.bounceLeftOut,transition.bounceRightIn,transition.bounceRightOut,transition.slideUpIn,transition.slideUpOut,transition.slideDownIn,transition.slideDownOut,transition.slideLeftIn,transition.slideLeftOut,transition.slideRightIn,transition.slideRightOut,transition.slideUpBigIn,transition.slideUpBigOut,transition.slideDownBigIn,transition.slideDownBigOut,transition.slideLeftBigIn,transition.slideLeftBigOut,transition.slideRightBigIn,transition.slideRightBigOut,transition.perspectiveUpIn,transition.perspectiveUpOut,transition.perspectiveDownIn,transition.perspectiveDownOut,transition.perspectiveLeftIn,transition.perspectiveLeftOut,transition.perspectiveRightIn,transition.perspectiveRightOut';
    			var animationArr = animationStr.split(',');
    			var arr = [];
    			$.merge(arr, animationArr, conf.cssAnimationExtra);
    			arr = $.unique(arr);
    			_initAnimation(arr, opElementObj, targetEl, type, 'js');
    		},
    		/**
    		 * 入场动画
    		 * @param {Array} 出场队列
    		 * @param {Array} 入场队列
    		 * @param {Function} 入场完成回调
    		 */
    		show: function(beforeQuene, currentQuene, callback) {
    			var self = this;
    			self.hide(beforeQuene);
    			currentQuene && self.run(currentQuene).then(function() {
    				callback && callback();
    			});
    		},
    		/**
    		 * 出场动画
    		 * @param {Array} 出场队列
    		 * @param {Function} 出场完成回调
    		 */
    		hide: function(quene, callback) {
    			var self = this;
    			callback && callback();
    			quene && self.run(quene);
    		},
    		/**
    		 * 图片懒加载
    		 * @param {Array} 图片列表
    		 * @param {Function} 图片加载回调
    		 */
    		imgLoader: function(imgList, callback) {
    			var count = imgList.length,
                    i = 0,
                    success = 0,
                    failed = 0,
                    failList = [];
    			for ( ; i < count ; i++ ) {
    				var img = new Image();
    				(function(i){
    					img.onload = function () {
    						success++;
    						if( (success + failed) == count ) {
    							callback&&callback.call( imgList , failed, failList);
    						}
    					};
    					img.onerror = function () {
    						failed++;
    						failList.push(imgList[i]);
    						if( (success + failed) == count ) {
    							callback&&callback.call( imgList , failed, failList );
    						}
    					};
    					img.src = imgList[i];
    				})(i);
    			}
    		},
    		/**
    		 * 注册自定义动画
    		 */
    		register: function() {
    			var self = this;
    			var args = [].slice.apply(arguments);
    			$.Velocity.RegisterEffect.apply(self, args);
    		},
    		/**
    		 * 封装velocity方法,统一管理队列和单个动画
    		 * @return {Object} promise对象
    		 */
    		run: function() {
    			var deferred = $.Deferred();
    			var self = this;
    			var args = [].slice.call(arguments);
    			var len = args[0].length;
    			
    			if($.isArray(args[0])) {
    				if(!args[0][len-1].options){
    					args[0][len-1].options = {};
    				}
    				args[0][len-1].options.complete = function() {
    					deferred.resolve();
    				};
    				$.Velocity.RunSequence.call(self, args[0]);
    				return deferred.promise();
    			}else {
    				return $.Velocity.animate.apply(self, args);
    			}
    			
    		},
    		/**
    		 * 启动CSS动画
    		 * @param {Object} 操作元素
    		 * @param {String} 初始class
    		 * @param {String} css动画
    		 * @param {Number} 动画时长
    		 * @param {Number} 动画延迟
    		 * @return {Object} promise对象
    		 */
    		cssAnimationRun: function(targetEl, className, animation, duration, delay, loop) {
    			loop = (loop === true) ? 0 : loop;
    			_cssRun(targetEl, className, animation, duration, delay, loop);
    		},
    		/**
    		 * 启动JS动画
    		 * @param {Object} 操作元素
    		 * @param {String} css动画
    		 * @param {Number} 动画时长
    		 * @param {Number} 动画延迟
    		 * @return {Object} promise对象
    		 */
    		jsAnimationRun: function(targetEl, animation, options) {
    			var opts = {
    				stagger: 200, 
    				drag: true
    			};
    			opts = $.extend(opts, options);
    			if(animation) {
    				this.run(targetEl, 'stop');
    				this.run(targetEl, animation, opts);
    			}
    		}
    	});
    });
    

      

        使用方式:
        
    var ras = new Ras({
    	cssAnimationExtra: ['bounce'],
    	jsAnimationExtra: ['callout.bounce']
    });
    ras.init();
    //调用相关方法
    

      

      测试效果地址

     
        附录(资源地址):
     
        <link rel="stylesheet"  href="http://s1.qhimg.com/!efd6dff2/animation.css">
        <script src="http://s0.qhimg.com/lib/jquery/191.js" ></script> 

        <script src="http://s3.qhimg.com/!44713922/bluebird.js" ></script>
        <script src="http://s6.qhimg.com/!7c8590ec/jquery.mousewheel.min.js"></script>
        <script src="http://s6.qhimg.com/!ccefcc09/velocity.min.js"></script>
        <script src="http://s5.qhimg.com/!d0b08d4d/velocity.ui.min.js"></script>

     
        参考资料:
     
  • 相关阅读:
    vlan原理与配置
    路由协议-ospf
    路由协议-rip
    人品
    阿波罗礼赞
    跳石头
    FBI树
    方程求解
    循环比赛
    国王的游戏
  • 原文地址:https://www.cnblogs.com/xiaoheimiaoer/p/4162546.html
Copyright © 2020-2023  润新知