商品飞向购物车的动画

  1 <!DOCTYPE html>
  2 <html lang="zh-cmn-Hans">
  3 <head>
  4     <meta charset="UTF-8">
  5     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  6     <link rel="stylesheet" href="css/style.css">
  7     <title>购物车动画</title>
  8     <style>
  9         html,body {
 10             margin: 0;
 11             padding: 0;
 12             background-color: rgba(0, 0, 0, .5);
 13             -webkit-user-select: none;
 14             width: 100%;
 15             height: 100%;
 16         }
 17 
 18         .wrapper {
 19             width: 100%;
 20             height: 100%;
 21             background:#fff;
 22             position: relative;
 23         }
 24         .parabola-animation {
 25             width: 100%;
 26         }
 27 
 28         .parabola-box-hor {
 29             position: fixed;
 30             z-index: 99;
 31             top: 0;
 32             left: 0;
 33             -webkit-animation: parabola-hor-animation 1s ease-out 1;
 34             animation: parabola-hor-animation 1s ease-out 1;
 35         }
 36 
 37         .parabola-box-hor.top {
 38             -webkit-animation-timing-function: ease-in;
 39             animation-timing-function: ease-in;
 40         }
 41 
 42         .parabola-box-ver {
 43             position: fixed;
 44             top: 50px;
 45             left: 20px;
 46             overflow: hidden;
 47             width: 35px;
 48             height: 35px;
 49             -webkit-animation: parabola-ver-animation 1s ease-in 1;
 50             animation: parabola-ver-animation 1s ease-in 1;
 51             border-radius: 50%;
 52         }
 53 
 54         .parabola-box-ver.top {
 55             -webkit-animation-timing-function: ease-out;
 56             animation-timing-function: ease-out;
 57         }
 58 
 59         .parabola-box-ver > img {
 60             width: 100%;
 61             height: 100%;
 62             vertical-align: middle;
 63         }
 64 
 65     </style>
 66 </head>
 67 <body>
 68 <div class="wrapper">
 69     <div class="top"  title="开始位置"  style="width:30px;height:30px;background:yellow; position:absolute;left:100px;top:0;"></div>
 70     <div class="bottom"   title="结束位置"  style="width:30px;height:30px;background:green;position:absolute;right:0;bottom:200px;"></div>
 71 </div>
 72 <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
 73 </body>
 74 </html>
 75 
 76 <script>
 77     var addCar = function(opt) {
 78         return (function() {
 79             var parabola = function(opt) {
 80                 this.init(opt);
 81             };
 82             parabola.prototype = {//原型,给原型添加方法:1.计算值;2.dom元素;3.坐标值;
 83                 init: function(opt) {
 84                     var flyO = this.calculatedValue(opt),
 85                         flyDom = this.creatHtml(flyO.site, flyO.img ,flyO.callback),
 86                         flyRule = this.creatRule(flyO.coord);
 87 
 88                     document.getElementsByTagName('head')[0].appendChild(flyRule);
 89                     document.body.appendChild(flyDom);
 90                 },
 91                 creatRule: function(coord) {
 92                     var cssAnimation = document.createElement('style');
 93                     cssAnimation.type = "text/css";
 94                     var rules = "\
 95                         @-webkit-keyframes parabola-hor-animation{\
 96                             0%{\
 97                                 -webkit-transform: translate(0px, 0px);\
 98                                         transform: translate(0px, 0px);\
 99                             }\
100                             10%{\
101                                 -webkit-transform: translate(0px, 0px);\
102                                         transform: translate(0px, 0px);\
103                             }\
104                             100%{\
105                                 -webkit-transform: translate(" + coord.x + "px, 0px);\
106                                         transform: translate(" + coord.x + "px, 0px);\
107                             }\
108                         }\
109                         @keyframes parabola-hor-animation{\
110                             0%{\
111                                 -webkit-transform: translate(0px, 0px);\
112                                         transform: translate(0px, 0px);\
113                             }\
114                             10%{\
115                                 -webkit-transform: translate(0px, 0px);\
116                                         transform: translate(0px, 0px);\
117                             }\
118                             100%{\
119                                 -webkit-transform: translate(" + coord.x + "px, 0px);\
120                                         transform: translate(" + coord.x + "px, 0px);\
121                             }\
122                         }\
123                         @-webkit-keyframes parabola-ver-animation{\
124                             0%{\
125                                 -webkit-transform: translate(0px, 0px);\
126                                         transform: translate(0px, 0px);\
127                             }\
128                             10%{\
129                                 -webkit-transform: translate(0px, " + coord.os + "px);\
130                                         transform: translate(0px, " + coord.os + "px);\
131                             }\
132                             100%{\
133                                 -webkit-transform: translate(0px," + coord.y + "px);\
134                                         transform: translate(0px," + coord.y + "px);\
135                             }\
136                         }\
137                         @keyframes parabola-ver-animation{\
138                             0%{\
139                                 -webkit-transform: translate(0px, 0px);\
140                                         transform: translate(0px, 0px);\
141                             }\
142                             10%{\
143                                 -webkit-transform: translate(0px, " + coord.os + "px);\
144                                         transform: translate(0px, " + coord.os + "px);\
145                             }\
146                             100%{\
147                                 -webkit-transform: translate(0px," + coord.y + "px);\
148                                         transform: translate(0px," + coord.y + "px);\
149                             }\
150                         }\
151                     ";
152                     cssAnimation.innerHTML = rules;
153                     return cssAnimation;
154                 },
155                 creatHtml: function(site, img ,callback) {
156                     var imgHtml = img == '' ? '' : '<img src="' + img + '">';
157 
158                     var html = '<div class="parabola-box-hor">\
159                                 <div class="parabola-box-ver">\
160                                     ' + imgHtml + '\
161                                 </div>\
162                             </div>';
163 
164                     var parentBox = document.createElement('div');
165                     parentBox.innerHTML = html;
166                     parentBox.setAttribute('class', 'parabola-animation');
167 
168                     $(parentBox).on('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', '.parabola-box-ver', function() {
169                         var _pfly = $(parentBox);
170                         if (_pfly.length) _pfly.remove();
171                         callback();
172                     });
173                     var frag = document.createDocumentFragment();
174                     frag.appendChild(parentBox);
175 
176                     var verBox = frag.querySelector('.parabola-box-ver'),
177                         horBpx = frag.querySelector('.parabola-box-hor');
178                     verBox.style.left = site.left + 'px';
179                     verBox.style.top = site.top + 'px';
180 
181                     if (site.cubic) {
182                         verBox.setAttribute("class", 'parabola-box-ver top');
183                         horBpx.setAttribute("class", 'parabola-box-hor top');
184                     }
185                     return frag;
186                 },
187                 calculatedValue: function(opt) {
188                     var fly = {
189                             begin: '',
190                             end: '',
191                             img: '',
192                             callback: function() {
193                                 console.log('动画完成');
194                             }
195                         },
196                         vData = {
197                             site: {
198                                 left: 0,
199                                 top: 0,
200                                 cubic: false
201                             },
202                             img: '',
203                             coord: {
204                                 x: 0,
205                                 y: 0,
206                                 os: 0
207                             },
208                             callback: function() {}
209                         },
210                         _this = this;
211 
212                     if (typeof opt == 'object') {
213                         fly = $.extend(true, fly, opt);
214                     }
215 
216                     //如果没有这两个元素中的其中一个则终止
217                     if (!fly.begin.length || !fly.end.length) return vData;
218                     /**
219                      * beginCrood 获取开始元素的位置
220                      * endCrood   获取结束元素的位置
221                      */
222                     var beginCrood = fly.begin[0].getBoundingClientRect(),
223                         endCrood = fly.end[0].getBoundingClientRect();
224 
225                     /*!
226                      *  购物车动画出现的位置
227                      *  left: 开始元素的left+width/2
228                      *  top: 开始元素的top
229                      *  购物车动画结束的位置
230                      *  x: 结束元素的left+width/2 再减去购物车动画出现的位置的left
231                      *  y: 结束元素的top+height/2 再减去购物车动画出现的位置的top
232                      */
233                     /**
234                      * 全部减去 18是因为购物车宽度和高度都是35px;一半难得算(-_-),就填18
235                      */
236                     vData.site.left = beginCrood.left + parseInt(beginCrood.width / 2, 10) - 18;
237                     vData.site.top = beginCrood.top - 18;
238                     vData.coord.x = endCrood.left + parseInt(endCrood.width / 2, 10) - vData.site.left - 18;
239                     vData.coord.y = endCrood.top + parseInt(endCrood.height / 2, 10) - vData.site.top - 18;
240                     vData.coord.os = -50;
241                     vData.img = fly.img;
242                     vData.callback = fly.callback;
243                     if (beginCrood.top > endCrood.top) vData.site.cubic = true;
244 
245                     return vData;
246                 }
247             }
248             return new parabola(opt);
249         })();
250     }
251     var addCar = function(opt) {
252         return (function() {
253             var parabola = function(opt) {
254                 this.init(opt);
255             };
256             parabola.prototype = {//原型,给原型添加方法:1.计算值;2.dom元素;3.坐标值;
257                 init: function(opt) {
258                     var flyO = this.calculatedValue(opt),
259                         flyDom = this.creatHtml(flyO.site, flyO.img ,flyO.callback),
260                         flyRule = this.creatRule(flyO.coord);
261 
262                     document.getElementsByTagName('head')[0].appendChild(flyRule);
263                     document.body.appendChild(flyDom);
264                 },
265                 creatRule: function(coord) {
266                     var cssAnimation = document.createElement('style');
267                     cssAnimation.type = "text/css";
268                     var rules = "\
269                         @-webkit-keyframes parabola-hor-animation{\
270                             0%{\
271                                 -webkit-transform: translate(0px, 0px);\
272                                         transform: translate(0px, 0px);\
273                             }\
274                             10%{\
275                                 -webkit-transform: translate(0px, 0px);\
276                                         transform: translate(0px, 0px);\
277                             }\
278                             100%{\
279                                 -webkit-transform: translate(" + coord.x + "px, 0px);\
280                                         transform: translate(" + coord.x + "px, 0px);\
281                             }\
282                         }\
283                         @keyframes parabola-hor-animation{\
284                             0%{\
285                                 -webkit-transform: translate(0px, 0px);\
286                                         transform: translate(0px, 0px);\
287                             }\
288                             10%{\
289                                 -webkit-transform: translate(0px, 0px);\
290                                         transform: translate(0px, 0px);\
291                             }\
292                             100%{\
293                                 -webkit-transform: translate(" + coord.x + "px, 0px);\
294                                         transform: translate(" + coord.x + "px, 0px);\
295                             }\
296                         }\
297                         @-webkit-keyframes parabola-ver-animation{\
298                             0%{\
299                                 -webkit-transform: translate(0px, 0px);\
300                                         transform: translate(0px, 0px);\
301                             }\
302                             10%{\
303                                 -webkit-transform: translate(0px, " + coord.os + "px);\
304                                         transform: translate(0px, " + coord.os + "px);\
305                             }\
306                             100%{\
307                                 -webkit-transform: translate(0px," + coord.y + "px);\
308                                         transform: translate(0px," + coord.y + "px);\
309                             }\
310                         }\
311                         @keyframes parabola-ver-animation{\
312                             0%{\
313                                 -webkit-transform: translate(0px, 0px);\
314                                         transform: translate(0px, 0px);\
315                             }\
316                             10%{\
317                                 -webkit-transform: translate(0px, " + coord.os + "px);\
318                                         transform: translate(0px, " + coord.os + "px);\
319                             }\
320                             100%{\
321                                 -webkit-transform: translate(0px," + coord.y + "px);\
322                                         transform: translate(0px," + coord.y + "px);\
323                             }\
324                         }\
325                     ";
326                     cssAnimation.innerHTML = rules;
327                     return cssAnimation;
328                 },
329                 creatHtml: function(site, img ,callback) {
330                     var imgHtml = img == '' ? '' : '<img src="' + img + '">';
331 
332                     var html = '<div class="parabola-box-hor">\
333                                 <div class="parabola-box-ver">\
334                                     ' + imgHtml + '\
335                                 </div>\
336                             </div>';
337 
338                     var parentBox = document.createElement('div');
339                     parentBox.innerHTML = html;
340                     parentBox.setAttribute('class', 'parabola-animation');
341 
342                     $(parentBox).on('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', '.parabola-box-ver', function() {
343                         var _pfly = $(parentBox);
344                         if (_pfly.length) _pfly.remove();
345                         callback();
346                     });
347                     var frag = document.createDocumentFragment();
348                     frag.appendChild(parentBox);
349 
350                     var verBox = frag.querySelector('.parabola-box-ver'),
351                         horBpx = frag.querySelector('.parabola-box-hor');
352                     verBox.style.left = site.left + 'px';
353                     verBox.style.top = site.top + 'px';
354 
355                     if (site.cubic) {
356                         verBox.setAttribute("class", 'parabola-box-ver top');
357                         horBpx.setAttribute("class", 'parabola-box-hor top');
358                     }
359                     return frag;
360                 },
361                 calculatedValue: function(opt) {
362                     var fly = {
363                             begin: '',
364                             end: '',
365                             img: '',
366                             callback: function() {
367                                 console.log('动画完成');
368                             }
369                         },
370                         vData = {
371                             site: {
372                                 left: 0,
373                                 top: 0,
374                                 cubic: false
375                             },
376                             img: '',
377                             coord: {
378                                 x: 0,
379                                 y: 0,
380                                 os: 0
381                             },
382                             callback: function() {}
383                         },
384                         _this = this;
385 
386                     if (typeof opt == 'object') {
387                         fly = $.extend(true, fly, opt);
388                     }
389 
390                     //如果没有这两个元素中的其中一个则终止
391                     if (!fly.begin.length || !fly.end.length) return vData;
392                     /**
393                      * beginCrood 获取开始元素的位置
394                      * endCrood   获取结束元素的位置
395                      */
396                     var beginCrood = fly.begin[0].getBoundingClientRect(),
397                         endCrood = fly.end[0].getBoundingClientRect();
398 
399                     /*!
400                      *  购物车动画出现的位置
401                      *  left: 开始元素的left+width/2
402                      *  top: 开始元素的top
403                      *  购物车动画结束的位置
404                      *  x: 结束元素的left+width/2 再减去购物车动画出现的位置的left
405                      *  y: 结束元素的top+height/2 再减去购物车动画出现的位置的top
406                      */
407                     /**
408                      * 全部减去 18是因为购物车宽度和高度都是35px;一半难得算(-_-),就填18
409                      */
410                     vData.site.left = beginCrood.left + parseInt(beginCrood.width / 2, 10) - 18;
411                     vData.site.top = beginCrood.top - 18;
412                     vData.coord.x = endCrood.left + parseInt(endCrood.width / 2, 10) - vData.site.left - 18;
413                     vData.coord.y = endCrood.top + parseInt(endCrood.height / 2, 10) - vData.site.top - 18;
414                     vData.coord.os = -50;
415                     vData.img = fly.img;
416                     vData.callback = fly.callback;
417                     if (beginCrood.top > endCrood.top) vData.site.cubic = true;
418 
419                     return vData;
420                 }
421             }
422             return new parabola(opt);
423         })();
424     }
425 
426 </script>
427 
428 <script>
429     $('body').on('click', '.top', function() {
430         addCar({
431             begin: $('.top'),
432             end: $('.bottom'),
433             img: './img/logo.jpg',
434             callback: function() {
435                 console.log('动画完成');
436             }
437         })
438     });
439 </script>

 

posted @ 2018-08-07 15:25  前端极客  阅读(587)  评论(0编辑  收藏  举报