资讯专栏INFORMATION COLUMN

avalon js+css3实现roundabout 图片轮播

AlphaGooo / 575人阅读

摘要:效果效果就像优酷综艺频道页面的图片轮播。本屌之前做过这个参见仿优酷频道首页的图片切换效果不过用的是类似的库做的。

roundabout效果

效果就像优酷综艺频道页面的图片轮播。
本屌之前做过这个roundabout,参见仿优酷频道首页的图片切换效果,不过用的是类似jquery的库做的。尽管js代码不到200行,但还是显得有点复杂。于是乎,本屌盘算着可不可以用更少的代码完成这个效果。
顺便说一下,如果有读者想造轮子,可以直接看优酷的js代码,基本上都没压缩,封装这个效果的代码在posterTvGrid.js
下面是本屌做出来的效果
http://v.youku.com/v_show/id_XMTM1ODk4NDQyNA==.html

要求

点击左右箭头,图片滚动

点击下面图片索引,如果点击的图片是当前图片或与当前图片相邻的图片,则图片滚动;否则,所有图片先变小,然后点击的图片和与之相邻的图片,在相应位置动态变大。

代码尽可能少,尽可能清晰

布局
    

图片的位置有2种情况:

不可见,即不是前面的3张图片,这里类名.hide

.hide {
  width: 530px;
  height: 100px;
  opacity: 0;
  z-index: 0;
  margin-top: 0;
  left: -530px;
}

可见的3张图片,按位置具体可分为.left,.middle,.right

.middle {
  width: 640px;
  height: 270px;
  opacity: 1;
  z-index: 2;
  margin-top: 0;
  left: 275px;
}
.left {
  width: 530px;
  height: 224px;
  opacity: 0.4;
  z-index: 1;
  margin-top: 23px;
  left: 0;
}
.right {
  width: 530px;
  height: 224px;
  opacity: 0.4;
  z-index: 1;
  margin-top: 23px;
  left: 660px;
}

每个类的6个属性都是和图片尺寸(640*270)配合好的,使得动画很自然。当然后面会用到css3 animation,使每张图片的这6个属性进行相应的变化。
下面把上面类添加到相应图片上

    var roundabout=avalon.define({
        $id:"roundabout",
        img_list:[],
        cur:0,//当前页
        ...
    });

cur相对于指针,表示当前中间(可见范围最大)图片是图片列表里的哪张图片,所以会有(从左向右看)

cur=>.middle

cur+1=>.right

cur-1=>.left

其他=>.hide

插值表达式中的逻辑运算符

这里就要把逻辑运算符用到插值表达式里

解释下
ms-class-middle="$index==cur"
这个很简单,指针的当前位置,添加.middle.

ms-class-left="$index==cur-1||(cur==0&&$index==img_list.size()-1)"
后面部分表示,如果指针在第一张图片那里,就在最后一张图片上添加.left.

ms-class-right="$index==cur+1||(cur==img_list.size()-1&&$index==0)"
和上面类似,后面部分表示,如果指针在最后一张图片那里,就在第一张图片上添加.right.

ms-class-hide="($indexcur+1&&(cur!=0||$index!=img_list.size()-1))"
由两个大或(||)组成

前面部分$index表示在cur-1(左边的可见)图片以左的图片,都会添加.hide隐藏,除开一种情况,当前指针在最后一张图片那里时,图片列表中的第一张图片不能添加.hide,因为它将被添加.right.

这里利用了||运算符的特点,如果第一个条件满足的话,就不会去判定第二个条件;第一个条件不满足时,才会去判定第二个条件。

后面部分$index>cur+1&&(cur!=0||$index!=img_list.size()-1)表示在cur+1(右边的可见)图片以右的图片,都会添加.hide隐藏,除了当前指针在第一张图片那里时,图片列表中的最后一张图片不能添加.hide,因为它将被添加.left.

实际上,用离散数学里的非(p且q)=非p或非q就很好想了,除开已经添加了.left,.middle,.right的图片,剩下的就得添加.hide,$index>cur+1$index可以保证$index!=cur.

然后是排除.left,满足.left的条件是$index==cur-1||(cur==0&&$index==img_list.size()-1),它的否定是$index!=cur-1&&(cur!=0||$index!=img_list.size()-1),这就和添加.hide的条件的左边部分一样了。

排除.right也是类似的。

把这两个部分组合起来就可以保证.left,.middle,.right,.hide这4个类之间是互斥的

当然也可以利用css优先级,让.left,.middle,.right类的优先级高于.hide,这样添加.hide的判定条件会简单很多。为了严谨些,就没有用这种方式。

圆点序列
        

cur==$index让"亮"的圆点和当前指针同步。
到这里,任意改变roundabout.cur=?都可以呈现roundabout布局。

图片滚动 定义css3 animation

滚动过程中,要滚动图片有4种动画状态,以向右滚动为例

左边可见的图片的上(左)一张图片,不可见=>在可见部分左边,部分可见

原来左边可见的图片,在可见部分左边,部分可见=>中间,全部可见

