PageSourceSearch

https://top-stm.ru/assets/js/jquery.flurry.js

js top-stm.ru collected 2026-10-04 23:14:19 UTC 15,113 bytes, 394 lines download raw bytes

1
2;(function($, undefined) {
3
4    /**
5     * requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel
6     * http://paulirish.com/2011/requestanimationframe-for-smart-animating/
7     * http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
8     *
9     * @link https://gist.github.com/lenville/9e13e63af075c145d662
10     */
11    (function() {
12        var lastTime = 0;
13        var vendors = ['ms', 'moz', 'webkit', 'o'];
14        for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
15            window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
16            window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
17        }
18
19        if (!window.requestAnimationFrame) {
20            window.requestAnimationFrame = function(callback, element) {
21                var currTime = new Date().getTime();
22                var timeToCall = Math.max(0, 16 - Math.abs(currTime - lastTime));
23                var id = window.setTimeout(function() {
24                    callback(currTime + timeToCall);
25                }, timeToCall);
26                lastTime = currTime + timeToCall;
27                return id;
28            };
29        }
30
31        if (!window.cancelAnimationFrame) {
32            window.cancelAnimationFrame = function(id) {
33                clearTimeout(id);
34            };
35        }
36    }());
37
38    // Change this to your plugin name.
39    var pluginName = 'flurry';
40
41    /**
42     * Behaves the same as setInterval except uses requestAnimationFrame() where possible for better performance
43     *
44     * http://www.joelambert.co.uk
45     * Copyright 2011, Joe Lambert.
46     * Free to use under the MIT license.
47     *
48     * @link https://gist.github.com/joelambert/1002116
49     * @param {function} fn The callback function
50     * @param {int} delay The delay in milliseconds
51     */
52    function requestInterval(fn, delay) {
53
54        /* jshint -W010 */
55        var start = new Date().getTime(),
56            handle = new Object();
57
58        function loop() {
59            var current = new Date().getTime(),
60                delta = current - start;
61
62            if(delta >= delay) {
63                fn.call();
64                start = new Date().getTime();
65            }
66
67            handle.value = window.requestAnimationFrame(loop);
68        }
69
70        handle.value = window.requestAnimationFrame(loop);
71        return handle;
72    }
73
74    /**
75     * Behaves the same as clearInterval except uses cancelRequestAnimationFrame() where possible for better performance
76     *
77     * http://www.joelambert.co.uk
78     * Copyright 2011, Joe Lambert.
79     * Free to use under the MIT license.
80     *
81     * @link https://gist.github.com/joelambert/1002116
82     * @param {int|object} fn The callback function
83     */
84    function clearRequestInterval(handle) {
85
86        /* jshint -W030 */
87        window.cancelAnimationFrame ? window.cancelAnimationFrame(handle.value) :
88            window.webkitCancelAnimationFrame ? window.webkitCancelAnimationFrame(handle.value) :
89                window.webkitCancelRequestAnimationFrame ? window.webkitCancelRequestAnimationFrame(handle.value) : /* Support for legacy API */
90                    window.mozCancelRequestAnimationFrame ? window.mozCancelRequestAnimationFrame(handle.value) :
91                        window.oCancelRequestAnimationFrame  ? window.oCancelRequestAnimationFrame(handle.value) :
92                            window.msCancelRequestAnimationFrame ? window.msCancelRequestAnimationFrame(handle.value) :
93                                clearInterval(handle);
94    }
95
96    /**
97     * Detects whether the browser supports CSS transitions (adapted from https://gist.github.com/jonraasch/373874)
98     *
99     * @return {boolean} True if CSS transitions are supported
100     */
101    function supportsTransitions() {
102        var thisBody = document.body || document.documentElement,
103            thisStyle = thisBody.style,
104            support = thisStyle.transition !== undefined || thisStyle.WebkitTransition !== undefined || thisStyle.MozTransition !== undefined || thisStyle.MsTransition !== undefined || thisStyle.OTransition !== undefined;
105        return support;
106    }
107
108    /**
109     * Generate a random integer within a range provided
110     *
111     * @param  {number} min The lowest number of the range
112     * @param  {number} max The highest number of the range
113     * @return {number}     The random integer within the range
114     */
115    function randomNumberInRange(min, max) {
116        return Math.floor(Math.random() * (max - min + 1) + min);
117    }
118
119    /**
120     * Creates a snowflake with randomized movement based on the options provided
121     *
122     * @param {object} options    The options set for the plugin
123     * @param {object} $container The jQuery element to append each snowflake to.
124     */
125    function createFlake(options, $container, containerWidth) {
126
127        // Set the character. If multiple characters are provided, randomly select one.
128        var character = options.character.length === 1 ? options.character : options.character.charAt(Math.round(randomNumberInRange(0, options.character.length - 1)));
129
130        // Set the flake's starting position to a random number between the container width, including additional space for the wind setting
131        var startX = randomNumberInRange(-Math.abs(options.wind), containerWidth + Math.abs(options.wind));
132
133        // Set the flake's ending X translation to a random number based on the wind and windVariance options
134        var endX = startX + randomNumberInRange(options.wind - options.windVariance, options.wind + options.windVariance);
135
136        // Set the flake's font size to a random number between the small and large options
137        var fontSize = randomNumberInRange(options.small, options.large);
138
139        // Set the flake's speed to a random number based on the speed setting and the randomized fontSize
140        var speed = options.speed / ((randomNumberInRange(fontSize * 1.2, fontSize * 0.8) - options.small) / (options.large - options.small) + 0.5);
141
142        // Set the flake's ending Y translation based on the height setting and the randomized fontSize
143        var endY = options.height - fontSize;
144
145        // Set the flake's rotation to a random degree based on the rotation and rotationVariance options
146        var endRotation = randomNumberInRange(options.wind - options.windVariance, options.wind + options.windVariance);
147
148        // Create object to store final CSS properties for the flake
149        var endCSS = {
150            "transform": "translateX(" + endX + "px) translateY(" + endY + "px) rotate(" + endRotation + "deg)",
151            "opacity": 0
152        };
153
154        // Create the flake, set the CSS for it, and animate it
155        var $flake = $('<span></span>');
156        $flake.html(character).css({
157            "color": options.blur && fontSize < (options.large + options.small) / 2 ? "transparent" : options.color,
158            "text-shadow": options.blur && fontSize < (options.large + options.small) / 2 ? "0 0 1px rgba(255,255,255,1)" : "none",
159            "display": "inline-block",
160            "line-height": 1,
161            "margin": 0,
162            "padding": "2px",
163            "pointer-events": "none",
164            "font-size": fontSize + "px",
165            "opacity": options.startTransparency,
166            "position": "absolute",
167            "top": "-" + (options.large * 1.2) + "px",
168            "transform": "translateX(" + startX + "px) translateY(0px)",
169            "transition": "transform " + (speed / 1000) + "s linear, opacity " + (speed / 1000) + "s " + options.opacityEasing,
170            "z-index": options.zIndex,
171        }).appendTo($container);
172
173        if (supportsTransitions) {
174
175            // Remove the flake element when it finishes transitioning
176            $flake.on('transitionend.flurry', function(event) {
177                $(event.target).remove();
178            });
179
180            // Set the endCSS to trigger the transition
181            window.requestAnimationFrame(function(){
182                $flake.css(endCSS);
183            });
184        } else {
185
186            // Use jQuery .animate()
187            $flake.animate(endCSS, speed, 'linear', function() {
188                $(this).remove();
189            });
190        }
191    }
192
193    /**
194     * Plugin object constructor.
195     * Implements the Revealing Module Pattern.
196     */
197    function Plugin(element, options) {
198
199        // References to this plugin instance, DOM and jQuery versions of element.
200        var self = this;
201        var el = element;
202        var $el = $(element);
203
204        // Extend default options with those supplied by user.
205        options = $.extend({
206            height: $el.height() > 200 ? 200 : $el.height(), // default to 200px or the height of the element, whichever is smaller
207            useRelative: $el.is('body') ? false : true, // default to false for the body element and true for all other elements
208        }, $.fn[pluginName].defaults, options);
209
210        // Ensure options that should be numbers are numbers
211        $.each(options, function(key, val) {
212            if (parseInt(val)) {
213                options[key] = parseInt(val);
214            }
215        });
216
217        /**
218         * Initialize plugin.
219         */
220        function init() {
221
222            // Add any initialization logic here...
223
224            // Set element position to relative if currently static
225            if (options.useRelative === true && $el.css('position') === 'static') {
226                $$el.css({
227                    'position': 'relative'
228                });
229            }
230
231            // Create container element to hold snowflakes
232            var $container = $(document.createElement('div')).addClass('flurry-container').css({
233                'margin': 0,
234                'padding': 0,
235                'position': 'absolute',
236                'top': 0,
237                'right': 0,
238                'left': 0,
239                'height': options.height,
240                'overflow': options.overflow,
241                'pointer-events': 'none'
242            }).prependTo($el);
243
244            // On window resize, recalculate the width used to generate flakes within
245            var containerWidth = $container.width();
246            $(window).resize(function() {
247                containerWidth = $container.width();
248            });
249
250            // Generate flakes at the interval set by the frequency setting
251            self.flakeInterval = requestInterval(function() {
252                createFlake(options, $container, containerWidth);
253            }, options.frequency);
254
255            // Call onInit hook
256            hook('onInit');
257        }
258
259        /**
260         * Get/set a plugin option.
261         * Get usage: $('#el').demoplugin('option', 'key');
262         * Set usage: $('#el').demoplugin('option', 'key', value);
263         */
264        function option (key, val) {
265            if (val) {
266                options[key] = parseInt(val) || val;
267            } else {
268                return options[key];
269            }
270        }
271
272        /**
273         * Destroy plugin.
274         * Usage: $('#el').demoplugin('destroy');
275         */
276        function destroy() {
277
278            // Iterate over each matching element.
279            $el.each(function() {
280                var el = this;
281                var $el = $(this);
282
283                // Add code to restore the element to its original state...
284
285                // Cancel snowflake generation
286                clearRequestInterval(self.flakeInterval);
287
288                // Remove container
289                $el.find('.flurry-container').remove();
290
291                // Call onDestroy hook
292                hook('onDestroy');
293
294                // Remove Plugin instance from the element.
295                $el.removeData('plugin_' + pluginName);
296            });
297        }
298
299        /**
300         * Callback hooks.
301         * Usage: In the defaults object specify a callback function:
302         * hookName: function() {}
303         * Then somewhere in the plugin trigger the callback:
304         * hook('hookName');
305         */
306        function hook(hookName) {
307            if (options[hookName] !== undefined) {
308
309                // Call the user defined function.
310                // Scope is set to the jQuery element we are operating on.
311                options[hookName].call(el);
312            }
313        }
314
315        // Initialize the plugin instance.
316        init();
317
318        // Expose methods of Plugin we wish to be public.
319        return {
320            option: option,
321            destroy: destroy
322        };
323    }
324
325    /**
326     * Plugin definition.
327     */
328    $.fn[pluginName] = function(options) {
329
330        // If the first parameter is a string, treat this as a call to a public method.
331        if (typeof arguments[0] === 'string') {
332            var methodName = arguments[0];
333            var args = Array.prototype.slice.call(arguments, 1);
334            var returnVal;
335            this.each(function() {
336
337                // Check that the element has a plugin instance, and that the requested public method exists.
338                if ($.data(this, 'plugin_' + pluginName) && typeof $.data(this, 'plugin_' + pluginName)[methodName] === 'function') {
339
340                    // Call the method of the Plugin instance, and Pass it the supplied arguments.
341                    returnVal = $.data(this, 'plugin_' + pluginName)[methodName].apply(this, args);
342                } else {
343                    throw new Error('Method ' +  methodName + ' does not exist on jQuery.' + pluginName);
344                }
345            });
346            if (returnVal !== undefined){
347
348                // If the method returned a value, return the value.
349                return returnVal;
350            } else {
351
352                // Otherwise, returning 'this' preserves chainability.
353                return this;
354            }
355
356            // If the first parameter is an object (options), or was omitted, instantiate a new instance of the plugin.
357        } else if (typeof options === "object" || !options) {
358            return this.each(function() {
359
360                // Only allow the plugin to be instantiated once.
361                if (!$.data(this, 'plugin_' + pluginName)) {
362
363                    // Pass options to Plugin constructor, and store Plugin instance in the elements jQuery data object.
364                    $.data(this, 'plugin_' + pluginName, new Plugin(this, options));
365                }
366            });
367        }
368    };
369
370    $.fn[pluginName].defaults = {
371        onInit: function() {},
372        onDestroy: function() {},
373        /* height: 200, */
374        /* useRelative: false, */
375        character: "❄",
376        color: "white",
377        frequency: 100,
378        speed: 12000,
379        small: 8,
380        large: 23,
381        wind: 40,
382        windVariance: 20,
383        height: 750,
384        rotation: 90,
385        rotationVariance: 180,
386        startOpacity: 1,
387        endOpacity: 0,
388        opacityEasing: "cubic-bezier(1,.3,.6,.74)",
389        blur: true,
390        overflow: "hidden",
391        zIndex: 9999
392    };
393
394})(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.