PageSourceSearch

https://gallenbach.info/wp-content/themes/mediapool-child/vc_addons/imagescompare/jquery.images-compare.min.js

js gallenbach.info collected 2026-10-09 22:40:17 UTC 15,411 bytes, 471 lines download raw bytes

1/** global: Hammer */
2;(function ($, window) {
3    "use strict";
4
5    function stringRepeat(s, precision) {
6        // String repeat polyfill
7        if (!String.prototype.repeat) {
8            precision = precision || 1;
9            return new Array(precision + 1).join(s);
10        }
11        return s.repeat(precision);
12    }
13
14    var pluginName = 'imagesCompare',
15        defaults = {
16            initVisibleRatio: 0.5,
17            interactionMode: "drag", // "drag", "mousemove", "click"
18            animationDuration: 400, // default animation duration in ms
19            animationEasing: "swing",
20            addSeparator: true, // add a html element on the separation
21            addDragHandle: true, // add a html drag handle element on the separation
22            precision: 4
23        };
24
25    // Our object, using revealing module pattern
26    function ImagesCompare(element, options) {
27        element = $(element);
28        options = $.extend({}, defaults, options);
29        options.roundFactor = parseInt('1' + stringRepeat('0', options.precision));
30
31        this._name = pluginName;
32
33        var frontElement, backElement, separator, dragHandle, lastRatio = 1, size = {
34            width: 0,
35            height: 0,
36            maxWidth: 0,
37            maxHeight: 0
38        }, events = {
39            initialised: "imagesCompare:initialised",
40            changed: "imagesCompare:changed",
41            resized: "imagesCompare:resized"
42        };
43
44        function onImagesLoaded() {
45            var images = element.find('img'),
46                totalImagesCount= images.length,
47                elementsLoaded = 0;
48
49            function onImageLoaded(){
50                if (elementsLoaded >= totalImagesCount) {
51                    init();
52                }
53            }
54
55            images.each(function() {
56                // Image already loaded (cached)
57                if ($(this)[0].complete) {
58                    totalImagesCount--;
59                    onImageLoaded();
60                } else {
61                    // Image loading / error
62                    $(this).on('load', function() {
63                        elementsLoaded++;
64                        onImageLoaded();
65                    });
66                    $(this).on('error', function() {
67                        elementsLoaded++;
68                        onImageLoaded();
69                    });
70                }
71            });
72        }
73
74        onImagesLoaded();
75
76        function init() {
77            updateDom();
78            patchSize();
79            initInteractions();
80
81            $(frontElement).attr('ratio', options.initVisibleRatio);
82            setVisibleRatio(options.initVisibleRatio);
83
84            // Let the world know we have done the init
85            element.trigger({
86                type: events.initialised
87            });
88        }
89
90        function addResize() {
91            $(window).on('resize', function (event) {
92                frontElement.css('clip', '');
93                patchSize();
94                setVisibleRatio(lastRatio);
95
96                // Let the world know we have done some resize updates
97                element.trigger({
98                    type: events.resized,
99                    originalEvent: event
100                });
101            });
102        }
103
104        function initInteractions() {
105            options.interactionMode = options.interactionMode.toLowerCase();
106
107            if (options.interactionMode != "drag" && options.interactionMode != "mousemove" && options.interactionMode != "click") {
108                console.warn('No valid interactionMode found, valid values are "drag", "mousemove", "click"');
109            }
110
111            switch (options.interactionMode) {
112                case "drag":
113                    initDrag();
114                    break;
115                case "mousemove":
116                    initMouseMove();
117                    break;
118                case "click":
119                    initClick();
120                    break;
121                default:
122                    initDrag();
123            }
124        }
125
126        function initDrag() {
127            if (typeof Hammer == 'undefined') {
128                console.error('Please include the hammerjs library for drag support');
129            }
130            addDrag();
131            addResize();
132        }
133
134        function initMouseMove() {
135            addMouseMove();
136            addResize();
137        }
138
139        function initClick() {
140            addClick();
141            addResize();
142        }
143
144        function addClick() {
145            element.on('click', function (event) {
146                var ratio = getElementRatio(event.pageX);
147                setVisibleRatio(ratio);
148            });
149        }
150
151        function addMouseMove() {
152            var lastMove = 0;
153            var eventThrottle = 1;
154            element.on('mousemove', function (event) {
155                event.preventDefault();
156                var now = Date.now();
157                if (now > lastMove + eventThrottle) {
158                    lastMove = now;
159                    var ratio = getElementRatio(event.pageX);
160                    setVisibleRatio(ratio);
161                }
162            });
163
164            element.on('mouseout', function (event) {
165                var ratio = getElementRatio(event.pageX);
166                setVisibleRatio(ratio);
167            });
168        }
169
170        function addDrag() {
171            var hammertime = new Hammer(element[0]);
172            hammertime.get('pan').set({direction: Hammer.DIRECTION_HORIZONTAL});
173            hammertime.on('pan', function (event) {
174                var ratio = getElementRatio(event.srcEvent.pageX);
175                setVisibleRatio(ratio);
176            });
177        }
178
179        function updateDom() {
180            element.addClass('images-compare-container');
181            element.css('display', 'inline-block');
182
183            frontElement = element.find('> *:nth-child(1)');
184            backElement = element.find('> *:nth-child(2)');
185
186            frontElement.addClass("images-compare-before");
187            frontElement.css('display', 'block');
188            backElement.addClass("images-compare-after");
189            backElement.css('display', 'block');
190
191            if (options.addDragHandle) {
192                buildDragHandle();
193            }
194
195            if (options.addSeparator) {
196                buildSeparator();
197            }
198        }
199
200        function buildSeparator() {
201            element.prepend("<div class='images-compare-separator'></div>");
202            separator = element.find(".images-compare-separator");
203
204        }
205
206        function buildDragHandle() {
207            element.prepend("<div class='images-compare-handle'></div>");
208            dragHandle = element.find(".images-compare-handle");
209            dragHandle.append("<span class='images-compare-left-arrow'></span>");
210            dragHandle.append("<span class='images-compare-right-arrow'></span>");
211        }
212
213        function patchSize() {
214            var imgRef = backElement.find('img').first();
215            setSize(imgRef.width(), imgRef.height(), imgRef.naturalWidth(), imgRef.naturalHeight());
216            element.css('max-width', size.maxWidth + 'px');
217            element.css('max-height', size.maxHeight + 'px');
218            frontElement.width(size.width);
219            frontElement.height(size.height);
220        }
221
222        /**
223         *
224         * @param x
225         * @return float
226         */
227        function getElementRatio(x) {
228            return roundRatio((x - element.offset().left) / frontElement.width());
229        }
230
231        /**
232         *
233         * @param ratio
234         * @return float
235         */
236        function roundRatio(ratio) {
237            ratio = Math.round((ratio * options.roundFactor)) / options.roundFactor;
238            if (ratio > 1) {
239                ratio = 1;
240            }
241
242            if (ratio < 0) {
243                ratio = 0;
244            }
245
246            return ratio;
247
248        }
249
250        /**
251         * Animation request
252         *
253         * @param startValue float
254         * @param endValue float
255         * @param duration value in ms
256         * @param easing linear or swing
257         */
258        function launchAnimation(startValue, endValue, duration, easing) {
259            $(frontElement).attr('ratio', startValue).animate({ratio: startValue}, {
260                duration: 0
261            });
262
263            $(frontElement).stop().attr('ratio', startValue).animate({ratio: endValue}, {
264                duration: duration,
265                easing: easing,
266                step: function (now) {
267                    var width = getRatioValue(now);
268                    lastRatio = now;
269                    frontElement.attr('ratio', now).css('clip', 'rect(0, ' + width + 'px, ' + size.height + 'px, 0)');
270
271                    if (options.addSeparator) {
272                        separator.css('left', width + 'px');
273                    }
274
275                    if (options.addDragHandle) {
276                        dragHandle.css('left', width + 'px');
277                    }
278                },
279                done: function (animation, jumpedToEnd) {
280                    var ratio = $(frontElement).attr('ratio');
281                    // Let the world know something has changed
282                    element.trigger({
283                        type: events.changed,
284                        ratio: ratio,
285                        value: getRatioValue(ratio),
286                        animate: true,
287                        animation : animation,
288                        jumpedToEnd: jumpedToEnd
289                    });
290                }
291            });
292        }
293
294        /**
295         * Get value to reach, based on a ratio
296         *
297         * @param ratio float
298         * @return {number}
299         */
300        function getRatioValue(ratio) {
301            ratio = Math.round((ratio * options.roundFactor)) / options.roundFactor;
302            return Math.round(frontElement.width() * ratio);
303        }
304
305        /**
306         * Change visible ratio
307         *
308         * @param ratio float
309         * @param animate boolean Do we want an animation ?
310         * @param duration in ms
311         * @param easing 'swing', 'linear'
312         */
313        function setVisibleRatio(ratio, animate, duration, easing) {
314            if (typeof animate == 'undefined') {
315                animate = false;
316            }
317
318            var width = getRatioValue(ratio);
319
320            if (animate) {
321                var finalDuration = duration ? duration : options.animationDuration;
322                var finalEasing = easing ? easing : options.animationEasing;
323
324                launchAnimation(lastRatio, ratio, finalDuration, finalEasing);
325
326                // Let the world know something has changed
327                if (lastRatio != ratio) {
328                    element.trigger({
329                        type: events.changed,
330                        ratio: lastRatio,
331                        value: width,
332                        animate: animate
333                    });
334                }
335
336                return;
337
338            } else {
339                frontElement.stop().css('clip', 'rect(0, ' + width + 'px, ' + size.height + 'px, 0)');
340
341                if (options.addSeparator) {
342                    $(separator).stop().css('left', width + 'px');
343                }
344
345                if (options.addDragHandle) {
346                    dragHandle.css('left', width + 'px');
347                }
348            }
349
350            // Let the world know something has changed
351            if (lastRatio != ratio) {
352                element.trigger({
353                    type: events.changed,
354                    ratio: ratio,
355                    value: width,
356                    animate: animate
357                });
358            }
359
360            lastRatio = ratio;
361        }
362
363        function setSize(width, height, maxWidth, maxHeight) {
364            if (typeof width != 'undefined') {
365                setWidth(width);
366            }
367            if (typeof height != 'undefined') {
368                setHeight(height);
369            }
370            if (typeof maxWidth != 'undefined') {
371                setMaxWidth(maxWidth);
372            }
373            if (typeof maxHeight != 'undefined') {
374                setMaxHeight(maxHeight);
375            }
376            return size;
377        }
378
379        function setWidth(width) {
380            size.width = width;
381            return size;
382        }
383
384        function setMaxWidth(maxWidth) {
385            size.maxWidth = maxWidth;
386            return size;
387        }
388
389        function setHeight(height) {
390            size.height = height;
391            return size;
392        }
393
394        function setMaxHeight(maxHeight) {
395            size.maxHeight = maxHeight;
396            return size;
397        }
398
399        // public function declaration
400        // returning element to preserve chaining
401        return {
402            "setValue": function (ratio, animate, duration, easing) {
403                setVisibleRatio(ratio, animate, duration, easing);
404                return element;
405            },
406            "getValue": function () {
407                return lastRatio;
408            },
409            "on": function (eventName, callback) {
410                element.on(eventName, callback);
411                return element;
412            },
413            "off": function (eventName, callback) {
414                element.off(eventName, callback);
415                return element;
416            },
417            "events": function () {
418                return events;
419            }
420        };
421    }
422
423
424    /**
425     * Plugin declaration
426     *
427     * @param userOptions
428     * @return {*}
429     */
430    $.fn.imagesCompare = function (userOptions) {
431        var options = $.extend(defaults, userOptions);
432        return this.each(function () {
433            if (!$.data(this, pluginName)) {
434                $.data(this, pluginName, new ImagesCompare(this, options));
435            }
436        });
437    };
438
439})(jQuery, window, document);
440
441// http://www.jacklmoore.com/notes/naturalwidth-and-naturalheight-in-ie/
442(function ($) {
443    var props = ['Width', 'Height'], prop, propsLength;
444
445    propsLength = props.length;
446
447    for (var index = 0; index < propsLength; index++) {
448        prop = props[index];
449        /*jslint loopfunc: true */
450        (function (natural, prop) {
451            $.fn[natural] = (natural in document.createElement('img')) ?
452                function () {
453                    return this[0][natural];
454                } :
455                function () {
456                    var
457                        node = this[0],
458                        img,
459                        value = 0;
460
461                    if (node.tagName.toLowerCase() === 'img') {
462                        img = document.createElement('img');
463                        img.src = node.src;
464                        value = img[prop];
465                    }
466                    return value;
467                };
468        }('natural' + prop, prop.toLowerCase()));
469        /*jslint loopfunc: false */
470    }
471}(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.