PageRenderTime 53ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/ajax/libs//1.1/parallax.js

https://gitlab.com/Mirros/cdnjs
JavaScript | 343 lines | 265 code | 65 blank | 13 comment | 87 complexity | 26be6f0cd38d8572f048de3912f6c6fe MD5 | raw file
  1. /*!
  2. * parallax.js v1.1 (http://pixelcog.github.io/parallax.js/)
  3. * Copyright (c) 2014 PixelCog, Inc.
  4. * Licensed under MIT (https://github.com/pixelcog/parallax.js/blob/master/LICENSE)
  5. */
  6. ;(function ( $, window, document, undefined ) {
  7. // Polyfill for requestAnimationFrame
  8. // via: https://gist.github.com/paulirish/1579671
  9. (function() {
  10. var lastTime = 0;
  11. var vendors = ['ms', 'moz', 'webkit', 'o'];
  12. for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
  13. window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
  14. window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
  15. || window[vendors[x]+'CancelRequestAnimationFrame'];
  16. }
  17. if (!window.requestAnimationFrame)
  18. window.requestAnimationFrame = function(callback, element) {
  19. var currTime = new Date().getTime();
  20. var timeToCall = Math.max(0, 16 - (currTime - lastTime));
  21. var id = window.setTimeout(function() { callback(currTime + timeToCall); },
  22. timeToCall);
  23. lastTime = currTime + timeToCall;
  24. return id;
  25. };
  26. if (!window.cancelAnimationFrame)
  27. window.cancelAnimationFrame = function(id) {
  28. clearTimeout(id);
  29. };
  30. }());
  31. // Parallax Constructor
  32. var $body = $('body');
  33. var $window = $(window);
  34. function Parallax(element, options) {
  35. var self = this;
  36. if (typeof options == 'object') {
  37. delete options.refresh;
  38. delete options.render;
  39. $.extend(this, options);
  40. }
  41. this.$element = $(element);
  42. if (!this.imageSrc && this.$element.is('img')) {
  43. this.imageSrc = this.$element.attr('src');
  44. }
  45. var positions = (this.position + '').toLowerCase().match(/\S+/g) || [];
  46. if (positions.length < 1) {
  47. positions.push('center');
  48. }
  49. if (positions.length == 1) {
  50. positions.push(positions[0]);
  51. }
  52. if (positions[0] == 'top' || positions[0] == 'bottom' ||
  53. positions[1] == 'left' || positions[1] == 'right') {
  54. self.positionX = positions[1];
  55. self.positionY = positions[0];
  56. } else {
  57. self.positionX = positions[0];
  58. self.positionY = positions[1];
  59. }
  60. if (this.positionX != undefined) positions[0] = this.positionX.toLowerCase();
  61. if (this.positionY != undefined) positions[1] = this.positionY.toLowerCase();
  62. if (this.positionX != 'left' && this.positionX != 'right') {
  63. if (isNaN(parseInt(this.positionX))) {
  64. this.positionX = 'center';
  65. } else {
  66. this.positionX = parseInt(this.positionX);
  67. }
  68. }
  69. if (this.positionY != 'top' && this.positionY != 'bottom') {
  70. if (isNaN(parseInt(this.positionY))) {
  71. this.positionY = 'center';
  72. } else {
  73. this.positionY = parseInt(this.positionY);
  74. }
  75. }
  76. this.position =
  77. this.positionX + (isNaN(this.positionX)? '' : 'px') + ' ' +
  78. this.positionY + (isNaN(this.positionY)? '' : 'px');
  79. if (navigator.userAgent.match(/(iPod|iPhone|iPad)/)) {
  80. if (this.iosFix && !this.$element.is('img')) {
  81. this.$element.css({
  82. backgroundImage: 'url(' + encodeURIComponent(this.imageSrc) + ')',
  83. backgroundSize: 'cover',
  84. backgroundPosition: this.position
  85. });
  86. }
  87. return this;
  88. }
  89. this.$mirror = $('<div />').prependTo('body');
  90. this.$slider = $('<img />').prependTo(this.$mirror);
  91. this.$mirror.addClass('parallax-mirror').css({
  92. visibility: 'hidden',
  93. zIndex: this.zIndex,
  94. position: 'fixed',
  95. top: 0,
  96. left: 0,
  97. overflow: 'hidden'
  98. });
  99. this.$slider.addClass('parallax-slider').one('load', function() {
  100. if (!self.naturalHeight || !self.naturalWidth) {
  101. self.naturalHeight = this.naturalHeight || this.height || 1;
  102. self.naturalWidth = this.naturalWidth || this.width || 1;
  103. }
  104. self.aspectRatio = self.naturalWidth / self.naturalHeight;
  105. Parallax.isSetup || Parallax.setup();
  106. Parallax.sliders.push(self);
  107. Parallax.isFresh = false;
  108. Parallax.requestRender();
  109. });
  110. this.$slider[0].src = this.imageSrc;
  111. if (this.naturalHeight && this.naturalWidth || this.$slider[0].complete) {
  112. this.$slider.trigger('load');
  113. }
  114. };
  115. // Parallax Instance Methods
  116. $.extend(Parallax.prototype, {
  117. speed: 0.2,
  118. bleed: 0,
  119. zIndex: -100,
  120. iosFix: true,
  121. position: 'center',
  122. refresh: function() {
  123. this.boxWidth = this.$element.width();
  124. this.boxHeight = this.$element.height() + this.bleed * 2;
  125. this.boxOffsetTop = this.$element.offset().top - this.bleed;
  126. this.boxOffsetLeft = this.$element.offset().left;
  127. this.boxOffsetBottom = this.boxOffsetTop + this.boxHeight;
  128. var margin = 0;
  129. var winHeight = Parallax.winHeight;
  130. var imageHeightMin = winHeight - (winHeight - this.boxHeight) * this.speed | 0;
  131. if (imageHeightMin * this.aspectRatio >= this.boxWidth) {
  132. this.imageWidth = imageHeightMin * this.aspectRatio | 0;
  133. this.imageHeight = imageHeightMin;
  134. this.offsetBaseTop = 0;
  135. margin = this.imageWidth - this.boxWidth;
  136. if (this.positionX == 'left') {
  137. this.offsetLeft = 0;
  138. } else if (this.positionX == 'right') {
  139. this.offsetLeft = - margin;
  140. } else if (!isNaN(this.positionX)) {
  141. this.offsetLeft = Math.max(this.positionX, - margin);
  142. } else {
  143. this.offsetLeft = - margin / 2 | 0;
  144. }
  145. } else {
  146. this.imageWidth = this.boxWidth;
  147. this.imageHeight = this.boxWidth / this.aspectRatio | 0;
  148. this.offsetLeft = 0;
  149. margin = this.imageHeight - imageHeightMin;
  150. if (this.positionY == 'top') {
  151. this.offsetBaseTop = 0;
  152. } else if (this.positionY == 'bottom') {
  153. this.offsetBaseTop = - margin;
  154. } else if (!isNaN(this.positionY)) {
  155. this.offsetBaseTop = Math.max(this.positionY, - margin);
  156. } else {
  157. this.offsetBaseTop = - margin / 2 | 0;
  158. }
  159. }
  160. },
  161. render: function() {
  162. var scrollTop = Parallax.scrollTop;
  163. var scrollLeft = Parallax.scrollLeft;
  164. var scrollBottom = scrollTop + Parallax.winHeight;
  165. if (this.boxOffsetBottom > scrollTop && this.boxOffsetTop < scrollBottom) {
  166. this.visibility = 'visible';
  167. } else {
  168. this.visibility = 'hidden';
  169. }
  170. this.mirrorTop = this.boxOffsetTop - scrollTop;
  171. this.mirrorLeft = this.boxOffsetLeft - scrollLeft;
  172. this.offsetTop = this.offsetBaseTop - this.mirrorTop * (1 - this.speed);
  173. this.$mirror.css({
  174. transform: 'translate3d(0px, 0px, 0px)',
  175. visibility: this.visibility,
  176. top: this.mirrorTop,
  177. left: this.mirrorLeft,
  178. height: this.boxHeight,
  179. width: this.boxWidth
  180. });
  181. this.$slider.css({
  182. transform: 'translate3d(0px, 0px, 0px)',
  183. position: 'absolute',
  184. top: this.offsetTop,
  185. left: this.offsetLeft,
  186. height: this.imageHeight,
  187. width: this.imageWidth
  188. });
  189. }
  190. });
  191. // Parallax Static Methods
  192. $.extend(Parallax, {
  193. scrollTop: 0,
  194. scrollLeft: 0,
  195. winHeight: 0,
  196. winWidth: 0,
  197. docHeight: 1 << 30,
  198. docWidth: 1 << 30,
  199. sliders: [],
  200. isReady: false,
  201. isFresh: false,
  202. isBusy: false,
  203. setup: function() {
  204. if (this.isReady) return;
  205. $window
  206. .on('scroll.px.parallax load.px.parallax', function() {
  207. var scrollTopMax = Parallax.docHeight - Parallax.winHeight;
  208. var scrollLeftMax = Parallax.docWidth - Parallax.winWidth;
  209. Parallax.scrollTop = Math.max(0, Math.min(scrollTopMax, $window.scrollTop()));
  210. Parallax.scrollLeft = Math.max(0, Math.min(scrollLeftMax, $window.scrollLeft()));
  211. Parallax.requestRender();
  212. })
  213. .on('resize.px.parallax load.px.parallax', function() {
  214. Parallax.winHeight = $window.height();
  215. Parallax.winWidth = $window.width();
  216. Parallax.docHeight = $(document).height();
  217. Parallax.docWidth = $(document).width();
  218. Parallax.isFresh = false;
  219. Parallax.requestRender();
  220. });
  221. this.isReady = true;
  222. },
  223. configure: function(options) {
  224. if (typeof options == 'object') {
  225. delete options.refresh;
  226. delete options.render;
  227. $.extend(this.prototype, options);
  228. }
  229. },
  230. refresh: function() {
  231. $.each(this.sliders, function(){ this.refresh() });
  232. this.isFresh = true;
  233. },
  234. render: function() {
  235. this.isFresh || this.refresh();
  236. $.each(this.sliders, function(){ this.render() });
  237. },
  238. requestRender: function() {
  239. var self = this;
  240. if (!this.isBusy) {
  241. this.isBusy = true;
  242. window.requestAnimationFrame(function() {
  243. self.render();
  244. self.isBusy = false;
  245. });
  246. }
  247. }
  248. });
  249. // Parallax Plugin Definition
  250. function Plugin(option) {
  251. return this.each(function () {
  252. var $this = $(this);
  253. var options = typeof option == 'object' && option;
  254. if (this == window || this == document || $this.is('body')) {
  255. Parallax.configure(options);
  256. }
  257. else if (!$this.data('px.parallax')) {
  258. options = $.extend({}, $this.data(), options);
  259. $this.data('px.parallax', new Parallax(this, options));
  260. }
  261. if (typeof option == 'string') {
  262. Parallax[option]();
  263. }
  264. })
  265. };
  266. var old = $.fn.parallax;
  267. $.fn.parallax = Plugin;
  268. $.fn.parallax.Constructor = Parallax;
  269. // Parallax No Conflict
  270. $.fn.parallax.noConflict = function () {
  271. $.fn.parallax = old;
  272. return this;
  273. };
  274. // Parallax Data-API
  275. $(document).on('ready.px.parallax.data-api', function () {
  276. $('[data-parallax="scroll"]').parallax();
  277. });
  278. }(jQuery, window, document));