Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

更nice的动画API #460

Closed
jinwei233 opened this issue Aug 29, 2013 · 7 comments
Closed

更nice的动画API #460

jinwei233 opened this issue Aug 29, 2013 · 7 comments
Milestone

Comments

@jinwei233
Copy link
Contributor

KISSY动画API


  Anim (elem, props[, duration, easing, completeFn])

    - elem (String|HTMLElement|KISSY.Node|window) – 作用动画的元素节点或窗口(窗口时仅支持 scrollTop/Left).

elem必须是一个selector或者HTML元素、KISSY.Node window

常见的动画本质上随时间变化,动态的去改变一个DOM元素的属性或样式,但是,有时候期望改变的不是dom的属性或样式。比如:

一道题目

在canvas上画一个圆,想实现其半径逐渐增大的一个动画。怎么实现?

jQuery的实现方式

       var ctx = document.getElementById('Canvas').getContext('2d')
       function circle(cx,cy,r,opt){
         ctx.beginPath();
         for(var x in opt){
           ctx[x] = opt[x];
         }
         ctx.arc(cx,cy,r,0,2*Math.PI,true);
         ctx.fill();
         ctx.closePath();
       };

       circle(200,200,5,{
         fillStyle:"#999"
       });

       $({r:5}).animate({r:50},{
         duration:5000,
         step:function(r){
           circle(200,200,r,{
             fillStyle:"#999"
           });
         }
       });

jQuery的方式非常自然。完整的demo见 http://jsbin.com/uBOtUKa

KISSY的变通实现方式

       var ctx = document.getElementById('Canvas').getContext('2d')
       function circle(cx,cy,r,opt){
         ctx.beginPath();
         for(var x in opt){
           ctx[x] = opt[x];
         }
         ctx.arc(cx,cy,r,0,2*Math.PI,true);
         ctx.fill();
         ctx.closePath();
       };

       circle(200,200,5,{
         fillStyle:"#999"
       });

       KISSY.use("anim",function(S,Anim){
         //必须制指定一个DOM节点作为地一个参数
         var anim = new Anim(window.document.body,{
               zoom2:1 //这里必须指定一个属性,否则frame不会执行
             },{
               easing:"swing",
               duration:5,
               frame:function(fx){
                 var r = 5+fx.pos*(50-5);
                 circle(200,200,r);
               }
           });
         anim.run();

完整的demo见 http://jsbin.com/IPUviQU

KISSY Anim 第一个参数必须是Node节点,第二个参数还必须传一个不存在的css属性,否则动画会改变元素的css样式 ,并且每一帧还要用户手动计算渐变过程的插值:

               frame:function(fx){
                 var r = 5+fx.pos*(50-5);
                 circle(200,200,r);
               }

KISSY更加理想的实现方式(目前还不支持)

但是做简单修改即可,see #459

       var o = {r:1};
       var anim = new Anim(o,{
         r:100 
       },{
           easing:"swing",
           duration:.5,
           frame:function(anim,fx){
             var propname = fx.prop;// r
             var val = fx.val;// r value
             circle(100,100,val);
           }
         });
       anim.run();

YUI3的方式——求怎么实现?

       var ctx = document.getElementById('Canvas').getContext('2d')
       function circle(cx,cy,r,opt){
         ctx.beginPath();
         for(var x in opt){
           ctx[x] = opt[x];
         }
         ctx.arc(cx,cy,r,0,2*Math.PI,true);
         ctx.fill();
         ctx.closePath();
       };

       circle(200,200,5,{
         fillStyle:"#999"
       });

       YUI().use("anim",function(Y){
         var anim = new Y.Anim({
           node:window,
           from:{

           },
           to:{

           },
           duration:1
         });
         anim.on("tween",function(e){//这里怎么办???
           console.log(e);
           //console.log(this.get("from"));
         });
         anim.run();

谁来补充下 YUI3的实现 ? http://jsbin.com/iHUxoXi

@blueaqua2000
Copy link

kissy gallery里有layer-anim组件,可以实现你的需求。
组件地址:http://gallery.kissyui.com/layer-anim/1.1/guide/index.html

   var ctx = document.getElementById('Canvas').getContext('2d');
   function circle(cx,cy,r,opt){
     ctx.beginPath();
     for(var x in opt){
       ctx[x] = opt[x];
     }
     ctx.arc(cx,cy,r,0,2*Math.PI,true);
     ctx.fill();
     ctx.closePath();
   };

   circle(200,200,5,{
     fillStyle:"#999"
   });

   KISSY.use("gallery/layer-anim/1.1/",function(S, LayerAnim){
     var obj = {r: 5};
     var anim = new LayerAnim({
       node: obj,
       from:{
           r: 5
       },
       to:{
           r: 50
       },
       duration:1
     });
     anim.on("update",function(){
       circle(200,200,obj.r,{
         fillStyle:"#999"
       });
     });
     anim.run();

@jinwei233
Copy link
Contributor Author

对KISSY anim 模块做了少许更改,不用引入组件就可以实现这个功能了
#459

@yiminghe
Copy link
Member

@jinwei233
Copy link
Contributor Author

要实现自定义属性的渐变,要属jQuery的API最精简了,但是$内部做了太多的重载。对KISSY未必合适。

但是,KISSY也可以继续做一些API上的精简或者语法糖,比如

方式一

KISSY.use("anim",function(S,Anim){
  S({r:5}).animate({r:50},{
     frame:function(fx){
       circle(200,200,fx.val,{
         fillStyle:"#999"
       });    
     }
  });
})

或者 方式二

KISSY.use("anim,Node",function(S,Anim,Node){
  S.one({r:5}).animate({r:50},{
     frame:function(fx){
       circle(200,200,fx.val,{
         fillStyle:"#999"
       });    
     }
  });
})

方式一 太jQuery了,把S当成万能的$了,也不符合KISSY的API设计。

方式二 也可能不太符合语义,S.one 应该是根据选择器获取一个Node,但是S.one现在本身也是可以传入window的,已经走出了一步了,所以再往前走一步,可以传入Object,也勉强说的过去。毕竟,对于很多jQuery过来的人,可能真的就把S.one/all返回的Node当成$在用了。经常能看到这样的代码:

KISSY.use("node",function(S){
  var $ = S.all;

  // $就是jQuery啦!
});

所以,我是倾向于 方式二 的.

@jinwei233
Copy link
Contributor Author

除了上面的canvas 圆圈画的例子,再贴一个文字长度变化的应用场景:

http://jsbin.com/OsUQuD/2/

同时很好奇YUI3怎么实现?

@jinwei233
Copy link
Contributor Author

要是github也有@功能就太好了,已经在weibo上邀请了美团网的panweizeng来解答这个问题。坐等。

@shepherdwind
Copy link

@WeweTom github本来就有@功能的,@panweizeng

yiminghe pushed a commit to yiminghe/kissy that referenced this issue Sep 3, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants