`
yiminghe
  • 浏览: 1460148 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Ext-core 阅读笔记 - 2 ( Ext.Fx )

阅读更多

基础:

 

Ext-core 阅读笔记 - 1 中揭示了lib.anim的基本原理,这只是动画的底层,extjs 在这基础上进一步封装,形成了以元素为单元的动画效果,其中最重要的就是Fx,其中的方法直接apply到Element元素,使得每个节点元素可以方便实现自己想要的独立效果,即使底层lib.anim是单一timer集中处理的。


Fx理论:

 

Fx.js这部分关键为生成 wrap为relative定位 ,并且overflow为hidden ,包围着要使用特效的 element, element在特效运行过程中为absolute定位 根据 archor固定初始element位置 (left,top,right,bottom ),然后利用底层动画库修改wrap的相关大小信息使得element渐渐显示出来即可,而不是直接修改element的相关信息,况且直接修改element的相关属性并不能表示出特定动画,如:slideIn , archor : t ,尾部信息要先显示出来,在这种情况下直接改变element的属性很难完成。

有兴趣可以看一下 calendarlite 中月份panel的显示过程,即是用了 slideIn('t',{...}) 。

 

 

SlideIn t 实现简述:

 

wrap元素css属性为overflow:hidden ;position: relative;

修改element元素css属性为position:absolute;bottom:0;left:0;

使得element底部始终贴着wrap的底部,随着wrap高度增加,element的顶部一点点显示,而底部始终显示出来,即从下到上显示

 

代码详细解释:

 

具体分析一下 Ext.Fx 中 slideIn 在 archor为 t 的代码运行过程。

 

slideIn : function(anchor, o){
	//当前进行动画的Ext.Element 直接 this也可以
        var el = this.getFxEl();
        o = o || {};


        //每个元素的动画处理为一个单位,
        //根据o设置是否并行,是否阻塞其他元素动画,是否终止上一个元素动画,在queueFx中判断
        //默认一般是串行不阻塞不中止上一个元素动画,所以一般操作是放入队列
        el.queueFx(o, function(){

	//动画什么方式
            anchor = anchor || "t";

            // 动画元素 display 要出来,加入文档树种处理
            this.fixDisplay();

            // 记下当前元素的postion,size,动画会破坏这些属性
            var r = this.getFxRestore();
            
            
            var b = this.getBox();
            // 动画元素要绝对定位了,那么就要设置高宽比较好
            this.setSize(b);

            // 同上述分析,要动画元素包装一层,以后就wrap属性动画了就行了
            var wrap = this.fxWrap(r.pos, o, "hidden");

            var st = this.dom.style;
            st.visibility = "visible";
            //动画元素绝对定位,关键部分!
            st.position = "absolute";

            //动画完了以后,恢复原状
            var after = function(){
            	  //wrap元素删掉,动画元素放到原来位置
                el.fxUnwrap(wrap, r.pos, o);
                st.width = r.width;
                st.height = r.height;
                //调用我们配置的callback
                el.afterFx(o);
            };
            
            //根据archor计算调用 lib.anim需要的参数
            var a, pt = {to: [b.x, b.y]}, bw = {to: b.width}, bh = {to: b.height};

            switch(anchor.toLowerCase()){
                case "t":
                    //初始wrap高为0,则动画元素看不到了
                    wrap.setSize(b.width, 0);
                    //使得动画元素的底部紧贴wrap底部,所以动画过程中,动画元素是底部先显示出来,最后才是头部。
                    //见 calendarlite
                    st.left = st.bottom = "0";
                    a = {height: bh};
                break;
                //只分析一下 默认的 t
                //...
            }
            //动画元素要始终显示,只要注意wrap的属性变化
            this.dom.style.visibility = "visible";
            wrap.show();

            //对wrap的height属性应用动画过程即可。
            arguments.callee.anim = wrap.fxanim(a,
                o,
                'motion',
                .5,
                'easeOut', after);
        });
        return this;
    }
 

 

 

 

 

 

 

 

 

 

1
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics