效果流--动态切换图片/内容栏

前言 : 有朋友看了我们的99分, 我处理的动画效果后觉得很赞, 想用于他们的平台上, 用来显示图片和内容. 然而我的那个平台整个就是一个canvas, 用于他的部分显然不适合.

 

但是用JQ 就能够很容易实现了. 只需要找到位置, 然后使用JQ的animate, 然后对他做一系列事件处理, 就ok了. 恩, 原理如此简单(当然做为dom 本来就没canvas 处理那么复杂, 虽然原理是差不多的, 但是canvas还有更多的绘制计算在内).

...

后来一想, 太不负责了, 就这样告诉人家, 其实做为DEMO 可以, 做为产品, 这就是大大的不妥了. 怎么填充数据? 怎么切换数据? 都木有哇.

所以经我这样一想, 这玩意立马就复杂了. 于是就有了这样一个相对折腾的东西, 一个封装好了的组件

不多说, 看代码 (他需要引用jq)

  1 <!doctype html>
  2 <html>
  3     <head>
  4         <title>move</title>
  5         <meta charset="utf-8" />
  6         <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
  7     </head>
  8     <body>
  9         <div id="page">
 10             <div id="header" class="header">
 11                 <div class="w800 center">
 12                 </div>
 13             </div>
 14             <div id="content" class="content w800 center">
 15                 我自己本身的是用canvas的, 所以写的算法是自己的, 这里如果仅仅是dom的话, 我们可以简单的用jq来实现. <br />
 16                 这里我实现了一个可以拓展的框架, 应该对你可以用有. 他可以适合很多应用和变化的场景. 包括修改等.
 17                 <br />
 18                 <style>
 19                 .show-0{width:350px;height:250px;border:1px red solid;position:relative;}
 20                 .show-0 .s1{position:absolute;width:70px;height:110px;border:1px red solid;background:#fff;}    
 21                 </style>
 22                 <div id="test" class="show-0">
 23                     <div class="s1">&nbsp;0-1</div>
 24                     <div class="s1">&nbsp;0-2</div>
 25                     <div class="s1">&nbsp;0-3</div>
 26                     <div class="s1">&nbsp;0-4</div>
 27                     <div class="s1">&nbsp;0-5</div>
 28                     <div class="s1">&nbsp;0-6</div>
 29                     <div class="s1">&nbsp;0-7</div>
 30                     <div class="s1">&nbsp;0-8</div>
 31                     <div class="s1">&nbsp;1-1</div>
 32                     <div class="s1">&nbsp;1-2</div>
 33                     <div class="s1">&nbsp;1-3</div>
 34                     <div class="s1">&nbsp;1-4</div>
 35                     <div class="s1">&nbsp;1-5</div>
 36                     <div class="s1">&nbsp;1-6</div>
 37                     <div class="s1">&nbsp;1-7</div>
 38                     <div class="s1">&nbsp;1-8</div>
 39                     <div class="s1">&nbsp;2-1</div>
 40                     <div class="s1">&nbsp;2-2</div>
 41                     <div class="s1">&nbsp;2-3</div>
 42                     <div class="s1">&nbsp;2-4</div>
 43                     <div class="s1">&nbsp;2-5</div>
 44                     <div class="s1">&nbsp;2-6</div>
 45                     <div class="s1">&nbsp;2-7</div>
 46                     <div class="s1">&nbsp;2-8</div>
 47                 </div>
 48             </div>
 49         </div>
 50         <script type="text/javascript">
 51          (function(){
 52              /*
 53               * author : hehe123 (Jerrod.zhou)
 54               * mail : mag.zhoujie@gmail.com
 55               */
 56              var plugin_divMoive = {
 57                  methods: {
 58                      nextShow: function(elms, data, callback, n){
 59                          var rec, i = 0, len = elms.length;
 60                          rec = setInterval(function(){
 61                              elms[i].show().animate({
 62                                  left: data.sidePos[i].l,
 63                                  top: data.sidePos[i].t,
 64                                  opacity: 1
 65                              }, 300);
 66                              (n && i === n && callback) && callback();
 67                              i++;
 68                              if (i >= len) {
 69                                  clearInterval(rec);
 70                                  (!n && callback) && callback();
 71                              }
 72                          }, 150);
 73                      },
 74                      prevHide: function(elms, data, callback, n){
 75                          var rec, i = 0, len = elms.length;
 76                          rec = setInterval(function(){
 77                              elms[i].show().animate({
 78                                  left: data.centerPos[0],
 79                                  top: data.centerPos[1],
 80                                  opacity: 0.5
 81                              }, 300, function(){
 82                                  $(this).hide();
 83                              });
 84                              (n && i === n && callback) && callback();
 85                              i++;
 86                              if (i >= len) {
 87                                  clearInterval(rec);
 88                                  (!n && callback) && callback();
 89                              }
 90                          }, 150);
 91                      },
 92                      run: function(){
 93                          var DM = plugin_divMoive, Mds = DM.methods;
 94                          return function(){
 95                              var P = this, status = P.status, elms = P.elms, data = P.data, childs = elms.childs, i = data.showClipFrameIdx, rec = data.rec, rTime = 0;
 96                              if (status.isMoving) {
 97                                  return;
 98                              }
 99                              status.isMoving = true;
100                             status.isOnParent = false;
101                             function mouseout(){
102                                 status.isMouseover = false;
103                                 status.isMouseout = true;
104                                 data.mouseOutRec = setTimeout(function(){
105                                     status.isMouseout && P.goon();
106                                     if(!status.isOnParent){
107                                         status.isOnParent = true;
108                                         P.onover && P.onover(P);
109                                     }
110                                 }, 1);
111                             }
112                             function mouseover(){
113                                 status.isMouseover = true;
114                                 status.isMouseout = false;
115                                 data.mouseOverRec = setTimeout(function(){
116                                     status.isMouseover && P.pause();
117                                     status.isOnParent = false;
118                                     P.onout && P.onout(P);
119                                 }, 1);
120                             }
121                             elms.parent.unbind('mouseover', mouseover).bind('mousemove', mouseover).unbind('mouseout', mouseout).bind('mouseout', mouseout)
122                              Mds.nextShow(data.showClipFrameArr[i], data, function(){
123                                  P.onshow && P.onshow(P);
124                              });
125                              data.rec = setInterval(function(){
126                                  if (status.isPause || status.isDeforming) {
127                                      return;
128                                  }
129                                  if ((rTime + 1) % P.time === 0) {
130                                      status.isDeforming = true;
131                                     i = data.showClipFrameIdx;
132                                      Mds.prevHide(data.showClipFrameArr[i], data, function(){
133                                          P.onhide && P.onhide(P);
134                                          i = i + 1 >= data.showClipFrameLength ? 0 : i + 1;
135                                          Mds.nextShow(data.showClipFrameArr[i], data, function(){
136                                              P.onshow && P.onshow(P);
137                                             data.showClipFrameIdx = i;
138                                              status.isDeforming = false;
139                                          });
140                                      }, 5);
141                                  }
142                                  rTime++;
143                                  rTime >= 1000 && (rTime = 0);
144                              }, 1000);
145                          };
146                      },
147                     switcher : function(){
148                         var DM = plugin_divMoive, Mds = DM.methods;
149                          return function(n){
150                             var P = this, status = P.status, elms = P.elms, data = P.data, childs = elms.childs, i = data.showClipFrameIdx;
151                             if(status.isDeforming){
152                                 return;
153                             }
154                             status.isPause = true;
155                             Mds.prevHide(data.showClipFrameArr[i], data, function(){
156                                  P.onhide && P.onhide(P);
157                                  i = i + 1 >= data.showClipFrameLength ? 0 : i + 1;
158                                  Mds.nextShow(data.showClipFrameArr[n], data, function(){
159                                      P.onshow && P.onshow(P);
160                                     data.showClipFrameIdx = n;
161                                      status.isDeforming = false;
162                                     status.isPause = false;
163                                  });
164                              }, 5);
165                         };
166                     },
167                      stop: function(){
168                          var DM = plugin_divMoive, Mds = DM.methods;
169                          return function(){
170                              var P = this, status = P.status, elms = P.elms, data = P.data, rec = data.rec;
171                              clearInterval(data.rec);
172                             status.isMoving = false;
173                          };
174                      },
175                     pause: function(){
176                         return function(callback){
177                             var P = this, status = P.status;
178                             status.isPause = true;
179                             callback && callback(P);
180                         }
181                     },
182                     goon: function(){
183                         return function(callback){
184                             var P = this, status = P.status;
185                             status.isPause = false;
186                             callback && callback(P);
187                         }
188                     }
189                 },    
190                  init: function(opts){
191                      var j = 0, z = 0, P = plugin_divMoive, methods = P.methods, data = new Object(), elms = {
192                          parent: opts.parent,
193                          childs: opts.childs
194                      }, run;
195                      data.sidePos = [];
196                      data.centerPos = [(opts.iWidth - opts.clipWidth) / 2, (opts.iHeight - opts.clipHeight) / 2];
197                      data.properties = {
198                          iWidth: opts.iWidth,
199                          iHeight: opts.iHeight,
200                          iPaddingTop: opts.iPaddingTop,
201                          iPaddingLeft: opts.iPaddingLeft,
202                          clipWidth: opts.clipWidth,
203                          clipHeight: opts.clipHeight,
204                          clipMarginRight: opts.clipMarginRight,
205                          clipMarginBottom: opts.clipMarginBottom,
206                          rows: opts.rows,
207                          cols: opts.cols,
208                          time: opts.time
209                      };
210                      data.showClipElmsNums = opts.rows * opts.cols;
211                      data.showClipFrameLength = Math.floor((opts.childs.length + 1) / data.showClipElmsNums);
212                      data.showClipFrameArr = function(){
213                          var arr = [], i = -1, len = data.showClipFrameLength - 1;
214                          for (; i++ < len; arr[i] = []);
215                          return arr;
216                      }();
217                      data.showClipFrameIdx = 0;
218                     opts.parent.css('position', 'relative');
219                      opts.childs.each(function(i){
220                          data.sidePos.push({
221                              i: i,
222                              w: opts.clipWidth,
223                              h: opts.clipHeight,
224                              l: opts.iPaddingLeft + (i % opts.cols) * (opts.clipWidth + opts.clipMarginRight),
225                              t: opts.iPaddingTop + j * (opts.clipHeight + opts.clipMarginBottom)
226                          });
227                          $(this).hide().css({
228                             position: 'absolute',
229                              left: data.centerPos[0],
230                              top: data.centerPos[1],
231                              opacity: 0.5
232                          });
233                          data.showClipFrameArr[z].push($(this));
234                          (i + 1) % data.showClipElmsNums === 0 && (z++);
235                          i % opts.cols === (opts.cols - 1) && (j++);
236                          j >= opts.rows && (j = 0);
237                      });
238                      return {
239                          status: {
240                              isMoving: false,
241                              isDeforming: false,
242                              isPause: false,
243                             isMouseover: false,
244                             isMouseout: true,
245                             isOnParent: false
246                          },
247                          elms: elms,
248                          data: data,
249                          time: opts.time,
250                          onshow: opts.onshow || null,
251                          onhide: opts.onhide || null,
252                          run: methods.run(),
253                          stop: methods.stop(),
254                         pause: methods.pause(),
255                         goon: methods.goon(),
256                         switcher: methods.switcher(),
257                         onover: opts.onmouseover || null,
258                         onout: opts.onmouseout || null
259                      };
260                  }
261              };
262              
263              var n0 = plugin_divMoive.init({
264                 parent : $('#test'),
265                 childs : $('#test > .s1'), 
266                 iWidth : $('#test').width(),
267                 iHeight : $('#test').height(),
268                 iPaddingTop : 10,
269                 iPaddingLeft : 10,
270                 clipWidth : $('#test > .s1').width(),
271                 clipHeight : $('#test > .s1').height(),
272                 clipMarginRight : 15,
273                 clipMarginBottom : 10,
274                 rows :  2,
275                 cols : 4,
276                 time : 4
277              });
278              n0.run();
279          })();
280         </script>  
281     </body>
282 </html>    

然后, 下面是该组件的一些说明:

 

/*
              * init 的必选:
              *     parent                : 父级框
              *     child                : 需要移动的子集
              *     iWidth                : 父级的宽
              *     iHeight                : 父级的高
              *     iPaddingTop            : 父级内上边距
              *     iPaddingLeft        : 父级内左边距
              *     clipWidth            : 子集个体宽
              *     clipHeight            : 子集个体高
              *     clipMarginRight        : 子集右边距
              *     clipMarginBottom    : 子集下边距
              *     rows                : 行数 (子集排成的行数)
              *     cols                : 列数 (子集排成的列数)
              *     time                : 停留时间
              *
              *     可选部分:
              *     onshow                : 每个集合显示完全后的 callback
              *                             如  onshow:function(O){ ....}
              *                             O 包含整个返回的object部分
              *        onhide                : 每个集合隐藏完全后的 callback
                                              用法如上.
                      onover                : 当鼠标停留在父级上的 callback. 用法如上
                      onout                : 当鼠标离开在父级上的 callback. 用法如上                        
              */
            
             /*
              * 返回的oject
              *     status                : 状态集合, 有
              *                         isMoving: 是否动画已经开始,
                                         isDeforming: 是否正在变形,
                                         isPause: 是否停顿,
                                        isMouseover: 是否鼠标父级上,
                                        isMouseout: 是否鼠标离开父级,
                                        isOnParent: 是否第一次鼠标在父级上
                                        
              *     elms                : 元素列表, 主要有两种
              *                         parent: 父级元素
                                         childs: 子级元素                        
              *     data                : 动态的记录数据
              *                         sidePos :    数组, 记录每次显示时的元素位置
              *                         centerPos : 数组, 记录中心点的位置数据
              *                         properties : 对象, 记录 init 的必须部分参数数据
              *                         showClipElmsNums: 记录每次显示的元素个数
              *                         showClipFrameLength: 记录总共分几页显示数据 (如,每页8个元素, 24个元素就3页)
              *                 **        showClipFrameArr: 每页的分类数组, 如果想修改某页某个元素, 就得依托他.
              *                         showClipFrameIdx: 当前显示到了第几页
              *                         rec : setInterval的句柄
              *     time                : 同init里的time. 停留时间. 也可以修改.
              *     onshow                : 同init里的onshow, 如果有, 则在该页子集显示时触发,
                     onhide                : 同init里的onhide, 如果有, 则在该页子集隐藏时触发,
                     run                    : 整个方法类的启动
                     stop                : 整个方法类的停止
                    pause                : 整个方法类的暂停 (在mouseover, mouseout 时也触发他)
                    goon                : 整个方法类的继续运行
                    switcher            : 从当前页跳到某一页
                    onover                : 同init里的onover, 如果有, 则在鼠标在父级上时触发,
                    onout                : 同init里的onout, 如果有, 则在鼠标离开父级上时触发
              */

 

因为有的pause, stop, goon, 也有了 onshow, onhide, 特别是 switcher (switcher可以帮你实现如果你想要用如