zoukankan      html  css  js  c++  java
  • velocity序列动画

          结合上次提到的velocity的UI Pack存在一下问题:
    • 动画名称过长,语意性差
    • 使用UI Pack的动画,loop属性会失效
    • 无法监听动画完成时机
     
         我这里想到了一种解决思路:
    • 动画名称过长,语意性差?这个问题很好解决,生成一些简单、易懂,并且大家都在用的动画名称,我这里主要参考了animation.css和magic.css的动画名称,因为这两个库,大家使用的比较多,并且语义化强。
    • 使用UI Pack的动画,loop属性会失效?我不太清楚为什么不支持循环设置,我这里想到的一种方案是,如果设置成无限循环,我会将循环次数设置成1000次。这个次数比较随性,没有进行过任何测试,这里只是提供一种思路,有这么一个参考,我的项目中,页面的平均停留时间是2分钟左右,这样就是120秒,所以我设置成为1000次,既不影响体验,对性能又有一些帮助。
    • 无法监听动画完成时机?我这里在最后一个动画的参数中,增加了一个回调函数,这样在最后一次动画执行完毕就会执行这个回调。同样的,如果你有需要在每个动画执行完毕都进行监听的话,可以尝试按照上面的思路进行实现。
     
         结合上述解决思路,又结合animation.css和magic.css两大css动画库,产出了velocity-ui-pack-extra(velocity动画库加强包),他主要解决的问题:
    • velocity现在使用不便的地方
    • 大幅度的丰富了动画库,使用起来更加方便和快捷。
    • 支持动画序列,根据动画的丰富程度,可以实现于flash相同的动画效果
    • 动画包增加了一些其他信息:动画类型(出现动画、特效动画、消失动画)、动画描述(动画效果的中文描述,便于业务使用)
    • Velocity没有一个很好的清除动画的方式,只是提供了stop和finish动画,不能完全解决问题,这里提供了一种思路,目前感觉还不是很完美,如果有新的思路希望可以帮我解惑。
     
         这里主要使用了Velocity底层提供的两个方法:RegisterEffect和RunSequence
     
         实现过程如下:
            //避免污染Velocity
    	window.MsAnimation = {
    		$: global,
    		/**
    		 * 清除动画,恢复元素初始状态
    		 * @param {String|Object} 元素选择器
    		 */
    		resetAnimation: function(selector) {
    			var  $ = this.$;
    
    		    $(selector).velocity('stop', true)
    			    .velocity('finish')
    			    .velocity({
    				    translate:0,
    					translateX: 0,
    					translateY: 0,
    					translateZ: 0,
    				    rotate: 0,
    				    rotateX: 0,
    				    rotateY: 0,
    				    rotateZ: 0,
    				    scale: 1,
    				    scaleX: 1,
    				    scaleY: 1,
    				    scaleZ: 1,
    				    skew: 0,
    				    skewX: 0,
    				    skewY: 0
    			    }, {
    				    duration: 10
    			    });
    		},
    		/**
    		 * 播放动画序列
    		 * @param selector 选择器或者dom
    		 * @param quene 动画数组或者单动画
    		 * @param callback 队列完成回调
    		 */
    		runAnimation: function(selector, quene, callback) {
    			var self = this;
    
    			var _quene = self._format2velocity(selector, quene);
    
    			if(_quene.length == 0) return;
    
    			//动画队列执行完毕回调
    			_quene[_quene.length-1].o['complete'] = callback ? callback : null;
    
    		    Velocity.RunSequence(_quene);
    		},
    		/**
    		 * 处理循环设置
    		 * @param {Object} animation
    		 * {
    		 *	name: 'bounce',
    		 *	duration: 1,
    		 *	delay: 1,
    		 * 	loop: 1
    		 * }
    		 * @param {Number} loop 循环次数,0代表无限循环
    		 */
    		_dealLoop: function (animation, loop) {
    			var  $ = this.$;
    			var _newQuene = [];
    
    			if(loop == 1) {
    				return [animation];
    			}
    			for(var i=0; i<loop; i++) {
    				var _animation = $.extend(true, {}, animation);
    				//解决循环的重复delay问题
    				if(i != 0) {
    					delete _animation.o.delay;
    				}
    				_newQuene.push(_animation);
    			}
    			return _newQuene;
    		},
    		/**
    		 * 格式化动画格式
    		 * @param {String|Object} 元素选择器
    		 * @param {Object} animation
    		 * {
    		 *	name: 'bounce',
    		 *	duration: 1,
    		 *	delay: 1,
    		 * 	loop: 1
    		 * }
    		 */
    		_animationStyleFormat: function (selector, animationStyle) {
    			var  $ = this.$;
    			var self = this;
    			var __quene = [];
    
    			var animation = {
    				e: $(selector)[0],
    				p: '',
    				o: {}
    			};
    			var duration = parseFloat(animationStyle.duration) * 1000;
    			var delay = parseFloat(animationStyle.delay) * 1000;
    			var interationCount = parseInt(animationStyle.loop);
    			var loop = animationStyle.loop === true ? 1000 : (interationCount ? interationCount : 1); //1000认为是无限循环
    			animation.o.duration = duration;
    			animation.o.delay = delay;
    			animation.p = animationStyle.name;
    			__quene = self._dealLoop(animation, loop);
    			return __quene;
    		},
    		/**
    		 * 动画队列格式化
    		 * @param {String|Object} 元素选择器
    		 * @param {Array|Object} 动画队列
    		 */
    		_format2velocity: function (selector, quene) {
    			var  $ = this.$;
    			var self = this;
    			var _newQuene = [];
    
    			if($.isPlainObject(quene)) {
    				return self._animationStyleFormat(selector, quene);
    			}
    
    			$.each(quene, function(i, animationStyle) {
    				var __quene = self._animationStyleFormat(selector, animationStyle);
    				_newQuene = _newQuene.concat(__quene);
    			});
    
    			return _newQuene;
    		}
    	};
     
         目前这种方式存在的问题:如果同时操作多元素执行多种动画,在移动端性能可能较差,目前正考虑如何解决。能想到的思路是:
         1.开启硬件加速,避免多次重排、重绘
         2.改进多元素执行的动画方式
         3.待深入研究,算是抛出一个问题吧
     
         目前使用上述方式在移动端和PC端有一些例子,感兴趣的可以了解一下。后续会继续解决性能问题。
      PC例子
      移动版例子(建议使用手机模式访问)
        
    注:更多例子可以看这里
  • 相关阅读:
    Leetcode NO.110 Balanced Binary Tree 平衡二叉树
    Leetcode NO.226 Invert Binary Tree 翻转二叉树
    Leetcode NO.215 Kth Largest Element In An Array 数组中的第K个最大元素
    根据特征的浏览器判断
    Cygwin在打开在当前目录
    【转帖】科学对待 健康养猫 打造快乐孕妇
    解决chrome浏览器安装扩展、应用程序一直处在“检查中”的问题
    对【SQL SERVER 分布式事务解决方案】的心得补充
    关于“点击这里继续访问您选择的百度XXX”
    VBA一例:如何保持文本框焦点
  • 原文地址:https://www.cnblogs.com/xiaoheimiaoer/p/4856875.html
Copyright © 2011-2022 走看看