box-slider-fx-scroll-3d.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. ;(function (w, $, undefined) {
  2. w.jqBoxSlider.registerAnimator('scrollVert3d,scrollHorz3d', (function () {
  3. var adaptor = {}
  4. , supports3D = false
  5. , vendorPrefix = '';
  6. // set local flags for 3D support and css vendor prefix
  7. adaptor.configure = function (can3D, prefix) {
  8. supports3D = can3D;
  9. vendorPrefix = prefix;
  10. };
  11. // sets the box and slides initial state via css
  12. adaptor.initialize = function ($box, $slides, settings) {
  13. var $parent = $box.parent();
  14. // cache original css
  15. adaptor._cacheOriginalCSS($box, 'box', settings, [
  16. vendorPrefix + 'transform'
  17. , vendorPrefix + 'transition'
  18. , vendorPrefix + 'transform-style'
  19. ]);
  20. adaptor._cacheOriginalCSS($slides, 'slides', settings, [
  21. vendorPrefix + 'transform'
  22. ]);
  23. adaptor._cacheOriginalCSS($parent, 'viewport', settings, [
  24. vendorPrefix + 'perspective'
  25. ]);
  26. adaptor.applyStyling($parent, $box, $slides, settings);
  27. if (supports3D) {
  28. adaptor.reset($box, settings);
  29. }
  30. else { // using fade hide all but first slide
  31. $slides.filter(':gt(0)').hide();
  32. }
  33. };
  34. adaptor.applyStyling = function ($parent, $box, $slides, settings) {
  35. var width = $parent.innerWidth()
  36. , height = $slides.innerHeight()
  37. , positioning = {
  38. position: 'absolute'
  39. , top: 0
  40. , left: 0
  41. , opacity: 1
  42. };
  43. // Fix the parents height so absolute positioning of the box
  44. // doesn't cause page jank
  45. $parent.css('height', height);
  46. // apply new styling
  47. $slides.css(positioning);
  48. $slides.eq(settings.bsfaceindex || 0).css('z-index', 2);
  49. $box.css($.extend(positioning, { width: width, height: height }));
  50. // ensure parent is positioned to hold the box
  51. if ('absolute fixed relative'.indexOf($parent.css('position')) === -1) {
  52. $parent.css('position', 'relative');
  53. }
  54. if (supports3D) {
  55. // set the Z axis translation amount on the settings for this box
  56. settings.translateZ = ((settings.effect === 'scrollVert3d')? height / 100 * 29: width / 100 * 29 ); //->3 face; (height / 2: width / 2) -> 4 face
  57. // set the parent as the 3D viewport
  58. $parent.css(vendorPrefix + 'perspective', settings.perspective);
  59. $parent.css('overflow', 'visible');
  60. // apply transforms before transition to stop initial animation
  61. $box.css(vendorPrefix + 'transform-style', 'preserve-3d');
  62. $box.css(
  63. vendorPrefix + 'transform'
  64. , 'translate3d(0, 0, -' + settings.translateZ + 'px)'
  65. );
  66. // set front slide
  67. $slides.eq(settings.bsfaceindex || 0).css(
  68. vendorPrefix + 'transform'
  69. , 'rotate3d(0, 1, 0, 0deg) translate3d(0, 0, ' +
  70. settings.translateZ + 'px)'
  71. );
  72. }
  73. };
  74. // update the settings on an option change
  75. adaptor.reset = function ($box, settings) {
  76. var speed = (settings.speed / 1000) + 's';
  77. settings.bsangle = 0;
  78. // queue the transition for box rotation so it doesn't animate into place
  79. setTimeout(function () {
  80. $box.css(vendorPrefix + 'transition', vendorPrefix + 'transform '+ speed);
  81. }, 0);
  82. };
  83. // moves the slider to the next, prev or 'index' slide
  84. adaptor.transition = function (settings) {
  85. var angle = settings.bsangle + (settings.reverse? 120 : -120)
  86. , isVert = settings.effect === 'scrollVert3d';
  87. if (!supports3D) { // no 3D support just use a basic fade transition
  88. settings.$slides.filter(function (index) {
  89. return settings.currIndex !== index; }
  90. ).hide();
  91. settings.$currSlide.fadeOut(settings.speed);
  92. settings.$nextSlide.fadeIn(settings.speed);
  93. }
  94. else {
  95. // correct angle if going from prev to next or vice versa
  96. if (angle === 0) {
  97. angle = settings.reverse? 360 : -360;
  98. }
  99. settings.$currSlide.css('z-index', 1);
  100. settings.$slides // remove transform from all slides except current front face
  101. .filter(function (index) { return settings.currIndex !== index; })
  102. .css(vendorPrefix + 'transform', 'none')
  103. .css('display', 'none');
  104. settings.$nextSlide.css( // move next slide to the effective next face
  105. vendorPrefix + 'transform'
  106. , rotation(angle, isVert) + ' translate3d(0, 0,' + settings.translateZ + 'px)'
  107. ).css({display: 'block', zIndex: 2})
  108. settings.$box.css( // rotate the box to show next face
  109. vendorPrefix + 'transform'
  110. , 'translate3d(0, 0, -' + settings.translateZ + 'px) rotate3d(' +
  111. (isVert ? '1, 0, 0, ' : '0, 1, 0, ') + angle + 'deg)'
  112. );
  113. // the box has gone full circle so start again from 0deg
  114. if (Math.abs(angle) === 360) {
  115. settings.$box.css(
  116. vendorPrefix + 'transform'
  117. , 'translate3d(0, 0, -' + settings.translateZ + 'px)'
  118. );
  119. angle = 0;
  120. }
  121. return {bsangle: angle};
  122. }
  123. };
  124. // just resets the box and slides to their original css
  125. adaptor.destroy = function ($box, settings) {
  126. var $slides = $box.children()
  127. , $parent = $box.parent();
  128. if (settings.origCSS) {
  129. $box.css(settings.origCSS.box);
  130. $slides.css(settings.origCSS.slides);
  131. $parent.css(settings.origCSS.viewport);
  132. delete settings.bsangle;
  133. delete settings.translateZ;
  134. }
  135. };
  136. adaptor.resize = function ($box, $slides, settings) {
  137. var origCSS = settings.origCSS;
  138. if (origCSS) {
  139. // Pop it
  140. $box.css(origCSS.box);
  141. $slides.css(origCSS.slides);
  142. // ...and lock it
  143. setTimeout(function () {
  144. adaptor.applyStyling($box.parent(), $box, $slides, settings);
  145. adaptor.reset($box, settings);
  146. }, 0);
  147. }
  148. };
  149. // returns the correct face rotation based on the box's rotated angle
  150. var rotation = function (angle, isVert) {
  151. switch (angle) {
  152. // case 360: case -360: return 'rotate3d(0, 1, 0, 0deg)'; // front
  153. // case 90: case -270: return 'rotate3d(' + (isVert? '1, 0, 0,' : '0, 1, 0,') + ' -90deg)'; // bottom / left side
  154. // case 180: case -180: return 'rotate3d(' + (isVert? '1, 0, 0,' : '0, 1, 0,') + ' 180deg)'; // back
  155. // case 270: case -90: return 'rotate3d(' + (isVert? '1, 0, 0,' : '0, 1, 0,') + ' 90deg)'; // top / right side
  156. case 360: case -360: return 'rotate3d(0, 1, 0, 0deg)'; // front
  157. case 120: case -240: return 'rotate3d(' + (isVert? '1, 0, 0,' : '0, 1, 0,') + ' -120deg)'; // bottom / left side
  158. case 240: case -120: return 'rotate3d(' + (isVert? '1, 0, 0,' : '0, 1, 0,') + ' 120deg)'; // back
  159. }
  160. };
  161. return adaptor;
  162. }()));
  163. }(window, jQuery || Zepto));