kontext.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*!
  2. * kontext
  3. * http://lab.hakim.se/kontext
  4. * MIT licensed
  5. *
  6. * Copyright (C) 2013 Hakim El Hattab, http://hakim.se
  7. */
  8. window.kontext = function( container ) {
  9. // Dispatched when the current layer changes
  10. var changed = new kontext.Signal();
  11. // All layers in this instance of kontext
  12. var layers = Array.prototype.slice.call( container.querySelectorAll( '.layer' ) );
  13. // Flag if the browser is capable of handling our fancy transition
  14. var capable = 'WebkitPerspective' in document.body.style ||
  15. 'MozPerspective' in document.body.style ||
  16. 'msPerspective' in document.body.style ||
  17. 'OPerspective' in document.body.style ||
  18. 'perspective' in document.body.style;
  19. if( capable ) {
  20. container.classList.add( 'capable' );
  21. }
  22. // Create dimmer elements to fade out preceding slides
  23. layers.forEach( function( el, i ) {
  24. if( !el.querySelector( '.dimmer' ) ) {
  25. var dimmer = document.createElement( 'div' );
  26. dimmer.className = 'dimmer';
  27. el.appendChild( dimmer );
  28. }
  29. } );
  30. /**
  31. * Transitions to and shows the target layer.
  32. *
  33. * @param target index of layer or layer DOM element
  34. */
  35. function show( target, direction ) {
  36. // Make sure our listing of available layers is up to date
  37. layers = Array.prototype.slice.call( container.querySelectorAll( '.layer' ) );
  38. // Flag to CSS that we're ready to animate transitions
  39. container.classList.add( 'animate' );
  40. // Flag which direction
  41. direction = direction || ( target > getIndex() ? 'right' : 'left' );
  42. // Accept multiple types of targets
  43. if( typeof target === 'string' ) target = parseInt( target );
  44. if( typeof target !== 'number' ) target = getIndex( target );
  45. // Enforce index bounds
  46. target = Math.max( Math.min( target, layers.length ), 0 );
  47. // Only navigate if were able to locate the target
  48. if( layers[ target ] && !layers[ target ].classList.contains( 'show' ) ) {
  49. layers.forEach( function( el, i ) {
  50. el.classList.remove( 'left', 'right' );
  51. el.classList.add( direction );
  52. if( el.classList.contains( 'show' ) ) {
  53. el.classList.remove( 'show' );
  54. el.classList.add( 'hide1' );
  55. //Scroll to face 1 in learnning-theory
  56. $(el).find('.flash-card-box').boxSlider('showSlide', 0)
  57. }
  58. else {
  59. el.classList.remove( 'hide1' );
  60. }
  61. } );
  62. layers[ target ].classList.add( 'show' );
  63. changed.dispatch( layers[target], target );
  64. }
  65. }
  66. /**
  67. * Shows the previous layer.
  68. */
  69. function prev() {
  70. var index = getIndex() - 1;
  71. show( index >= 0 ? index : layers.length + index, 'left' );
  72. }
  73. /**
  74. * Shows the next layer.
  75. */
  76. function next() {
  77. show( ( getIndex() + 1 ) % layers.length, 'right' );
  78. }
  79. /**
  80. * Retrieves the index of the current slide.
  81. *
  82. * @param of [optional] layer DOM element which index is
  83. * to be returned
  84. */
  85. function getIndex( of ) {
  86. var index = 0;
  87. layers.forEach( function( layer, i ) {
  88. if( ( of && of == layer ) || ( !of && layer.classList.contains( 'show' ) ) ) {
  89. index = i;
  90. return;
  91. }
  92. } );
  93. return index;
  94. }
  95. /**
  96. * Retrieves the total number of layers.
  97. */
  98. function getTotal() {
  99. return layers.length;
  100. }
  101. // API
  102. return {
  103. show: show,
  104. prev: prev,
  105. next: next,
  106. getIndex: getIndex,
  107. getTotal: getTotal,
  108. changed: changed
  109. };
  110. };
  111. /**
  112. * Minimal utility for dispatching signals (events).
  113. */
  114. kontext.Signal = function() {
  115. this.listeners = [];
  116. }
  117. kontext.Signal.prototype.add = function( callback ) {
  118. this.listeners.push( callback );
  119. }
  120. kontext.Signal.prototype.remove = function( callback ) {
  121. var i = this.listeners.indexOf( callback );
  122. if( i >= 0 ) this.listeners.splice( i, 1 );
  123. }
  124. kontext.Signal.prototype.dispatch = function() {
  125. var args = Array.prototype.slice.call( arguments );
  126. this.listeners.forEach( function( f, i ) {
  127. f.apply( null, args );
  128. } );
  129. }