原来中间全部可见的图片,中间,全部可见=>在可见部分右边,部分可见

原来右边可见的图片,在可见部分右边,部分可见=>不可见
这里用css3 animation

@keyframes to-right1 {//向右滚动
  0% {
    width: 530px;
    height: 100px;
    opacity: 0;
    z-index: 0;
    margin-top: 85px;
    left: -530px;
  }
  100% {
    width: 530px;
    height: 224px;
    opacity: 0.4;
    z-index: 1;
    margin-top: 23px;
    left: 0;
  }
}
@keyframes to-right2 {
  0% {
    width: 530px;
    height: 224px;
    opacity: 0.4;
    z-index: 1;
    margin-top: 23px;
    left: 0;
  }
  100% {
    width: 640px;
    height: 270px;
    opacity: 1;
    z-index: 2;
    margin-top: 0;
    left: 275px;
  }
}
@keyframes to-right3 {
  0% {
    width: 640px;
    height: 270px;
    opacity: 1;
    z-index: 2;
    margin-top: 0;
    left: 275px;
  }
  100% {
    width: 530px;
    height: 224px;
    opacity: 0.4;
    z-index: 1;
    margin-top: 23px;
    left: 660px;
  }
}
@keyframes to-right4 {
  0% {
    width: 530px;
    height: 224px;
    opacity: 0.4;
    z-index: 1;
    margin-top: 23px;
    left: 660px;
  }
  100% {
    width: 530px;
    height: 100px;
    opacity: 0;
    z-index: 0;
    margin-top: 85px;
    left: 1190px;
  }
}
...

可以看到,动画无非是在.hide,.left,.middle,.right这4个状态间切换。

@keyframes to-right1 {//向右滚动
    0% {
      //.hide
    }
    100% {
      //.left
    }
}
@keyframes to-right2{
    0% {
        //.left
    }
    100% {  
        //.middle
    }
}
@keyframes to-right3{
    0% {
        //middle
    }
    100% {  
        //right
    }
}
@keyframes to-right4{
    0% {
        //right
    }
    100% {  
        //hide1
    }
}
...

为了方便编码,用less

.state(@width,@height,@opacity,@z-index,@margin-top,@left){
    width: @width;
    height: @height;
    opacity: @opacity;
    z-index: @z-index;
    margin-top: @margin-top;
    left:@left;
}
.middle(){
    .state(640px,270px,1,2,0,275px);
}
.left(){
    .state(530px,224px,0.4,1,23px,0);
}
.right(){
    .state(530px,224px,0.4,1,23px,660px);
}
.hide(){
    .state(530px,100px,0,0,85px,-530px);
}
.hide1(){
    .state(530px,100px,0,0,85px,1190px);
}
.middle{
    .middle();
}
.left{
    .left();
}
.right{
    .right();
}
.hide{
    .hide();
}
@keyframes to-right1{//向右滚动
    0% {
        .hide();
    }
    100% {  
        .left();
    }
}
@keyframes to-right2{
    0% {
        .left();
    }
    100% {  
        .middle();
    }
}
@keyframes to-right3{
    0% {
        .middle();
    }
    100% {  
        .right();
    }
}
@keyframes to-right4{
    0% {
        .right();
    }
    100% {  
        .hide1();
    }
}
...
点击左右箭头,图片滚动
    var roundabout=avalon.define({
        $id:"roundabout",
        img_list:[],
        cur:0,//当前页
        jump:function(i,dir){//dir:滚动方向
            roundabout.cur=i;
        }
    });
    
...

jump方法的dir参数后面会用到。
这里还没有添加动画类,只能进行没有动画的滚动。

添加动画
//所有的动画类
var animate_class="to-right1 to-right2 to-right3 to-right4 to-left1 to-left2 to-left3 to-left4";
...
jump:function(i,dir){
    if(dir==1){//向右滚 cur-1
        avalon($("img"+prev(i))).removeClass(animate_class).addClass("to-right1");
        avalon($("img"+i)).removeClass(animate_class).addClass("to-right2");
        avalon($("img"+next(i))).removeClass(animate_class).addClass("to-right3");
        avalon($("img"+next(next(i)))).removeClass(animate_class).addClass("to-right4");
    }else{//向左滚 cur+1
        avalon($("img"+next(i))).removeClass(animate_class).addClass("to-left1");
        avalon($("img"+i)).removeClass(animate_class).addClass("to-left2");
        avalon($("img"+prev(i))).removeClass(animate_class).addClass("to-left3");
        avalon($("img"+prev(prev(i)))).removeClass(animate_class).addClass("to-left4");
    }
    roundabout.cur=i;
}
...
function prev(now){//上一页
    return now==0?roundabout.img_list.size()-1:now-1;
}
function next(now){//下一页
    return now==roundabout.img_list.size()-1?0:now+1;
}

几点说明

这里的removeClass方法和jquery中的一样,当传入参数像上面animate_class变量,多个类以空格分开时,对目标删除多个类(如果有的话)。

