Guest User

deck.js

a guest
Apr 3rd, 2020
293
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. 'use strict';
  2.  
  3. var Deck = (function () {
  4.   'use strict';
  5.  
  6.   var ticking;
  7.   var animations = [];
  8.  
  9.   function animationFrames(delay, duration) {
  10.     var now = Date.now();
  11.  
  12.     // calculate animation start/end times
  13.     var start = now + delay;
  14.     var end = start + duration;
  15.  
  16.     var animation = {
  17.       start: start,
  18.       end: end
  19.     };
  20.  
  21.     // add animation
  22.     animations.push(animation);
  23.  
  24.     if (!ticking) {
  25.       // start ticking
  26.       ticking = true;
  27.       requestAnimationFrame(tick);
  28.     }
  29.     var self = {
  30.       start: function start(cb) {
  31.         // add start callback (just one)
  32.         animation.startcb = cb;
  33.         return self;
  34.       },
  35.       progress: function progress(cb) {
  36.         // add progress callback (just one)
  37.         animation.progresscb = cb;
  38.         return self;
  39.       },
  40.       end: function end(cb) {
  41.         // add end callback (just one)
  42.         animation.endcb = cb;
  43.         return self;
  44.       }
  45.     };
  46.     return self;
  47.   }
  48.  
  49.   function tick() {
  50.     var now = Date.now();
  51.  
  52.     if (!animations.length) {
  53.       // stop ticking
  54.       ticking = false;
  55.       return;
  56.     }
  57.  
  58.     for (var i = 0, animation; i < animations.length; i++) {
  59.       animation = animations[i];
  60.       if (now < animation.start) {
  61.         // animation not yet started..
  62.         continue;
  63.       }
  64.       if (!animation.started) {
  65.         // animation starts
  66.         animation.started = true;
  67.         animation.startcb && animation.startcb();
  68.       }
  69.       // animation progress
  70.       var t = (now - animation.start) / (animation.end - animation.start);
  71.       animation.progresscb && animation.progresscb(t < 1 ? t : 1);
  72.       if (now > animation.end) {
  73.         // animation ended
  74.         animation.endcb && animation.endcb();
  75.         animations.splice(i--, 1);
  76.         continue;
  77.       }
  78.     }
  79.     requestAnimationFrame(tick);
  80.   }
  81.  
  82.   // fallback
  83.   window.requestAnimationFrame || (window.requestAnimationFrame = function (cb) {
  84.     setTimeout(cb, 0);
  85.   });
  86.  
  87.   var style = document.createElement('p').style;
  88.   var memoized = {};
  89.  
  90.   function prefix(param) {
  91.     if (typeof memoized[param] !== 'undefined') {
  92.       return memoized[param];
  93.     }
  94.  
  95.     if (typeof style[param] !== 'undefined') {
  96.       memoized[param] = param;
  97.       return param;
  98.     }
  99.  
  100.     var camelCase = param[0].toUpperCase() + param.slice(1);
  101.     var prefixes = ['webkit', 'moz', 'Moz', 'ms', 'o'];
  102.     var test;
  103.  
  104.     for (var i = 0, len = prefixes.length; i < len; i++) {
  105.       test = prefixes[i] + camelCase;
  106.       if (typeof style[test] !== 'undefined') {
  107.         memoized[param] = test;
  108.         return test;
  109.       }
  110.     }
  111.   }
  112.  
  113.   var has3d;
  114.  
  115.   function translate(a, b, c) {
  116.     typeof has3d !== 'undefined' || (has3d = check3d());
  117.  
  118.     c = c || 0;
  119.  
  120.     if (has3d) {
  121.       return 'translate3d(' + a + ', ' + b + ', ' + c + ')';
  122.     } else {
  123.       return 'translate(' + a + ', ' + b + ')';
  124.     }
  125.   }
  126.  
  127.   function check3d() {
  128.     // I admit, this line is stealed from the great Velocity.js!
  129.     // http://julian.com/research/velocity/
  130.     var isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
  131.  
  132.     if (!isMobile) {
  133.       return false;
  134.     }
  135.  
  136.     var transform = prefix('transform');
  137.     var $p = document.createElement('p');
  138.  
  139.     document.body.appendChild($p);
  140.     $p.style[transform] = 'translate3d(1px,1px,1px)';
  141.  
  142.     has3d = $p.style[transform];
  143.     has3d = has3d != null && has3d.length && has3d !== 'none';
  144.  
  145.     document.body.removeChild($p);
  146.  
  147.     return has3d;
  148.   }
  149.  
  150.   function createElement(type) {
  151.     return document.createElement(type);
  152.   }
  153.  
  154.   var maxZ = 52;
  155.  
  156.   function _card(i) {
  157.     var transform = prefix('transform');
  158.  
  159.     // calculate rank/suit, etc..
  160.     var rank = i % 13 + 1;
  161.     var suit = i / 13 | 0;
  162.     var z = (52 - i) / 4;
  163.  
  164.     // create elements
  165.     var $el = createElement('div');
  166.     var $face = createElement('div');
  167.     var $back = createElement('div');
  168.  
  169.     // states
  170.     var isDraggable = false;
  171.     var isFlippable = false;
  172.  
  173.     // self = card
  174.     var self = { i: i, rank: rank, suit: suit, pos: i, $el: $el, mount: mount, unmount: unmount, setSide: setSide };
  175.  
  176.     var modules = Deck.modules;
  177.     var module;
  178.  
  179.     // add classes
  180.     $face.classList.add('face');
  181.     $back.classList.add('back');
  182.  
  183.     // add default transform
  184.     $el.style[transform] = translate(-z + 'px', -z + 'px');
  185.  
  186.     // add default values
  187.     self.x = -z;
  188.     self.y = -z;
  189.     self.z = z;
  190.     self.rot = 0;
  191.  
  192.     // set default side to back
  193.     self.setSide('back');
  194.  
  195.     // add drag/click listeners
  196.     addListener($el, 'mousedown', onMousedown);
  197.     addListener($el, 'touchstart', onMousedown);
  198.  
  199.     // load modules
  200.     for (module in modules) {
  201.       addModule(modules[module]);
  202.     }
  203.  
  204.     self.animateTo = function (params) {
  205.       var delay = params.delay;
  206.       var duration = params.duration;
  207.       var _params$x = params.x;
  208.       var x = _params$x === undefined ? self.x : _params$x;
  209.       var _params$y = params.y;
  210.       var y = _params$y === undefined ? self.y : _params$y;
  211.       var _params$rot = params.rot;
  212.       var rot = _params$rot === undefined ? self.rot : _params$rot;
  213.       var ease$$ = params.ease;
  214.       var onStart = params.onStart;
  215.       var onProgress = params.onProgress;
  216.       var onComplete = params.onComplete;
  217.  
  218.       var startX, startY, startRot;
  219.       var diffX, diffY, diffRot;
  220.  
  221.       animationFrames(delay, duration).start(function () {
  222.         startX = self.x || 0;
  223.         startY = self.y || 0;
  224.         startRot = self.rot || 0;
  225.         onStart && onStart();
  226.       }).progress(function (t) {
  227.         var et = ease[ease$$ || 'cubicInOut'](t);
  228.  
  229.         diffX = x - startX;
  230.         diffY = y - startY;
  231.         diffRot = rot - startRot;
  232.  
  233.         onProgress && onProgress(t, et);
  234.  
  235.         self.x = startX + diffX * et;
  236.         self.y = startY + diffY * et;
  237.         self.rot = startRot + diffRot * et;
  238.  
  239.         $el.style[transform] = translate(self.x + 'px', self.y + 'px') + (diffRot ? 'rotate(' + self.rot + 'deg)' : '');
  240.       }).end(function () {
  241.         onComplete && onComplete();
  242.       });
  243.     };
  244.  
  245.     // set rank & suit
  246.     self.setRankSuit = function (rank, suit) {
  247.       var suitName = SuitName(suit);
  248.       $el.setAttribute('class', 'card ' + suitName + ' rank' + rank);
  249.     };
  250.  
  251.     self.setRankSuit(rank, suit);
  252.  
  253.     self.enableDragging = function () {
  254.       // this activates dragging
  255.       if (isDraggable) {
  256.         // already is draggable, do nothing
  257.         return;
  258.       }
  259.       isDraggable = true;
  260.       $el.style.cursor = 'move';
  261.     };
  262.  
  263.     self.enableFlipping = function () {
  264.       if (isFlippable) {
  265.         // already is flippable, do nothing
  266.         return;
  267.       }
  268.       isFlippable = true;
  269.     };
  270.  
  271.     self.disableFlipping = function () {
  272.       if (!isFlippable) {
  273.         // already disabled flipping, do nothing
  274.         return;
  275.       }
  276.       isFlippable = false;
  277.     };
  278.  
  279.     self.disableDragging = function () {
  280.       if (!isDraggable) {
  281.         // already disabled dragging, do nothing
  282.         return;
  283.       }
  284.       isDraggable = false;
  285.       $el.style.cursor = '';
  286.     };
  287.  
  288.     return self;
  289.  
  290.     function addModule(module) {
  291.       // add card module
  292.       module.card && module.card(self);
  293.     }
  294.  
  295.     function onMousedown(e) {
  296.       var startPos = {};
  297.       var pos = {};
  298.       var starttime = Date.now();
  299.  
  300.       e.preventDefault();
  301.  
  302.       // get start coordinates and start listening window events
  303.       if (e.type === 'mousedown') {
  304.         startPos.x = pos.x = e.clientX;
  305.         startPos.y = pos.y = e.clientY;
  306.         addListener(window, 'mousemove', onMousemove);
  307.         addListener(window, 'mouseup', onMouseup);
  308.       } else {
  309.         startPos.x = pos.x = e.touches[0].clientX;
  310.         startPos.y = pos.y = e.touches[0].clientY;
  311.         addListener(window, 'touchmove', onMousemove);
  312.         addListener(window, 'touchend', onMouseup);
  313.       }
  314.  
  315.       if (!isDraggable) {
  316.         // is not draggable, do nothing
  317.         return;
  318.       }
  319.  
  320.       // move card
  321.       $el.style[transform] = translate(self.x + 'px', self.y + 'px') + (self.rot ? ' rotate(' + self.rot + 'deg)' : '');
  322.       $el.style.zIndex = maxZ++;
  323.  
  324.       function onMousemove(e) {
  325.         if (!isDraggable) {
  326.           // is not draggable, do nothing
  327.           return;
  328.         }
  329.         if (e.type === 'mousemove') {
  330.           pos.x = e.clientX;
  331.           pos.y = e.clientY;
  332.         } else {
  333.           pos.x = e.touches[0].clientX;
  334.           pos.y = e.touches[0].clientY;
  335.         }
  336.  
  337.         // move card
  338.         $el.style[transform] = translate(Math.round(self.x + pos.x - startPos.x) + 'px', Math.round(self.y + pos.y - startPos.y) + 'px') + (self.rot ? ' rotate(' + self.rot + 'deg)' : '');
  339.       }
  340.  
  341.       function onMouseup(e) {
  342.         if (isFlippable && Date.now() - starttime < 200) {
  343.           // flip sides
  344.           self.setSide(self.side === 'front' ? 'back' : 'front');
  345.         }
  346.         if (e.type === 'mouseup') {
  347.           removeListener(window, 'mousemove', onMousemove);
  348.           removeListener(window, 'mouseup', onMouseup);
  349.         } else {
  350.           removeListener(window, 'touchmove', onMousemove);
  351.           removeListener(window, 'touchend', onMouseup);
  352.         }
  353.         if (!isDraggable) {
  354.           // is not draggable, do nothing
  355.           return;
  356.         }
  357.  
  358.         // set current position
  359.         self.x = self.x + pos.x - startPos.x;
  360.         self.y = self.y + pos.y - startPos.y;
  361.       }
  362.     }
  363.  
  364.     function mount(target) {
  365.       // mount card to target (deck)
  366.       target.appendChild($el);
  367.  
  368.       self.$root = target;
  369.     }
  370.  
  371.     function unmount() {
  372.       // unmount from root (deck)
  373.       self.$root && self.$root.removeChild($el);
  374.       self.$root = null;
  375.     }
  376.  
  377.     function setSide(newSide) {
  378.       // flip sides
  379.       if (newSide === 'front') {
  380.         if (self.side === 'back') {
  381.           $el.removeChild($back);
  382.         }
  383.         self.side = 'front';
  384.         $el.appendChild($face);
  385.         self.setRankSuit(self.rank, self.suit);
  386.       } else {
  387.         if (self.side === 'front') {
  388.           $el.removeChild($face);
  389.         }
  390.         self.side = 'back';
  391.         $el.appendChild($back);
  392.         $el.setAttribute('class', 'card');
  393.       }
  394.     }
  395.   }
  396.  
  397.   function SuitName(suit) {
  398.     // return suit name from suit value
  399.     return suit === 0 ? 'spades' : suit === 1 ? 'hearts' : suit === 2 ? 'clubs' : suit === 3 ? 'diamonds' : 'joker';
  400.   }
  401.  
  402.   function addListener(target, name, listener) {
  403.     target.addEventListener(name, listener);
  404.   }
  405.  
  406.   function removeListener(target, name, listener) {
  407.     target.removeEventListener(name, listener);
  408.   }
  409.  
  410.   var ease = {
  411.     linear: function linear(t) {
  412.       return t;
  413.     },
  414.     quadIn: function quadIn(t) {
  415.       return t * t;
  416.     },
  417.     quadOut: function quadOut(t) {
  418.       return t * (2 - t);
  419.     },
  420.     quadInOut: function quadInOut(t) {
  421.       return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
  422.     },
  423.     cubicIn: function cubicIn(t) {
  424.       return t * t * t;
  425.     },
  426.     cubicOut: function cubicOut(t) {
  427.       return --t * t * t + 1;
  428.     },
  429.     cubicInOut: function cubicInOut(t) {
  430.       return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
  431.     },
  432.     quartIn: function quartIn(t) {
  433.       return t * t * t * t;
  434.     },
  435.     quartOut: function quartOut(t) {
  436.       return 1 - --t * t * t * t;
  437.     },
  438.     quartInOut: function quartInOut(t) {
  439.       return t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t;
  440.     },
  441.     quintIn: function quintIn(t) {
  442.       return t * t * t * t * t;
  443.     },
  444.     quintOut: function quintOut(t) {
  445.       return 1 + --t * t * t * t * t;
  446.     },
  447.     quintInOut: function quintInOut(t) {
  448.       return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t;
  449.     }
  450.   };
  451.  
  452.   var flip = {
  453.     deck: function deck(_deck) {
  454.       _deck.flip = _deck.queued(flip);
  455.  
  456.       function flip(next, side) {
  457.         var flipped = _deck.cards.filter(function (card) {
  458.           return card.side === 'front';
  459.         }).length / _deck.cards.length;
  460.  
  461.         _deck.cards.forEach(function (card, i) {
  462.           card.setSide(side ? side : flipped > 0.5 ? 'back' : 'front');
  463.         });
  464.         next();
  465.       }
  466.     }
  467.   };
  468.  
  469.   var sort = {
  470.     deck: function deck(_deck2) {
  471.       _deck2.sort = _deck2.queued(sort);
  472.  
  473.       function sort(next, reverse) {
  474.         var cards = _deck2.cards;
  475.  
  476.         cards.sort(function (a, b) {
  477.           if (reverse) {
  478.             return a.i - b.i;
  479.           } else {
  480.             return b.i - a.i;
  481.           }
  482.         });
  483.  
  484.         cards.forEach(function (card, i) {
  485.           card.sort(i, cards.length, function (i) {
  486.             if (i === cards.length - 1) {
  487.               next();
  488.             }
  489.           }, reverse);
  490.         });
  491.       }
  492.     },
  493.     card: function card(_card2) {
  494.       var $el = _card2.$el;
  495.  
  496.       _card2.sort = function (i, len, cb, reverse) {
  497.         var z = i / 4;
  498.         var delay = i * 10;
  499.  
  500.         _card2.animateTo({
  501.           delay: delay,
  502.           duration: 400,
  503.  
  504.           x: -z,
  505.           y: -150,
  506.           rot: 0,
  507.  
  508.           onComplete: function onComplete() {
  509.             $el.style.zIndex = i;
  510.           }
  511.         });
  512.  
  513.         _card2.animateTo({
  514.           delay: delay + 500,
  515.           duration: 400,
  516.  
  517.           x: -z,
  518.           y: -z,
  519.           rot: 0,
  520.  
  521.           onComplete: function onComplete() {
  522.             cb(i);
  523.           }
  524.         });
  525.       };
  526.     }
  527.   };
  528.  
  529.   function plusminus(value) {
  530.     var plusminus = Math.round(Math.random()) ? -1 : 1;
  531.  
  532.     return plusminus * value;
  533.   }
  534.  
  535.   function fisherYates(array) {
  536.     var rnd, temp;
  537.  
  538.     for (var i = array.length - 1; i; i--) {
  539.       rnd = Math.random() * i | 0;
  540.       temp = array[i];
  541.       array[i] = array[rnd];
  542.       array[rnd] = temp;
  543.     }
  544.  
  545.     return array;
  546.   }
  547.  
  548.   function fontSize() {
  549.     return window.getComputedStyle(document.body).getPropertyValue('font-size').slice(0, -2);
  550.   }
  551.  
  552.   var ____fontSize;
  553.  
  554.   var shuffle = {
  555.     deck: function deck(_deck3) {
  556.       _deck3.shuffle = _deck3.queued(shuffle);
  557.  
  558.       function shuffle(next) {
  559.         var cards = _deck3.cards;
  560.  
  561.         ____fontSize = fontSize();
  562.  
  563.         fisherYates(cards);
  564.  
  565.         cards.forEach(function (card, i) {
  566.           card.pos = i;
  567.  
  568.           card.shuffle(function (i) {
  569.             if (i === cards.length - 1) {
  570.               next();
  571.             }
  572.           });
  573.         });
  574.         return;
  575.       }
  576.     },
  577.  
  578.     card: function card(_card3) {
  579.       var $el = _card3.$el;
  580.  
  581.       _card3.shuffle = function (cb) {
  582.         var i = _card3.pos;
  583.         var z = i / 4;
  584.         var delay = i * 2;
  585.  
  586.         _card3.animateTo({
  587.           delay: delay,
  588.           duration: 200,
  589.  
  590.           x: plusminus(Math.random() * 40 + 20) * ____fontSize / 16,
  591.           y: -z,
  592.           rot: 0
  593.         });
  594.         _card3.animateTo({
  595.           delay: 200 + delay,
  596.           duration: 200,
  597.  
  598.           x: -z,
  599.           y: -z,
  600.           rot: 0,
  601.  
  602.           onStart: function onStart() {
  603.             $el.style.zIndex = i;
  604.           },
  605.  
  606.           onComplete: function onComplete() {
  607.             cb(i);
  608.           }
  609.         });
  610.       };
  611.     }
  612.   };
  613.  
  614.   var __fontSize;
  615.  
  616.   var poker = {
  617.     deck: function deck(_deck4) {
  618.       _deck4.poker = _deck4.queued(poker);
  619.  
  620.       function poker(next) {
  621.         var cards = _deck4.cards;
  622.         var len = cards.length;
  623.  
  624.         __fontSize = fontSize();
  625.  
  626.         cards.slice(-5).reverse().forEach(function (card, i) {
  627.           card.poker(i, len, function (i) {
  628.             card.setSide('front');
  629.             if (i === 4) {
  630.               next();
  631.             }
  632.           });
  633.         });
  634.       }
  635.     },
  636.     card: function card(_card4) {
  637.       var $el = _card4.$el;
  638.  
  639.       _card4.poker = function (i, len, cb) {
  640.         var delay = i * 250;
  641.  
  642.         _card4.animateTo({
  643.           delay: delay,
  644.           duration: 250,
  645.  
  646.           x: Math.round((i - 2.05) * 70 * __fontSize / 16),
  647.           y: Math.round(-110 * __fontSize / 16),
  648.           rot: 0,
  649.  
  650.           onStart: function onStart() {
  651.             $el.style.zIndex = len - 1 + i;
  652.           },
  653.           onComplete: function onComplete() {
  654.             cb(i);
  655.           }
  656.         });
  657.       };
  658.     }
  659.   };
  660.  
  661.   var intro = {
  662.     deck: function deck(_deck5) {
  663.       _deck5.intro = _deck5.queued(intro);
  664.  
  665.       function intro(next) {
  666.         var cards = _deck5.cards;
  667.  
  668.         cards.forEach(function (card, i) {
  669.           card.setSide('front');
  670.           card.intro(i, function (i) {
  671.             animationFrames(250, 0).start(function () {
  672.               card.setSide('back');
  673.             });
  674.             if (i === cards.length - 1) {
  675.               next();
  676.             }
  677.           });
  678.         });
  679.       }
  680.     },
  681.     card: function card(_card5) {
  682.       var transform = prefix('transform');
  683.  
  684.       var $el = _card5.$el;
  685.  
  686.       _card5.intro = function (i, cb) {
  687.         var delay = 500 + i * 10;
  688.         var z = i / 4;
  689.  
  690.         $el.style[transform] = translate(-z + 'px', '-250px');
  691.         $el.style.opacity = 0;
  692.  
  693.         _card5.x = -z;
  694.         _card5.y = -250 - z;
  695.         _card5.rot = 0;
  696.  
  697.         _card5.animateTo({
  698.           delay: delay,
  699.           duration: 1000,
  700.  
  701.           x: -z,
  702.           y: -z,
  703.  
  704.           onStart: function onStart() {
  705.             $el.style.zIndex = i;
  706.           },
  707.           onProgress: function onProgress(t) {
  708.             $el.style.opacity = t;
  709.           },
  710.           onComplete: function onComplete() {
  711.             $el.style.opacity = '';
  712.             cb && cb(i);
  713.           }
  714.         });
  715.       };
  716.     }
  717.   };
  718.  
  719.   var _fontSize;
  720.  
  721.   var fan = {
  722.     deck: function deck(_deck6) {
  723.       _deck6.fan = _deck6.queued(fan);
  724.  
  725.       function fan(next) {
  726.         var cards = _deck6.cards;
  727.         var len = cards.length;
  728.  
  729.         _fontSize = fontSize();
  730.  
  731.         cards.forEach(function (card, i) {
  732.           card.fan(i, len, function (i) {
  733.             if (i === cards.length - 1) {
  734.               next();
  735.             }
  736.           });
  737.         });
  738.       }
  739.     },
  740.     card: function card(_card6) {
  741.       var $el = _card6.$el;
  742.  
  743.       _card6.fan = function (i, len, cb) {
  744.         var z = i / 4;
  745.         var delay = i * 10;
  746.         var rot = i / (len - 1) * 260 - 130;
  747.  
  748.         _card6.animateTo({
  749.           delay: delay,
  750.           duration: 300,
  751.  
  752.           x: -z,
  753.           y: -z,
  754.           rot: 0
  755.         });
  756.         _card6.animateTo({
  757.           delay: 300 + delay,
  758.           duration: 300,
  759.  
  760.           x: Math.cos(deg2rad(rot - 90)) * 55 * _fontSize / 16,
  761.           y: Math.sin(deg2rad(rot - 90)) * 55 * _fontSize / 16,
  762.           rot: rot,
  763.  
  764.           onStart: function onStart() {
  765.             $el.style.zIndex = i;
  766.           },
  767.  
  768.           onComplete: function onComplete() {
  769.             cb(i);
  770.           }
  771.         });
  772.       };
  773.     }
  774.   };
  775.  
  776.   function deg2rad(degrees) {
  777.     return degrees * Math.PI / 180;
  778.   }
  779.  
  780.   var ___fontSize;
  781.  
  782.   var bysuit = {
  783.     deck: function deck(_deck7) {
  784.       _deck7.bysuit = _deck7.queued(bysuit);
  785.  
  786.       function bysuit(next) {
  787.         var cards = _deck7.cards;
  788.  
  789.         ___fontSize = fontSize();
  790.  
  791.         cards.forEach(function (card) {
  792.           card.bysuit(function (i) {
  793.             if (i === cards.length - 1) {
  794.               next();
  795.             }
  796.           });
  797.         });
  798.       }
  799.     },
  800.     card: function card(_card7) {
  801.       var rank = _card7.rank;
  802.       var suit = _card7.suit;
  803.  
  804.       _card7.bysuit = function (cb) {
  805.         var i = _card7.i;
  806.         var delay = i * 10;
  807.  
  808.         _card7.animateTo({
  809.           delay: delay,
  810.           duration: 400,
  811.  
  812.           x: -Math.round((6.75 - rank) * 8 * ___fontSize / 16),
  813.           y: -Math.round((1.5 - suit) * 92 * ___fontSize / 16),
  814.           rot: 0,
  815.  
  816.           onComplete: function onComplete() {
  817.             cb(i);
  818.           }
  819.         });
  820.       };
  821.     }
  822.   };
  823.  
  824.   function queue(target) {
  825.     var array = Array.prototype;
  826.  
  827.     var queueing = [];
  828.  
  829.     target.queue = queue;
  830.     target.queued = queued;
  831.  
  832.     return target;
  833.  
  834.     function queued(action) {
  835.       return function () {
  836.         var self = this;
  837.         var args = arguments;
  838.  
  839.         queue(function (next) {
  840.           action.apply(self, array.concat.apply(next, args));
  841.         });
  842.       };
  843.     }
  844.  
  845.     function queue(action) {
  846.       if (!action) {
  847.         return;
  848.       }
  849.  
  850.       queueing.push(action);
  851.  
  852.       if (queueing.length === 1) {
  853.         next();
  854.       }
  855.     }
  856.     function next() {
  857.       queueing[0](function (err) {
  858.         if (err) {
  859.           throw err;
  860.         }
  861.  
  862.         queueing = queueing.slice(1);
  863.  
  864.         if (queueing.length) {
  865.           next();
  866.         }
  867.       });
  868.     }
  869.   }
  870.  
  871.   function observable(target) {
  872.     target || (target = {});
  873.     var listeners = {};
  874.  
  875.     target.on = on;
  876.     target.one = one;
  877.     target.off = off;
  878.     target.trigger = trigger;
  879.  
  880.     return target;
  881.  
  882.     function on(name, cb, ctx) {
  883.       listeners[name] || (listeners[name] = []);
  884.       listeners[name].push({ cb: cb, ctx: ctx });
  885.     }
  886.  
  887.     function one(name, cb, ctx) {
  888.       listeners[name] || (listeners[name] = []);
  889.       listeners[name].push({
  890.         cb: cb, ctx: ctx, once: true
  891.       });
  892.     }
  893.  
  894.     function trigger(name) {
  895.       var self = this;
  896.       var args = Array.prototype.slice(arguments, 1);
  897.  
  898.       var currentListeners = listeners[name] || [];
  899.  
  900.       currentListeners.filter(function (listener) {
  901.         listener.cb.apply(self, args);
  902.  
  903.         return !listener.once;
  904.       });
  905.     }
  906.  
  907.     function off(name, cb) {
  908.       if (!name) {
  909.         listeners = {};
  910.         return;
  911.       }
  912.  
  913.       if (!cb) {
  914.         listeners[name] = [];
  915.         return;
  916.       }
  917.  
  918.       listeners[name] = listeners[name].filter(function (listener) {
  919.         return listener.cb !== cb;
  920.       });
  921.     }
  922.   }
  923.  
  924.   function Deck(jokers) {
  925.     // init cards array
  926.     var cards = new Array(jokers ? 55 : 52);
  927.  
  928.     var $el = createElement('div');
  929.     var self = observable({ mount: mount, unmount: unmount, cards: cards, $el: $el });
  930.     var $root;
  931.  
  932.     var modules = Deck.modules;
  933.     var module;
  934.  
  935.     // make queueable
  936.     queue(self);
  937.  
  938.     // load modules
  939.     for (module in modules) {
  940.       addModule(modules[module]);
  941.     }
  942.  
  943.     // add class
  944.     $el.classList.add('deck');
  945.  
  946.     var card;
  947.  
  948.     // create cards
  949.     for (var i = cards.length; i; i--) {
  950.       card = cards[i - 1] = _card(i - 1);
  951.       card.setSide('back');
  952.       card.mount($el);
  953.     }
  954.  
  955.     return self;
  956.  
  957.     function mount(root) {
  958.       // mount deck to root
  959.       $root = root;
  960.       $root.appendChild($el);
  961.     }
  962.  
  963.     function unmount() {
  964.       // unmount deck from root
  965.       $root.removeChild($el);
  966.     }
  967.  
  968.     function addModule(module) {
  969.       module.deck && module.deck(self);
  970.     }
  971.   }
  972.   Deck.animationFrames = animationFrames;
  973.   Deck.ease = ease;
  974.   Deck.modules = { bysuit: bysuit, fan: fan, intro: intro, poker: poker, shuffle: shuffle, sort: sort, flip: flip };
  975.   Deck.Card = _card;
  976.   Deck.prefix = prefix;
  977.   Deck.translate = translate;
  978.  
  979.   return Deck;
  980. })();
Add Comment
Please, Sign In to add comment