PageSourceSearch

https://obl.ru/local/templates/obl/js/vendor/jquery.mobilezoom/jquery.mobilezoom.js?154452212718026

js obl.ru collected 2026-09-24 08:36:00 UTC 18,026 bytes, 460 lines download raw bytes

1// jQuery Mobile Zoom by Denis Korovkin
2
3$(function(){
4    $.fn.mobilezoom = function(options) {
5        var settings = $.extend({
6            backbutton: 'Вернуться',
7            marginbetween: 30
8        }, options );
9
10        var touches = [];
11        var zoomStartTouches = [];
12        var zoomStarted = false;
13        var zoomStartDistance = false;
14        var zoomStartSize = false;
15        var moveStarted = false;
16        var moveStartPosition = false;
17
18        var next = false;
19        var prev = false;
20
21        var animating = false;
22
23        /* If many elements — do for each */
24        if(this.length > 1){
25            this.each(function(){
26                $(this).mobilezoom(settings);
27            });
28            return this;
29        }
30        /* If no elements — exit */
31        if(this.length == 0){
32            return this;
33        }
34
35        /* If already initialized — exit */
36        if(this.is('.mobilezoom__element')) return this;
37
38        this.addClass('mobilezoom__element');
39        initTouchEvents();
40
41        /* If is gallery — get other elements */
42        if(this.data('gallery')){
43            var gallery = $('*[data-gallery="'+ this.data('gallery') +'"]');
44        }
45
46        var current = this;
47
48        /* Handle click event */
49        this.on('click', function(e){
50            showImage(this);
51            e.preventDefault();
52            return false;
53        });
54
55        function showImage(element){
56            element = $(element);
57            var url;
58            if(element.is('img')){
59                url = element.attr('src');
60            } else {
61                url = element.attr('href');
62            }
63            $('body').append('<div class="mobilezoom__holder"><div class="mobilezoom__topbar"><div class="mobilezoom__backbutton">'+settings.backbutton+'</div></div><div class="mobilezoom__image"><img src="'+ url +'" /></div></div>');
64            $('body').addClass('mobilezoom__opened');
65
66            window.mobileZoomGallery = gallery;
67            window.mobileZoomCurrent = element;
68
69            defaultImagePosition();
70
71            $('.mobilezoom__backbutton').on('click', function(e){
72                $('.mobilezoom__holder').remove();
73                $('body').removeClass('mobilezoom__opened');
74            });
75            $('.mobilezoom__holder').on('click', function(e){
76                $('.mobilezoom__topbar').fadeToggle(300);
77            });
78
79            prepareNext();
80        }
81
82        function showNext(element){
83            element = $(element);
84            var url;
85            if(element.is('img')){
86                url = element.attr('src');
87            } else {
88                url = element.attr('href');
89            }
90            $('.mobilezoom__holder').append('<div class="mobilezoom__next-image"><img src="'+ url +'" /></div>');
91
92            function setPosition(){
93                var width = $('.mobilezoom__next-image').find('img').width();
94                var height = $('.mobilezoom__next-image').find('img').height();
95                var naturalWidth = $('.mobilezoom__next-image').find('img').get(0).naturalWidth;
96                var naturalHeight = $('.mobilezoom__next-image').find('img').get(0).naturalHeight;
97
98                if(naturalWidth > 0){
99                    $('.mobilezoom__next-image').data('nwidth', naturalWidth).data('nheight', naturalHeight);
100                    $('.mobilezoom__next-image').width('width').height('height').css({
101                        'left': ($('.mobilezoom__holder').width() + 20) + 'px',
102                        'top': (($('.mobilezoom__holder').height() - height) / 2) + 'px',
103                        'position': 'absolute'
104                    });
105                } else {
106                    $('.mobilezoom__next-image').find('img').on('load', setPosition);
107                }
108            }
109            setPosition();
110
111        }
112
113        function showPrev(element){
114            element = $(element);
115            var url;
116            if(element.is('img')){
117                url = element.attr('src');
118            } else {
119                url = element.attr('href');
120            }
121            $('.mobilezoom__holder').append('<div class="mobilezoom__prev-image"><img src="'+ url +'" /></div>');
122
123            function setPosition(){
124                var width = $('.mobilezoom__prev-image').find('img').width();
125                var height = $('.mobilezoom__prev-image').find('img').height();
126                var naturalWidth = $('.mobilezoom__prev-image').find('img').get(0).naturalWidth;
127                var naturalHeight = $('.mobilezoom__prev-image').find('img').get(0).naturalHeight;
128
129                if(naturalWidth > 0){
130                    $('.mobilezoom__prev-image').data('nwidth', naturalWidth).data('nheight', naturalHeight);
131                    $('.mobilezoom__prev-image').width('width').height('height').css({
132                        'left': (- $('.mobilezoom__holder').width() - settings.marginbetween) + 'px',
133                        'top': (($('.mobilezoom__holder').height() - height) / 2) + 'px',
134                        'position': 'absolute'
135                    });
136                } else {
137                    $('.mobilezoom__prev-image').find('img').on('load', setPosition);
138                }
139            }
140            setPosition();
141        }
142
143        function prepareNext(){
144
145            var gallery = window.mobileZoomGallery;
146            var current = window.mobileZoomCurrent;
147
148            if(!gallery) {
149                return;
150            }
151
152            var current_index = gallery.index(current);
153
154            if(current_index < gallery.length - 1){
155                next = gallery.eq(current_index + 1);
156                showNext(next);
157            } else {
158                next = false;
159            }
160            if(current_index > 0){
161                prev = gallery.eq(current_index - 1);
162                showPrev(prev);
163            } else {
164                prev = false;
165            }
166        }
167
168        function defaultImagePosition(){
169            var width = $('.mobilezoom__image').find('img').width();
170            var height = $('.mobilezoom__image').find('img').height();
171            var naturalWidth = $('.mobilezoom__image').find('img').get(0).naturalWidth;
172            var naturalHeight = $('.mobilezoom__image').find('img').get(0).naturalHeight;
173
174            if(naturalWidth > 0){
175                $('.mobilezoom__image').data('nwidth', naturalWidth).data('nheight', naturalHeight);
176                $('.mobilezoom__image').width('width').height('height').css({
177                    'left': 0,
178                    'top': (($('.mobilezoom__holder').height() - height) / 2) + 'px'
179                });
180            } else {
181                $('.mobilezoom__image').find('img').on('load', defaultImagePosition);
182            }
183        }
184
185        function initTouchEvents(){
186            if($('body').is('.mobilezoom__ready')) return;
187
188            $('body').addClass('mobilezoom__ready');
189
190            touches[0] = {x: false, y: false};
191            touches[1] = {x: false, y: false};
192            touches[99] = {x: false, y: false}; // that's middle point
193
194            $(document).on('touchstart', function(e){
195                touches[0] = {x: e.originalEvent.touches[0].clientX, y: e.originalEvent.touches[0].clientY};
196                touches[99] = touches[0];
197
198                if(e.originalEvent.touches.length > 1){
199                    touches[1] = {x: e.originalEvent.touches[1].clientX, y: e.originalEvent.touches[1].clientY};
200                    touches[99] = {
201                        x: (touches[0].x + touches[1].x) / 2,
202                        y: (touches[0].y + touches[1].y) / 2
203                    }
204                } else {
205                    touches[1] = {x: false, y: false};
206                }
207
208            });
209            $(document).on('touchend', function(e){
210                if(e.originalEvent.touches.length == 0){
211                    touches[0] = {x: false, y: false};
212                    touches[1] = {x: false, y: false};
213                    touches[99] = {x: false, y: false};
214
215                    if(moveStarted){
216                        fitBounds();
217                    }
218
219                    zoomStarted = false;
220                    moveStarted = false;
221                }
222            });
223
224            $(document).on('touchmove', function(e){
225
226                if($('body').is('.mobilezoom__opened')){
227
228                    var previous = $.extend({}, touches);
229                    var zoomDelta = 0;
230                    if(animating) return;
231                    if(!moveStarted){
232                        moveStartPosition = {
233                            x: $('.mobilezoom__image').position().left,
234                            y: $('.mobilezoom__image').position().top
235                        }
236                        moveStarted = true;
237                    }
238
239                    touches[0] = {x: e.originalEvent.touches[0].clientX, y: e.originalEvent.touches[0].clientY};
240                    touches[99] = touches[0];
241
242                    if(e.originalEvent.touches.length > 1){
243                        touches[1] = {x: e.originalEvent.touches[1].clientX, y: e.originalEvent.touches[1].clientY};
244                        touches[99] = {
245                            x: (touches[0].x + touches[1].x) / 2,
246                            y: (touches[0].y + touches[1].y) / 2
247                        }
248
249                        if(!zoomStarted){
250                            zoomStarted = true;
251                            zoomStartTouches = $.extend({}, touches);
252                            zoomStartDistance = getZoomDistance();
253                            zoomStartSize = {
254                                width: $('.mobilezoom__image').width(),
255                                height: $('.mobilezoom__image').height(),
256                                aspect: $('.mobilezoom__image').data('nwidth') / $('.mobilezoom__image').data('nheight')
257                            }
258                        } else {
259                            zoomDelta = getZoomDistance() - zoomStartDistance;
260                        }
261
262                    } else {
263                        if(zoomStarted){
264                            moveStartPosition = {
265                                x: $('.mobilezoom__image').position().left,
266                                y: $('.mobilezoom__image').position().top
267                            }
268                            previous = $.extend({}, touches); // prevent jumping
269
270                        }
271                        touches[1] = {x: false, y: false};
272                        zoomStarted = false;
273                    }
274
275                    var positionDeltaX = touches[99].x - previous[99].x;
276                    var positionDeltaY = touches[99].y - previous[99].y;
277
278                    if(zoomStarted) {
279
280                        var zoomDeltaX = touches[99].x - zoomStartTouches[99].x;
281                        var zoomDeltaY = touches[99].y - zoomStartTouches[99].y;
282
283                        zoomImage(zoomDelta, zoomDeltaX, zoomDeltaY);
284                    } else {
285                        moveImage(positionDeltaX, positionDeltaY);
286                    }
287
288
289                    e.preventDefault();
290                    return false;
291                }
292            });
293
294        }
295
296        function getZoomDistance(){
297            if(touches[1].x != false){
298                return Math.sqrt(Math.pow(touches[0].x - touches[1].x, 2) + Math.pow(touches[0].y - touches[1].y, 2));
299            } else {
300                return false;
301            }
302        }
303
304        function moveImage(x, y){
305            var left = $('.mobilezoom__image').position().left;
306            var top = $('.mobilezoom__image').position().top;
307            $('.mobilezoom__image').css({
308                'left': (left + x) + 'px',
309            });
310            if($('.mobilezoom__image').height() > $('.mobilezoom__holder').height()){
311                $('.mobilezoom__image').css({
312                    'top': (top + y) + 'px'
313                });
314            }
315            $('.mobilezoom__next-image').css({
316                'left': ((left + x) + $('.mobilezoom__image').width() + settings.marginbetween) + 'px'
317            });
318            $('.mobilezoom__prev-image').css({
319                'left': ((left + x) - $('.mobilezoom__prev-image').width() - settings.marginbetween) + 'px'
320            });
321            if($('.mobilezoom__next-image').length == 1 && $('.mobilezoom__next-image').position().left <= $('.mobilezoom__holder').width() / 1.5){
322                switchToNext();
323            }
324            if($('.mobilezoom__prev-image').length == 1 && $('.mobilezoom__prev-image').position().left >= - $('.mobilezoom__holder').width() / 1.5){
325                switchToPrev();
326            }
327
328
329        }
330
331        function zoomImage(distance, x, y){
332            var xdelta = distance;
333            var ydelta = distance / zoomStartSize.aspect;
334            if(zoomStartSize.aspect < 1){
335                ydelta = distance;
336                xdelta = distance * zoomStartSize.aspect;
337            }
338
339            // Tweaking
340            xdelta*=1.5;
341            ydelta*=1.5;
342
343            $('.mobilezoom__image').css({
344                'width': (zoomStartSize.width + xdelta) + 'px',
345                'height': (zoomStartSize.height + ydelta) + 'px',
346                'left': (moveStartPosition.x - xdelta/2 + x) + 'px',
347                'top': (moveStartPosition.y - ydelta/2 + y) + 'px'
348            });
349        }
350
351        function switchToNext(){
352
353            moveStarted = false;
354            animating = true;
355            var left = $('.mobilezoom__next-image').position().left;
356
357            $('.mobilezoom__next-image').animate({left: 0}, 500);
358            $('.mobilezoom__image').animate({left: '-=' + left}, 500, function(){
359                $('.mobilezoom__prev-image').remove();
360                $('.mobilezoom__image').remove();
361                $('.mobilezoom__next-image').removeClass('mobilezoom__next-image').addClass('mobilezoom__image');
362                window.mobileZoomCurrent = getNext();
363                prepareNext();
364                animating = false;
365            });
366        }
367
368        function getNext(){
369            return window.mobileZoomGallery.eq(window.mobileZoomGallery.index(window.mobileZoomCurrent) + 1);
370        }
371
372        function getPrev(){
373            return window.mobileZoomGallery.eq(window.mobileZoomGallery.index(window.mobileZoomCurrent) - 1);
374        }
375
376        function switchToPrev(){
377            moveStarted = false;
378            animating = true;
379            var left = $('.mobilezoom__prev-image').position().left;
380
381            $('.mobilezoom__prev-image').animate({left: 0}, 500);
382            $('.mobilezoom__image').animate({left: '+=' + (0-left)}, 500, function(){
383                $('.mobilezoom__next-image').remove();
384                $('.mobilezoom__image').remove();
385                $('.mobilezoom__prev-image').removeClass('mobilezoom__prev-image').addClass('mobilezoom__image');
386                window.mobileZoomCurrent = getPrev();
387                prepareNext();
388                animating = false;
389            });
390        }
391
392        function fitBounds(){
393            var width = $('.mobilezoom__image').width();
394            var height = $('.mobilezoom__image').height();
395            var nwidth = $('.mobilezoom__image').data('nwidth');
396            var nheight = $('.mobilezoom__image').data('nheight');
397            var x = $('.mobilezoom__image').position().left;
398            var y = $('.mobilezoom__image').position().top;
399            var cwidth = $('.mobilezoom__holder').width();
400            var cheight = $('.mobilezoom__holder').height();
401            var aspect = nwidth/nheight;
402            var caspect = cwidth/cheight;
403
404            var maxZoom = 1;
405
406            if(width < cwidth && height < cheight){
407                // To small. Fit to window.
408
409                if(aspect > caspect){
410                    $('.mobilezoom__image').animate({
411                        'width': cwidth + 'px',
412                        'height': (cwidth / aspect) + 'px',
413                        'left': 0,
414                        'top': ((cheight - cwidth / aspect) / 2) + 'px'
415                    }, 300);
416                } else {
417                    $('.mobilezoom__image').animate({
418                        'height': cheight + 'px',
419                        'width': (cheight * aspect) + 'px',
420                        'top': 0,
421                        'left': ((cwidth - cheight * aspect) / 2) + 'px'
422                    }, 300);
423                }
424            } else {
425                // Fit to bounds
426                if(width >= cwidth) {
427                    var xnew;
428                    if(x > 0) xnew = 0;
429                    if(x + width < cwidth) xnew = cwidth - width;
430                } else {
431                    var xnew = (cwidth - width) / 2;
432                }
433                if(height >= cheight) {
434                    var ynew;
435                    if(y > 0) ynew = 0;
436                    if(y + height < cheight) ynew = cheight - height;
437                } else {
438                    var ynew = (cheight - height) / 2;
439                }
440                if(x != xnew || y != ynew){
441                    $('.mobilezoom__image').animate({'top': ynew + 'px', 'left': xnew + 'px'}, 300);
442                    $('.mobilezoom__next-image').animate({'left': (cwidth + settings.marginbetween) + 'px'}, 300);
443                    $('.mobilezoom__prev-image').animate({'left': (-cwidth - settings.marginbetween) + 'px'}, 300);
444                }
445            }
446
447            if(width > nwidth * maxZoom || height > nheight * maxZoom){
448                // Too big. Zooming to maxZoom
449                $('.mobilezoom__image').animate({
450                    'width': nwidth * maxZoom + 'px',
451                    'height': nheight * maxZoom + 'px',
452                    'left': "+=" + (width - nwidth * maxZoom)/2,
453                    'top': "+=" + (height - nheight * maxZoom)/2
454                }, 300);
455            }
456
457        }
458
459    };
460});

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.