PageSourceSearch

https://www.ettoi.pl/modules/advanceblog/views/js/unitegallery/js/ug-zoomslider.js

js ettoi.pl collected 2026-10-06 13:12:01 UTC 19,168 bytes, 858 lines download raw bytes

1/**
2* The MIT License (MIT)
3*
4* Copyright (c) 2015 Max Valiano | http://unitegallery.net
5*
6* Permission is hereby granted, free of charge, to any person
7* obtaining a copy of this software and associated documentation
8* files (the "Software"), to deal in the Software without
9* restriction, including without limitation the rights to use,
10* copy, modify, merge, publish, distribute, sublicense, and/or sell
11* copies of the Software, and to permit persons to whom the
12* Software is furnished to do so, subject to the following
13* conditions:
14*
15* The above copyright notice and this permission notice shall be
16* included in all copies or substantial portions of the Software.
17*
18* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25* OTHER DEALINGS IN THE SOFTWARE.
26*
27* @author    Max Valiano
28* @copyright Copyright (c) 2017 Max Valiano | http://unitegallery.net
29* @license   The MIT License (MIT)
30*/
31
32/**
33 * touch thumbs control class
34 * addon to strip gallery
35 */
36function UGZoomSliderControl(){
37
38	var g_objSlider, g_objInner, g_parent = new UGSlider(), g_objParent;
39
40	var g_functions = new UGFunctions();
41
42	var t = this;
43
44	var g_options = {
45		slider_zoom_step: 1.2,							//the step of zooming with mouse wheel or zoom button
46		slider_zoom_max_ratio: 6,						//max zoom ratio
47		slider_zoom_return_pan_duration: 400,			//the return from pan animation duration
48		slider_zoom_return_pan_easing: "easeOutCubic"	//the return from pan wasing function
49	};
50
51	var g_temp = {
52		isPanActive:false,
53		startMouseX:0,
54		startMouseY:0,
55		lastMouseX:0,
56		lastMouseY:0,
57		startImageX:0,
58		startImageY:0,
59		panXActive:false,
60		panYActive:false,
61		objImage:null,
62		objImageSize:null,
63		objParent:null,
64		objParentSize:null,
65		objSlide:null,
66		storeImageLastTime:0,
67
68		isZoomActive: false,
69		startDistance:0,
70		startMiddlePoint:null,
71		imageOrientPoint:null,
72		objFitImageSize:null,
73		isZoomedOnce:false
74	};
75
76
77	/**
78	 * init the object
79	 */
80	function initObject(objSlider, customOptions){
81
82		g_parent = objSlider;
83		g_objParent = jQuery(g_parent);
84		g_objects = objSlider.getObjects();
85		g_objSlider = g_objects.g_objSlider;
86		g_objInner = g_objects.g_objInner;
87
88		g_options = jQuery.extend(g_options, customOptions);
89
90		initEvents();
91	}
92
93
94	/**
95	 * get fit image to slider scale mode
96	 * the fill become fit
97	 */
98	function getFitScaleMode(){
99
100		var scaleMode = g_parent.getScaleMode();
101
102		if(scaleMode != "down")
103			scaleMode = "fit";
104
105		return(scaleMode);
106	}
107
108
109	/**
110	 * cache current slide and image
111	 */
112	function storeCurrentImage(){
113
114		//prevent continious image storring
115		var currentTime = jQuery.now();
116		var diff = currentTime - g_temp.storeImageLastTime;
117
118		if(diff < 20)
119			return(false);
120
121		var slides = g_parent.getSlidesReference();
122		g_temp.objSlide = slides.objCurrentSlide;
123		g_temp.objImage = slides.objCurrentSlide.find("img");
124
125		if(g_temp.objImage.length == 0)
126			return(false);
127
128		g_temp.objImageSize = g_functions.getElementSize(g_temp.objImage);
129		g_temp.objParent = g_temp.objImage.parent();
130		g_temp.objParentSize = g_functions.getElementSize(g_temp.objParent);
131
132		var scaleMode = getFitScaleMode();
133
134		objPadding = g_parent.getObjImagePadding();
135
136		g_temp.objFitImageSize = g_functions.getImageInsideParentDataByImage(g_temp.objImage, scaleMode, objPadding);
137
138		var currentTime = jQuery.now();
139		g_temp.storeImageLastTime = currentTime;
140
141		return(true);
142	}
143
144
145	/**
146	 * zoom current image
147	 * mode: in, out, back
148	 */
149	function zoomCurrentImage(mode, mousePos){
150
151		var slides = g_parent.getSlidesReference();
152		var objImage = slides.objCurrentSlide.find("img");
153		var scaleMode = getFitScaleMode();
154
155		g_objParent.trigger(g_parent.events.ZOOM_START);
156
157		//flag if the images zoomed
158		var isZoomed = true;
159
160		var objPadding = g_parent.getObjImagePadding();
161
162		if(mode == "back"){
163			var objOriginalSize = g_functions.getImageOriginalSize(objImage);
164			g_functions.scaleImageFitParent(objImage, objOriginalSize.width, objOriginalSize.height, scaleMode, objPadding);
165		}
166		else{
167			var zoomIn = (mode == "in")?true:false;
168
169			isZoomed = g_functions.zoomImageInsideParent(objImage, zoomIn, g_options.slider_zoom_step, mousePos, scaleMode, g_options.slider_zoom_max_ratio, objPadding);
170		}
171
172		if(isZoomed == true){
173			g_objParent.trigger(g_parent.events.ZOOMING);
174			g_objParent.trigger(g_parent.events.ZOOM_CHANGE);
175			g_objParent.trigger(g_parent.events.ZOOM_END);
176		}
177
178	}
179
180
181	function ____________PAN_____________(){};
182
183
184	/**
185	 * check if pan is posible for the current image
186	 * check if the image is bigger then the parent
187	 */
188	function isPanPosible(objImage, event, stictTouchesCheck){
189
190		//check num touches, strict means that even if 0 - pan not posible
191		var arrTouches = g_functions.getArrTouches(event);
192
193		if(stictTouchesCheck === true){
194
195			if(arrTouches.length != 1)
196				return(false);
197		}else{
198			if(arrTouches.length > 1)
199				return(false);
200		}
201
202		if(g_functions.isElementBiggerThenParent(objImage))
203			return(true);
204
205		return(false);
206	}
207
208
209	/**
210	 * store pan values
211	 */
212	function storePanInitValues(event){
213
214		var mousePos = g_functions.getMousePosition(event);
215
216		g_temp.startMouseX = mousePos.pageX;
217		g_temp.startMouseY = mousePos.pageY;
218
219		g_temp.lastMouseX = g_temp.startMouseX;
220		g_temp.lastMouseY = g_temp.startMouseY;
221
222		g_temp.startImageX = g_temp.objImageSize.left;
223		g_temp.startImageY = g_temp.objImageSize.top;
224
225		g_temp.panXActive = (g_temp.objImageSize.width > g_temp.objParentSize.width);
226		g_temp.panYActive = (g_temp.objImageSize.height > g_temp.objParentSize.height);
227
228	}
229
230
231	/**
232	 * check pan start, and start if posible
233	 */
234	function startPan(event){
235
236		g_temp.isPanActive = true;
237		storePanInitValues(event);
238
239	}
240
241
242	/**
243	 * pan the image
244	 */
245	function panImage(event){
246
247		if(g_temp.objImage == undefined || g_temp.objImage.length == 0)
248			return(true);
249
250		var mousePos = g_functions.getMousePosition(event);
251
252		var diffX = mousePos.pageX - g_temp.startMouseX;
253		var diffY = mousePos.pageY - g_temp.startMouseY;
254
255		//get active direction
256		var diffLastX = mousePos.pageX - g_temp.lastMouseX;
257		var diffLastY = mousePos.pageY - g_temp.lastMouseY;
258
259		var directionX = (diffLastX < 0) ? "left":"right";
260		var directionY = (diffLastY < 0) ? "up":"down";
261
262		g_temp.lastMouseX = mousePos.pageX;
263		g_temp.lastMouseY = mousePos.pageY;
264
265		var posImage = g_functions.getElementSize(g_temp.objImage);
266
267		//var imageX = g_temp.startImageX + diffX;
268		//var imageY = g_temp.startImageY + diffY;
269
270
271		//slow down if no pan available in this point
272		//slow down y
273
274		if(g_temp.panYActive == false){
275
276			diffLastY = 0;
277
278		}else{		//zoom enabled
279
280			if(directionY == "down" && posImage.top > 0){
281
282				diffLastY = diffLastY / 3;
283
284			}else if(directionY == "up" && posImage.bottom < g_temp.objParentSize.height){
285
286				diffLastY = diffLastY / 3;
287
288			}
289		}
290
291		//slow down x (only if the pan enabled)
292		if(g_temp.panXActive == false || g_parent.isInnerInPlace() == false){
293
294			diffLastX = 0;
295
296		}else{	//zoom enabled
297
298			if(directionX == "right" && posImage.left > 0){
299				diffLastX = diffLastX / 3;
300			}
301			else if(directionX == "left" && posImage.right < g_temp.objParentSize.width){
302				diffLastX = diffLastX / 3;
303			}
304	    }
305
306		var imageX = posImage.left + diffLastX;
307		var imageY = posImage.top + diffLastY;
308
309
310		g_functions.placeElement(g_temp.objImage, imageX, imageY);
311
312	}
313
314
315
316
317	/**
318	 * return the image to place if it's out of borders
319	 */
320	function checkReturnAfterPan(){
321
322		var isReturnX = false, isReturnY = false, newX = 0, newY = 0;
323		var objSize = g_functions.getElementSize(g_temp.objImage);
324		var objImagePadding = g_parent.getObjImagePadding();
325
326		var objCenterPos = g_functions.getElementCenterPosition(g_temp.objImage, objImagePadding);
327
328		g_temp.panXActive = (g_temp.objImageSize.width > g_temp.objParentSize.width);
329		g_temp.panYActive = (g_temp.objImageSize.height > g_temp.objParentSize.height);
330
331
332		if(g_temp.panYActive == true){
333
334			if(objSize.top > 0){		//off limit top
335
336				newY = 0;
337				isReturnY = true;
338
339			}else if(objSize.bottom < g_temp.objParentSize.height){		//off limit bottom
340
341				newY = g_temp.objParentSize.height - objSize.height;
342				isReturnY = true;
343
344			}
345
346		}else{		//pan not active y - return to center
347
348			if(objSize.top != objCenterPos.top){
349				isReturnY = true;
350				newY = objCenterPos.top;
351			}
352
353		}
354
355
356		//check return x to place
357		if(g_temp.panXActive == true){
358
359			if(objSize.left > 0){		//off limit left
360
361				newX = 0;
362				isReturnX = true;
363
364			}else if(objSize.right < g_temp.objParentSize.width){		//off limit right
365
366				newX = g_temp.objParentSize.width - objSize.width;
367				isReturnX = true;
368
369			}
370
371		}else{		//pan not active x - return to center
372
373		//	debugLine("not active", true);
374
375			if(objSize.left != objCenterPos.left){
376				isReturnX = true;
377				newX = objCenterPos.left;
378			}
379		}
380
381
382		//do the animation
383		var objCss = {};
384		if(isReturnY == true)
385			objCss.top = newY + "px";
386
387		if(isReturnX == true)
388			objCss.left = newX + "px";
389
390
391		if(isReturnY == true || isReturnX == true){
392
393			g_temp.objImage.animate(objCss,{
394				duration: g_options.slider_zoom_return_pan_duration,
395				easing: g_options.slider_zoom_return_pan_easing,
396				queue: false
397			});
398
399		}
400
401	}
402
403	/**
404	 * check if the image animating or not
405	 */
406	function isImageAnimating(){
407
408		if(g_temp.objImage && g_temp.objImage.is(":animated"))
409			return(true);
410
411		return(false);
412	}
413
414	function ____________END_PAN_____________(){};
415
416	function ________TOUCH_ZOOM_____________(){};
417
418	/**
419	 * start touch zoom
420	 */
421	function startTouchZoom(arrTouches){
422
423		g_temp.isZoomActive = true;
424
425		//store init diff
426		g_temp.startDistance = g_functions.getDistance(arrTouches[0].pageX, arrTouches[0].pageY, arrTouches[1].pageX, arrTouches[1].pageY);
427		if(g_temp.startDistance == 0)
428			g_temp.startDistance = 1;
429
430
431		//store init positions
432		g_temp.startMiddlePoint = g_functions.getMiddlePoint(arrTouches[0].pageX, arrTouches[0].pageY, arrTouches[1].pageX, arrTouches[1].pageY);
433
434		g_temp.objImageSize = g_functions.getElementSize(g_temp.objImage);
435
436		g_temp.startImageX = g_temp.objImageSize.left;
437		g_temp.startImageY = g_temp.objImageSize.top;
438
439		//set orient point
440		g_temp.imageOrientPoint = g_functions.getElementLocalPoint(g_temp.startMiddlePoint, g_temp.objImage);
441
442		var isInsideImage = g_functions.isPointInsideElement(g_temp.imageOrientPoint, g_temp.objImageSize);
443		if(isInsideImage == false){
444			g_temp.imageOrientPoint = g_functions.getElementCenterPoint(g_temp.objImage);
445		}
446
447		//trigger start zoom event
448		g_objParent.trigger(g_parent.events.ZOOM_START);
449	}
450
451
452	/**
453	 * check num touches, if not 2 - end zoom
454	 */
455	function checkTouchZoomEnd(event){
456
457		if(g_temp.isZoomActive == false)
458			return(false);
459
460		var arrTouches = g_functions.getArrTouches(event);
461		if(arrTouches.length != 2){		//end touch zoom
462
463			g_temp.isZoomActive = false;
464
465			//trigger end zoom event
466			g_objParent.trigger(g_parent.events.ZOOM_END);
467		}
468
469	}
470
471
472	/**
473	 * check start touch zoom
474	 */
475	function checkTouchZoomStart(event){
476
477		if(g_temp.isZoomActive == true)
478			return(true);
479
480
481		var arrTouches = g_functions.getArrTouches(event);
482
483		if(arrTouches.length != 2)
484			return(true);
485
486		startTouchZoom(arrTouches);
487	}
488
489
490	/**
491	 * do touch zoom on touch devices
492	 */
493	function doTouchZoom(event){
494
495		var arrTouches = g_functions.getArrTouches(event);
496
497		var distance = g_functions.getDistance(arrTouches[0].pageX, arrTouches[0].pageY, arrTouches[1].pageX, arrTouches[1].pageY);
498		var zoomRatio = distance / g_temp.startDistance;
499
500		var middlePoint = g_functions.getMiddlePoint(arrTouches[0].pageX, arrTouches[0].pageY, arrTouches[1].pageX, arrTouches[1].pageY);
501
502		//set zoom data:
503		var newWidth = g_temp.objImageSize.width * zoomRatio;
504		var newHeight = g_temp.objImageSize.height * zoomRatio;
505
506		//check max zoom ratio:
507		var objOriginalSize = g_functions.getImageOriginalSize(g_temp.objImage);
508		var expectedZoomRatio = 1;
509		if(objOriginalSize.width > 0)
510			expectedZoomRatio = newWidth / objOriginalSize.width;
511
512		if(expectedZoomRatio > g_options.slider_zoom_max_ratio)
513			return(true);
514
515		//set pan data:
516		panX = -(g_temp.imageOrientPoint.x * zoomRatio - g_temp.imageOrientPoint.x);
517		panY = -(g_temp.imageOrientPoint.y * zoomRatio - g_temp.imageOrientPoint.y);
518
519		var diffMiddleX = (middlePoint.x - g_temp.startMiddlePoint.x);
520	    var diffMiddleY = (middlePoint.y - g_temp.startMiddlePoint.y);
521
522	    var posx = g_temp.startImageX + panX + diffMiddleX;
523		var posy = g_temp.startImageY + panY + diffMiddleY;
524
525
526		//resize and place:
527		g_functions.setElementSizeAndPosition(g_temp.objImage, posx, posy, newWidth, newHeight);
528
529		//trigger zooming event
530		g_objParent.trigger(g_parent.events.ZOOMING);
531		g_objParent.trigger(g_parent.events.ZOOM_CHANGE);
532
533		/*
534		debugLine({
535			middleStartX: g_temp.startMiddlePoint.x,
536			middleX: middlePoint.x,
537			diffMiddleX: diffMiddleX
538		});
539		*/
540
541	}
542
543
544	/**
545	 * check return the image from zoom
546	 */
547	function checkReturnFromZoom(){
548
549		if(g_temp.objImage == undefined || g_temp.objImage.length == 0)
550			return(true);
551
552		var objSize = g_functions.getElementSize(g_temp.objImage);
553
554		if(objSize.width < g_temp.objFitImageSize.imageWidth){
555
556			g_temp.objImage.css({
557				position:"absolute",
558				margin:"none"
559			});
560
561			var objCss = {
562				top: g_temp.objFitImageSize.imageTop + "px",
563				left: g_temp.objFitImageSize.imageLeft + "px",
564				width: g_temp.objFitImageSize.imageWidth + "px",
565				height: g_temp.objFitImageSize.imageHeight + "px"
566			};
567
568			g_temp.objImage.animate(objCss,{
569				duration: g_options.slider_zoom_return_pan_duration,
570				easing: g_options.slider_zoom_return_pan_easing,
571				queue: false
572			});
573
574		}else{
575			checkReturnAfterPan();
576		}
577
578	}
579
580
581	function ________END_TOUCH_ZOOM_____________(){};
582
583
584	/**
585	 *
586	 * touch start event - start pan, remember start pan data
587	 */
588	function onTouchStart(event){
589
590		//if no image type, exit
591		if(g_parent.isCurrentSlideType("image") == false)
592			return(true);
593
594		var isStored = storeCurrentImage();
595
596		if(g_temp.objImage == undefined || g_temp.objImage.length == 0)
597			return(true);
598
599		event.preventDefault();
600
601		//stop animation if exists
602		if(isImageAnimating() == true){
603			g_temp.objImage.stop(true);
604		}
605
606		if(g_temp.isZoomActive == true){
607
608			checkTouchZoomEnd(event);
609
610		}else{
611
612			checkTouchZoomStart(event);
613
614		}
615
616		//if zoom started stop panning, if not, start panning
617		if(g_temp.isZoomActive == true){
618
619			g_temp.isPanActive = false;
620
621		}else if(isPanPosible(g_temp.objImage, event) == true && g_temp.isZoomedOnce == true){
622
623			startPan(event);
624		}
625
626		/*
627		debugLine({
628				pan: g_temp.isPanActive,
629				zoom: g_temp.isZoomActive,
630				event: "start"
631			}, true);
632		*/
633
634	}
635
636
637	/**
638	 * touch end event - bring the image to place
639	 */
640	function onTouchEnd(event){
641
642		if(g_parent.isCurrentSlideType("image") == false)
643			return(true);
644
645		//check if some gallery button clicked
646		var objTarget = jQuery(event.target);
647		if(objTarget.data("ug-button") == true){
648			//event.preventDefault();
649			return(false);
650		}
651
652		var isStored = storeCurrentImage();
653
654		if(g_temp.objImage == undefined || g_temp.objImage.length == 0)
655			return(true);
656
657		var panWasActive = g_temp.isPanActive;
658		var zoomWasActive = g_temp.isZoomActive;
659
660		//if the inner not in place, don't return noting, let the slide change
661		if(g_parent.isInnerInPlace() == false){
662			g_temp.isZoomActive = false;
663			g_temp.isPanActive = false;
664			return(true);
665		}
666
667		//check end zoom
668		if(g_temp.isZoomActive == true){
669			checkTouchZoomEnd(event);
670		}else{
671			checkTouchZoomStart(event);
672		}
673
674
675		if(g_temp.isZoomActive == true){
676
677			g_temp.isPanActive = false;
678
679		}else{
680
681			var panPosible = isPanPosible(g_temp.objImage, event, true);
682
683			if(g_temp.isPanActive == true ){
684
685				g_temp.isPanActive = false;
686
687			}else if(panPosible == true){
688
689				startPan(event);
690			}
691
692		}
693
694		/*
695		debugLine({
696			pan:g_temp.isPanActive,
697			zoom: g_temp.isZoomActive
698		}, true);
699		*/
700
701		if((panWasActive || zoomWasActive) && g_temp.isZoomActive == false && g_temp.isPanActive == false){
702			checkReturnFromZoom();
703		}
704
705
706	}
707
708
709	/**
710	 *
711	 * touch move event - pan
712	 */
713	function onTouchMove(event){
714
715		if(g_parent.isCurrentSlideType("image") == false)
716			return(true);
717
718		//check touch zoom (pinch gesture)
719		if(g_temp.isZoomActive == true){
720
721			doTouchZoom(event);
722
723		}else if(g_temp.isPanActive == true){
724
725			panImage(event);
726
727		}
728
729
730	}
731
732
733	/**
734	 * on slider mousewheel event
735	 */
736	function onSliderMouseWheel(event, delta, deltaX, deltaY){
737
738		if(g_options.slider_zoom_mousewheel == false)
739			return(true);
740
741		if(g_parent.isCurrentSlideType("image") == false)
742			return(true);
743
744		event.preventDefault();
745
746		//prevent default only if needed
747		//if(zoomIn == true || zoomIn == false && g_functions.isElementBiggerThenParent(objImage))
748		//event.preventDefault();
749
750
751		var zoomIn = (delta > 0);
752		var mousePos = g_functions.getMousePosition(event);
753		var	mode = (zoomIn == true) ? "in":"out";
754
755		zoomCurrentImage(mode, mousePos);
756	}
757
758
759	/**
760	 * init touch events
761	 */
762	function initEvents(){
763
764		//debugLine("init");
765		g_objSlider.on("mousewheel",onSliderMouseWheel);
766
767		//slider mouse down - pan start
768		g_objSlider.bind("mousedown touchstart",onTouchStart);
769
770		//on body move
771		jQuery("body").bind("mousemove touchmove",onTouchMove);
772
773		//on body mouse up - pan end
774		jQuery(window).add("body").bind("mouseup touchend", onTouchEnd);
775
776		//event before image returned to init position
777		g_objParent.bind(g_parent.events.BEFORE_RETURN, function(){
778
779			checkReturnFromZoom();
780		});
781
782		//on item change update isZoomedOnce event. Allow panning only if zoomed once
783		g_objParent.bind(g_parent.events.ITEM_CHANGED, function(){
784			g_temp.isZoomedOnce = false;
785		});
786
787		g_objParent.bind(g_parent.events.ZOOM_CHANGE, function(){
788			g_temp.isZoomedOnce = true;
789		});
790
791	}
792
793	this.________EXTERNAL_____________ = function(){};
794
795	/**
796	 * check if the image is zoomed, and there is a place for left panning
797	 */
798	this.isPanEnabled = function(event, direction){
799
800		storeCurrentImage();
801
802		if(g_temp.objImage == undefined || g_temp.objImage.length == 0)
803			return(false);
804
805		if(g_temp.isZoomedOnce == false)
806			return(false);
807
808		if(isPanPosible(g_temp.objImage, event) == false)
809			return(false);
810
811		if(g_parent.isInnerInPlace() == false)
812			return(false);
813
814		if(direction == "left"){
815
816			if(g_temp.objImageSize.right <= g_temp.objParentSize.width)
817				return(false);
818
819		}else{	//right direction
820
821			if(g_temp.objImageSize.left >= 0)
822				return(false);
823		}
824
825		return(true);
826	}
827
828
829	/**
830	 * init function for avia controls
831	 */
832	this.init = function(objSlider, customOptions){
833
834		initObject(objSlider, customOptions);
835	}
836
837	/**
838	 * zoom in
839	 */
840	this.zoomIn = function(){
841		zoomCurrentImage("in");
842	}
843
844	/**
845	 * zoom out
846	 */
847	this.zoomOut = function(){
848		zoomCurrentImage("out");
849	}
850
851	/**
852	 * zoom back
853	 */
854	this.zoomBack = function(){
855
856		zoomCurrentImage("back");
857	}
858}

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.