PageSourceSearch

https://cucinaconviviale.it/wp-content/themes/grandrestaurant/js/hw-parallax.js

js cucinaconviviale.it collected 2026-10-08 16:05:57 UTC 10,726 bytes, 237 lines download raw bytes

1/*
2 Copyright (C) 2013 Ziad Saab ziad(dot)saab(at)gmail(dot)com
3
4 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
5 documentation files (the "Software"), to deal in the Software without restriction, including without limitation
6 the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
7 permit persons to whom the Software is furnished to do so, subject to the following conditions:
8
9 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
12 WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
13 OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
14 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15*/
16;(function($) {
17  var ParallaxManager = function(options) {
18    this.options = options;
19    this.vendor_prefixes = ['webkit', 'moz', 'o', 'ms'];
20    this.num_vendor_prefixes = this.vendor_prefixes.length;
21
22    // Function used to detect support for a certain CSS style
23    var thisBrowserSupportsStyle = function(style) {
24      var vendors = ['Webkit', 'Moz', 'ms', 'O'];
25      var num_vendors = vendors.length;
26      var dummy_el = window.document.createElement('parallax');
27
28      // First test the bare style without prefix
29      if (dummy_el.style[style] !== undefined) {
30        return true;
31      }
32
33      // Test the camel-cased vendor-prefixed styles
34      style = style.replace(/./, function(first) {return first.toUpperCase();});
35      for (var i = 0; i < num_vendors; i++) {
36        var pfx_style = vendors[i] + style;
37        // The browser will return an empty string if a style is supported but not present, and undefined if the style is not supported
38        if (dummy_el.style[pfx_style] !== undefined) {
39          return true;
40        }
41      }
42      return false;
43    };
44
45    // Detect if we have 2d or 3d transforms by checking for support of the transform (2d) and perspective (3d) styles
46    this.has_3dtransforms = thisBrowserSupportsStyle('perspective');
47    // Additional test due to false positives returned with WebKit on some browsers: they support perspective but can't do 3d transforms
48    if (this.has_3dtransforms && thisBrowserSupportsStyle('WebkitPerspective')) {
49      var $test_el = $('<div><style type="text/css">@media (transform-3d),(-webkit-transform-3d) {#parallax-3dtest {position: absolute;left: 9px;height: 5px;margin: 0;padding: 0;border: 0;}</style><div id="parallax-3dtest"></div></div>').appendTo('body');
50      var $el = $('#parallax-3dtest');
51      this.has_3dtransforms = $el.height() == 5 && $el.offset().left == 9;
52      $test_el.remove();
53    }
54    this.has_2dtransforms = thisBrowserSupportsStyle('transform');
55  };
56
57  // Define "methods" on the ParallaxManager class
58  $.extend(ParallaxManager.prototype, {
59    init: function() {
60      this.scroll_factor = this.options.scroll_factor;
61      var parallax_blocks = this.parallax_blocks = [];
62      var image_attr = this.options.image_attr
63
64      var $body = $('body');
65      var $origins = this.options.origins;
66      $origins.each(function() {
67        var $origin = $(this);
68        var $parallax_block;
69        if ($origin.data(image_attr)) {
70          $parallax_block = $('<div class="parallax-block"><img class="parallax-image" src="' + $origin.data(image_attr) + '"></div>');
71          parallax_blocks.push({
72            origin: $origin,
73            block: $parallax_block,
74            bg_ratio: $origin.data('width') / $origin.data('height')
75          });
76          $body.prepend($parallax_block);
77        }
78        else if ($origin.data('tile')) {
79          $parallax_block = $('<div class="parallax-block"><div class="parallax-image" style="background-image: url(' + $origin.data('tile') + ')"></div></div>')
80          parallax_blocks.push({
81            origin: $origin,
82            block: $parallax_block,
83            bg_ratio: 1
84          });
85          $body.prepend($parallax_block);
86        }
87      });
88
89      var manager = this;
90      var reconfigure = function() {
91        manager.redrawBlocks();
92        manager.render();
93      };
94      var $window = $(window);
95      $window.on('load', reconfigure);
96      $window.on('resize', reconfigure);
97      $window.on('hwparallax.reconfigure', reconfigure);
98      $window.on('scroll', function() {manager.render();});
99    },
100    redrawBlocks: function() {
101      var window_width = $(window).width();
102      var window_height = this.window_height = $(window).height();
103
104      // Calculate document height to fix Chrome issue when scrolling past the content...
105      var body = document.body;
106      var html = document.documentElement;
107
108      var document_height = Math.max( body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
109      this.max_scrolltop = Math.max(0, document_height - window_height);
110
111      var num_parallax_blocks = this.parallax_blocks.length;
112      for (var i = 0; i < num_parallax_blocks; i++) {
113        var parallax_block_data = this.parallax_blocks[i];
114        var $parallax_block = parallax_block_data.block;
115        var bg_ratio = parallax_block_data.bg_ratio;
116        var $parallax_image = $parallax_block.children('.parallax-image');
117        var $origin = parallax_block_data.origin;
118
119        // Calculate the minimum background image height so that we may scroll by the scroll factor and keep the image in the bounds of its container
120        var origin_height = $origin.outerHeight();
121        var min_height = window_height - ((window_height - origin_height) * this.scroll_factor);
122
123        // Calculate the size of the parallax background image so that it covers the target block while still respecting the previously calculated minimum height
124        // Also, if the image's width is larger than the window's, center it about its parent element
125        var img_width = window_width;
126        var img_height = Math.ceil(img_width / bg_ratio);
127        var img_xoff = 0;
128        if (img_height < min_height) {
129          img_height = min_height;
130          img_width = img_height * bg_ratio;
131          img_xoff = Math.floor(img_width - window_width) / 2;
132        }
133        $parallax_image.width(img_width).height(img_height);
134
135        // Set the dimensions of the parallax block and hide it
136        $parallax_block.width(window_width).height(origin_height).css('visibility', 'hidden');
137
138        // Cache some data about the parallax block so that we don't have to recalculate it on every tick
139        // This data potentially changes, only changes when the window is resized
140        $.extend(parallax_block_data, {
141          origin_position: $origin.offset().top,
142          origin_height: origin_height,
143          image: $parallax_image,
144          image_xoff: img_xoff,
145          image_height: img_height
146        });
147      }
148    },
149    render: function() {
150      if (!this.drawing) {
151        this.drawing = true;
152        var manager = this;
153        if (window.requestAnimationFrame) {
154          window.requestAnimationFrame(function() {manager.draw();}, document);
155        }
156        else {
157          manager.draw();
158        }
159      }
160    },
161    draw: function() {
162      var scroll_top = Math.min(Math.max(0, $(window).scrollTop()), this.max_scrolltop);
163
164      // Loop thru all the parallax blocks
165      var num_blocks = this.parallax_blocks.length;
166      var data;
167      for (var i = 0; i < num_blocks; i++) {
168        data = this.parallax_blocks[i];
169        // Determine if parallax block is in view
170        // i.e. its bottom is below the window's upper bound and its top is above the window's lower bound
171        if (data.origin_position < scroll_top + this.window_height && data.origin_position + data.origin_height > scroll_top) {
172          // The block's y position in its fixed plane is the position of the original block relative to the top of the window
173          var new_block_position = data.origin_position - scroll_top;
174          // The background image's position is parallaxed to follow the block by the scroll factor
175          var new_image_position = new_block_position * (this.scroll_factor - 1);
176
177          // Apply the translations to block and image using the best method possible: 3d transform, 2d transform or regular top/left
178          var block_styles = {
179            visibility: 'visible'
180          };
181          var image_styles = {};
182          var block_transform, image_transform, prefixed_style;
183          var j;
184          
185          if (this.has_3dtransforms) {
186            block_transform = block_styles.transform = 'translate3d(0px, ' + new_block_position + 'px, 0px)';
187            image_transform = image_styles.transform = 'translate3d(-' + data.image_xoff + 'px, ' + new_image_position + 'px, 0px)';
188            for (j = 0; j < this.num_vendor_prefixes; j++) {
189              prefixed_style = '-' + this.vendor_prefixes[j] + '-transform';
190              block_styles[prefixed_style] = block_transform;
191              image_styles[prefixed_style] = image_transform;
192            }
193          }
194          else if (this.has_2dtransforms) {
195            block_transform = block_styles.transform = 'translate(0px, ' + new_block_position + 'px)';
196            image_transform = image_styles.transform = 'translate(-' + data.image_xoff + 'px, ' + new_image_position + 'px)';
197            for (j = 0; j < this.num_vendor_prefixes; j++) {
198              prefixed_style = '-' + this.vendor_prefixes[j] + '-transform';
199              block_styles[prefixed_style] = block_transform;
200              image_styles[prefixed_style] = image_transform;
201            }
202          }
203          else {
204            block_styles.top = new_block_position + 'px';
205            block_styles.left = 0 + 'px';
206            image_styles.top = new_image_position + 'px';
207            image_styles.left = -data.image_xoff + 'px';
208          }
209          data.block.css(block_styles);
210          data.image.css(image_styles);
211        }
212        else {
213          data.block.css('visibility', 'hidden');
214        }
215      }
216      this.drawing = false;
217    }
218  });
219
220  // Hook into jQuery
221  $.extend($.fn, {
222    parallax: function(options) {
223      var settings = $.extend(
224          {
225            scroll_factor: 0.2,
226            image_attr: 'image'
227          },
228          options,
229          {
230            origins: $(this)
231          }
232      );
233      var pm = new ParallaxManager(settings);
234      pm.init();
235    }
236  });
237})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.