prev,next方法用来得到上一张图片和下一张图片的在图片列表中的索引.注意next(next(i))不等于next(i+1).

添加动画类之前,要先删除所有可能存在的动画类。

点击圆点,图片滚动

和点击左右箭头,图片滚动的动画不一样,这里对目标图片及其左右图片是一个从小变大的动画效果。

.state(@width,@height,@opacity,@z-index,@margin-top,@left){
    width: @width;
    height: @height;
    opacity: @opacity;
    z-index: @z-index;
    margin-top: @margin-top;
    left:@left;
}
.jump-state(){
    .state(0,0,0,0,135px,585px);
}
@keyframes jump-prev{//变小->左边图片
    0% {
        .jump-state();
    }
    100% {  
        .left();
    }
}
@keyframes jump-middle{//变小->中间图片
    0% {
        .jump-state();
    }
    100% {  
        .middle();
    }
}
@keyframes jump-next{//变小->右边图片
    0% {
        .jump-state();
    }
    100% {  
        .right();
    }
}

下面对圆点绑定点击事件

spec_jump:function(i){
    var cur=roundabout.cur;
    if(cur-prev(i)==0||cur-next(i)==0){//如果点击的图片是当前图片或当前图片的相邻图片
        var dir=1;//确定滚动方向
        if(cur-prev(i)==0)
            dir=2;
        roundabout.jump(i,dir);
    }else{
        roundabout.cur=i;
        avalon($("img"+prev(i))).removeClass(animate_class).addClass("jump-prev");
        avalon($("img"+i)).removeClass(animate_class).addClass("jump-middle");
        avalon($("img"+next(i))).removeClass(animate_class).addClass("jump-next");
    }
}

这里会添加jump-prev,jump-middle,jump-next类,所以前面的animate_class变量也要加上这3个类。

后记

js代码不超过50行,当然css代码多点,不过用less写的话,编程体验很好

下载

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/111169.html

相关文章

  • avalon js+css3实现roundabout 图片轮播

    摘要:效果效果就像优酷综艺频道页面的图片轮播。本屌之前做过这个参见仿优酷频道首页的图片切换效果不过用的是类似的库做的。 roundabout效果 效果就像优酷综艺频道页面的图片轮播。本屌之前做过这个roundabout,参见仿优酷频道首页的图片切换效果,不过用的是类似jquery的库做的。尽管js代码不到200行,但还是显得有点复杂。于是乎,本屌盘算着可不可以用更少的代码完成这个效果。顺便说...

    Awbeci 评论0 收藏0
  • 基于CSS3实现淡入(fadeIn)淡出(fadeOut)效果

    摘要:网上的淡入淡出效果大多是依照中和的方法使用来控制元素的透明度达到目的,但缺点是有轻微的卡顿感,并且运行效率一般。思路是将淡入,淡出的效果做成预先定义好的样式类,然后用改变元素的类来达到图片轮播。 网上的淡入淡出效果大多是依照jquery中fadeIn和fadeOut的方法使用js来控制元素的透明度达到目的,但缺点是有轻微的卡顿感,并且运行效率一般。 这里提供另外一个思路,即通过预先定义...

    XUI 评论0 收藏0
  • CSS3 transition属性实现淡入淡出轮播

    摘要:最近想自己写下轮播图,在网上发现一个网友用属性实现的轮播,赶脚超简单哦,自己学习了后整理如下。如果我们用给加上类,的就要变成对吧,由于有属性,所以要等,才能完全变为,实现了淡入。最近想自己写下轮播图,在网上发现一个网友用CSS transition属性实现的轮播,赶脚超简单哦,自己学习了后整理如下。(找不到原网址了-.-...就不贴了...)(如果不了解transition,先去这里(点我,...

    Heier 评论0 收藏0
  • 小小幻灯片

    摘要:上一篇说了瀑布流,今天说一下小小幻灯片的故事。幻灯片学名又叫轮播。轮播原理这里先说一下基本原理吧,就是将图片向左或向右移,然后接着显示下一张,或者上一张。这里需要感谢一下爱编程提供的图片接着重头戏就是。用来标识当前的元素的序号。 上一篇说了瀑布流,今天说一下小小幻灯片的故事。 幻灯片学名又叫 轮播。应该算是一种最常用的页面展示信息。以前由于ie6/7的拖累,导致我们只能使用,很古老的方...

    anonymoussf 评论0 收藏0
  • 面试官(6): 写过『通用前端组件』吗?

    摘要:很久没上掘金发现草稿箱里存了好几篇没发的文章最近梳理下发出来往期面试官系列如何实现深克隆面试官系列的实现面试官系列前端路由的实现面试官系列基于数据劫持的双向绑定优势所在面试官系列你为什么使用前端框架前言设计前端组件是最能考验开发者基本功的测 很久没上掘金,发现草稿箱里存了好几篇没发的文章,最近梳理下发出来 往期 面试官系列(1): 如何实现深克隆 面试官系列(2): Event Bus...

    waltr 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<