cws_parallax.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /**
  2. CWS Parallax scroll plugin
  3. **/
  4. (function ( $ ){
  5. $.fn.cws_prlx = cws_prlx;
  6. window.addEventListener( 'scroll', function (){
  7. if ( window.cws_prlx != undefined && !window.cws_prlx.disabled ){
  8. window.cws_prlx.translate_layers();
  9. }
  10. }, false );
  11. window.addEventListener( 'resize', function (){
  12. var i, section_id, section_params;
  13. if ( window.cws_prlx != undefined ){
  14. if ( window.cws_prlx.servant.is_mobile() ){
  15. if ( !window.cws_prlx.disabled ){
  16. for ( layer_id in window.cws_prlx.layers ){
  17. window.cws_prlx.layers[layer_id].el.removeAttribute( 'style' );
  18. }
  19. window.cws_prlx.disabled = true;
  20. }
  21. }
  22. else{
  23. if ( window.cws_prlx.disabled ){
  24. window.cws_prlx.disabled = false;
  25. }
  26. for ( section_id in window.cws_prlx.sections ){
  27. section_params = window.cws_prlx.sections[section_id];
  28. if ( section_params.height != section_params.el.offsetHeight ){
  29. window.cws_prlx.prepare_section_data( section_id );
  30. }
  31. }
  32. }
  33. }
  34. }, false );
  35. function cws_prlx ( args ){
  36. var factory, sects;
  37. sects = $( this );
  38. if ( !sects.length ) return;
  39. factory = new cws_prlx_factory( args );
  40. window.cws_prlx = window.cws_prlx != undefined ? window.cws_prlx : new cws_prlx_builder ();
  41. sects.each( function (){
  42. var sect = $( this );
  43. var sect_id = factory.add_section( sect );
  44. if ( sect_id ) window.cws_prlx.prepare_section_data( sect_id );
  45. });
  46. }
  47. function cws_prlx_factory ( args ){
  48. var args = args != undefined ? args : {};
  49. args.def_speed = args.def_speed != undefined && !isNaN( parseInt( args.def_speed ) ) && parseInt( args.def_speed > 0 ) && parseInt( args.def_speed <= 100 ) ? args.def_speed : 50;
  50. args.layer_sel = args.layer_sel != undefined && typeof args.layer_sel == "string" && args.layer_sel.length ? args.layer_sel : ".cws_prlx_layer";
  51. this.args = args;
  52. this.add_section = cws_prlx_add_section;
  53. this.add_layer = cws_prlx_add_layer;
  54. this.remove_layer = cws_prlx_remove_layer;
  55. }
  56. function cws_prlx_builder (){
  57. this.servant = new cws_servant ();
  58. this.sections = {};
  59. this.layers = {};
  60. this.calc_layer_speed = cws_prlx_calc_layer_speed;
  61. this.prepare_section_data = cws_prlx_prepare_section_data;
  62. this.prepare_layer_data = cws_prlx_prepare_layer_data;
  63. this.translate_layers = cws_prlx_translate_layers;
  64. this.translate_layer = cws_prlx_translate_layer;
  65. this.conditions = {};
  66. this.conditions.layer_loaded = cws_prlx_layer_loaded_condition;
  67. this.disabled = false;
  68. }
  69. function cws_prlx_add_section ( section_obj ){
  70. var factory, section, section_id, layers, layer, i;
  71. factory = this;
  72. section = section_obj[0];
  73. layers = $( factory.args.layer_sel, section_obj );
  74. if ( !layers.length ) return false;
  75. section_id = window.cws_prlx.servant.uniq_id( 'cws_prlx_section_' );
  76. section.id = section_id;
  77. window.cws_prlx.sections[section_id] = {
  78. 'el' : section,
  79. 'height' : null,
  80. 'layer_sel' : factory.args.layer_sel
  81. }
  82. if ( /cws_Yt_video_bg/.test( section.className ) ){ /* for youtube video background */
  83. section.addEventListener( "DOMNodeRemoved", function ( e ){
  84. var el = e.srcElement ? e.srcElement : e.target;
  85. if ( $( el ).is( factory.args.layer_sel ) ){
  86. factory.remove_layer( el.id );
  87. }
  88. }, false );
  89. section.addEventListener( "DOMNodeInserted", function ( e ){
  90. var el = e.srcElement ? e.srcElement : e.target;
  91. if ( $( el ).is( factory.args.layer_sel ) ){
  92. factory.add_layer( el, section_id );
  93. }
  94. }, false );
  95. }
  96. section.addEventListener( "DOMNodeRemoved", function ( e ){ /* for dynamically removed content */
  97. window.cws_prlx.prepare_section_data( section_id );
  98. },false );
  99. section.addEventListener( "DOMNodeInserted", function ( e ){ /* for dynamically added content */
  100. window.cws_prlx.prepare_section_data( section_id );
  101. },false );
  102. for ( i = 0; i < layers.length; i++ ){
  103. layer = layers[i];
  104. factory.add_layer( layer, section_id )
  105. }
  106. return section_id;
  107. }
  108. function cws_prlx_add_layer ( layer, section_id ){
  109. var factory, layer_rel_speed, layer_params;
  110. factory = this;
  111. layer.id = !layer.id.length ? window.cws_prlx.servant.uniq_id( 'cws_prlx_layer_' ) : layer.id;
  112. layer_rel_speed = $( layer ).data( 'scroll-speed' );
  113. layer_rel_speed = layer_rel_speed != undefined ? layer_rel_speed : factory.args.def_speed;
  114. layer_params = {
  115. 'el' : layer,
  116. 'section_id' : section_id,
  117. 'height' : null,
  118. 'loaded' : false,
  119. 'rel_speed' : layer_rel_speed,
  120. 'speed' : null
  121. }
  122. window.cws_prlx.layers[layer.id] = layer_params;
  123. return layer.id;
  124. }
  125. function cws_prlx_remove_layer ( layer_id ){
  126. var layers;
  127. layers = window.cws_prlx.layers;
  128. if ( layers[layer_id] != undefined ){
  129. delete layers[layer_id];
  130. }
  131. }
  132. function cws_prlx_prepare_section_data ( section_id ){
  133. var section, section_params, layer_sel, layers, layer, layer_id, i;
  134. if ( !Object.keys( window.cws_prlx.sections ).length || window.cws_prlx.sections[section_id] == undefined ) return false;
  135. section_params = window.cws_prlx.sections[section_id];
  136. section = section_params.el;
  137. section_params.height = section.offsetHeight;
  138. section_obj = $( section );
  139. layers = $( section_params.layer_sel, section_obj );
  140. for ( i=0; i<layers.length; i++ ){
  141. layer = layers[i];
  142. layer_id = layer.id;
  143. if ( layer_id ) window.cws_prlx.prepare_layer_data( layer_id, section_id );
  144. }
  145. }
  146. function cws_prlx_prepare_layer_data ( layer_id, section_id ){
  147. window.cws_prlx.servant.wait_for( 'layer_loaded', [ layer_id ], function ( layer_id ){
  148. var layer_params, layer;
  149. layer_params = window.cws_prlx.layers[layer_id];
  150. layer = layer_params.el;
  151. layer_params.height = layer.offsetHeight;
  152. window.cws_prlx.calc_layer_speed( layer_id );
  153. window.cws_prlx.translate_layer( layer_id );
  154. layer_params.loaded = true;
  155. }, [ layer_id ]);
  156. }
  157. function cws_prlx_translate_layers (){
  158. var layers, layer_ids, layer_id, i;
  159. if ( window.cws_prlx == undefined ) return;
  160. layers = window.cws_prlx.layers;
  161. layer_ids = Object.keys( layers );
  162. for ( i = 0; i < layer_ids.length; i++ ){
  163. layer_id = layer_ids[i];
  164. window.cws_prlx.translate_layer( layer_id );
  165. }
  166. }
  167. function cws_prlx_translate_layer ( layer_id ){
  168. var layer_params, section, layer, layer_translation, style_adjs;
  169. if ( window.cws_prlx == undefined || window.cws_prlx.layers[layer_id] == undefined ) return false;
  170. layer_params = window.cws_prlx.layers[layer_id];
  171. if ( layer_params.speed == null ) return false;
  172. if ( layer_params.section_id == undefined || window.cws_prlx.sections[layer_params.section_id] == undefined ) return false;
  173. section = window.cws_prlx.sections[layer_params.section_id].el;
  174. if ( window.cws_prlx.servant.is_visible( section ) ) {
  175. layer = layer_params.el;
  176. layer_translation = ( section.getBoundingClientRect().top - window.innerHeight ) * layer_params.speed;
  177. style_adjs = {
  178. "WebkitTransform" : "translate(-50%," + layer_translation + "px)",
  179. "MozTransform" : "translate(-50%," + layer_translation + "px)",
  180. "msTransform" : "translate(-50%," + layer_translation + "px)",
  181. "OTransform" : "translate(-50%," + layer_translation + "px)",
  182. "transform" : "translate(-50%," + layer_translation + "px)"
  183. }
  184. for ( key in style_adjs ){
  185. layer.style[key] = style_adjs[key];
  186. }
  187. }
  188. }
  189. function cws_servant (){
  190. this.uniq_id = cws_uniq_id;
  191. this.wait_for = cws_wait_for;
  192. this.is_visible = cws_is_visible;
  193. this.is_mobile = cws_is_mobile;
  194. }
  195. function cws_uniq_id ( prefix ){
  196. var d, t, n, id;
  197. var prefix = prefix != undefined ? prefix : "";
  198. d = new Date();
  199. t = d.getTime();
  200. n = parseInt( Math.random() * t );
  201. id = prefix + n;
  202. return id;
  203. }
  204. function cws_wait_for ( condition, condition_args, callback, callback_args ){
  205. var match = false;
  206. var condition_args = condition_args != undefined && typeof condition_args == 'object' ? condition_args : new Array();
  207. var callback_args = callback_args != undefined && typeof callback_args == 'object' ? callback_args : new Array();
  208. if ( condition == undefined || typeof condition != 'string' || callback == undefined || typeof callback != 'function' ) return match;
  209. match = window.cws_prlx.conditions[condition].apply( window, condition_args );
  210. if ( match == true ){
  211. callback.apply( window, callback_args );
  212. return true;
  213. }
  214. else if ( match == false ){
  215. setTimeout( function (){
  216. cws_wait_for ( condition, condition_args, callback, callback_args );
  217. }, 10);
  218. }
  219. else{
  220. return false;
  221. }
  222. }
  223. function cws_is_visible ( el ){
  224. var window_top, window_height, window_bottom, el_top, el_height, el_bottom, r;
  225. window_top = window.pageYOffset;
  226. window_height = window.innerHeight;
  227. window_bottom = window_top + window_height;
  228. el_top = $( el ).offset().top;
  229. el_height = el.offsetHeight;
  230. el_bottom = el_top + el_height;
  231. r = ( el_top > window_top && el_top < window_bottom ) || ( el_top < window_top && el_bottom > window_bottom ) || ( el_bottom > window_top && el_bottom < window_bottom ) ? true : false;
  232. return r;
  233. }
  234. function cws_is_mobile (){
  235. return window.innerWidth < 768;
  236. }
  237. function cws_prlx_layer_loaded_condition ( layer_id ){
  238. var layer, r;
  239. r = false;
  240. if ( layer_id == undefined || typeof layer_id != 'string' ) return r;
  241. if ( window.cws_prlx.layers[layer_id] == undefined ) return r;
  242. layer = window.cws_prlx.layers[layer_id].el;
  243. switch ( layer.tagName ){
  244. case "IMG":
  245. if ( layer.complete == undefined ){
  246. console.log( 'img hasn\'t complete property' );
  247. }
  248. else{
  249. if ( !layer.complete ){
  250. return r;
  251. }
  252. }
  253. break;
  254. case "DIV": /* for youtube video background */
  255. if ( /^video-/.test( layer.id ) ){
  256. return r;
  257. }
  258. break;
  259. }
  260. return true;
  261. }
  262. function cws_prlx_calc_layer_speed ( layer_id ){
  263. var layer_params, layer, section_id, section_params, window_height;
  264. layer_params = window.cws_prlx.layers[layer_id];
  265. layer = layer_params.el;
  266. section_id = layer_params.section_id;
  267. section_params = window.cws_prlx.sections[section_id];
  268. window_height = window.innerHeight;
  269. layer_params.speed = ( ( layer_params.height - section_params.height ) / ( window_height + section_params.height ) ) * ( layer_params.rel_speed / 100 );
  270. }
  271. }(jQuery));