1(function ($) { 2 3 $.fn.twentytwenty = function (options) { 4 var options = $.extend({ 5 default_offset_pct: 0.5, 6 orientation: 'horizontal', 7 before_label: 'Before', 8 after_label: 'After', 9 no_overlay: false, 10 move_slider_on_hover: false, 11 move_with_handle_only: true, 12 click_to_move: false 13 }, options); 14 15 return this.each(function () { 16 17 var sliderPct = options.default_offset_pct; 18 var container = $(this); 19 var sliderOrientation = options.orientation; 20 var beforeDirection = (sliderOrientation === 'vertical') ? 'down' : 'left'; 21 var afterDirection = (sliderOrientation === 'vertical') ? 'up' : 'right'; 22 23 24 container.wrap("<div class='twentytwenty-wrapper twentytwenty-" + sliderOrientation + "'></div>"); 25 if (!options.no_overlay) { 26 container.append("<div class='twentytwenty-overlay'></div>"); 27 } 28 var beforeImg = container.find("img:first"); 29 var afterImg = container.find("img:last"); 30 container.append("<div class='twentytwenty-handle'></div>"); 31 var slider = container.find(".twentytwenty-handle"); 32 slider.append("<span class='twentytwenty-" + beforeDirection + "-arrow'></span>"); 33 slider.append("<span class='twentytwenty-" + afterDirection + "-arrow'></span>"); 34 container.addClass("twentytwenty-container"); 35 beforeImg.addClass("twentytwenty-before"); 36 afterImg.addClass("twentytwenty-after"); 37 38 var overlay = container.find(".twentytwenty-overlay"); 39 overlay.append("<div class='twentytwenty-before-label' data-content='" + options.before_label + "'></div>"); 40 overlay.append("<div class='twentytwenty-after-label' data-content='" + options.after_label + "'></div>"); 41 42 var calcOffset = function (dimensionPct) { 43 var w = beforeImg.width(); 44 var h = beforeImg.height(); 45 return { 46 w: w + "px", 47 h: h + "px", 48 cw: (dimensionPct * w) + "px", 49 ch: (dimensionPct * h) + "px" 50 }; 51 }; 52 53 var adjustContainer = function (offset) { 54 if (sliderOrientation === 'vertical') { 55 beforeImg.css("clip", "rect(0," + offset.w + "," + offset.ch + ",0)"); 56 afterImg.css("clip", "rect(" + offset.ch + "," + offset.w + "," + offset.h + ",0)"); 57 } 58 else { 59 beforeImg.css("clip", "rect(0," + offset.cw + "," + offset.h + ",0)"); 60 afterImg.css("clip", "rect(0," + offset.w + "," + offset.h + "," + offset.cw + ")"); 61 } 62 container.css("height", offset.h); 63 }; 64 65 var adjustSlider = function (pct) { 66 var offset = calcOffset(pct); 67 slider.css((sliderOrientation === "vertical") ? "top" : "left", (sliderOrientation === "vertical") ? offset.ch : offset.cw); 68 adjustContainer(offset); 69 }; 70 71 // Return the number specified or the min/max number if it outside the range given. 72 var minMaxNumber = function (num, min, max) { 73 return Math.max(min, Math.min(max, num)); 74 }; 75 76 // Calculate the slider percentage based on the position. 77 var getSliderPercentage = function (positionX, positionY) { 78 var sliderPercentage = (sliderOrientation === 'vertical') ? 79 (positionY - offsetY) / imgHeight : 80 (positionX - offsetX) / imgWidth; 81 82 return minMaxNumber(sliderPercentage, 0, 1); 83 }; 84 85 86 $(window).on("resize.twentytwenty", function (e) { 87 adjustSlider(sliderPct); 88 }); 89 90 var offsetX = 0; 91 var offsetY = 0; 92 var imgWidth = 0; 93 var imgHeight = 0; 94 var onMoveStart = function (e) { 95 if (((e.distX > e.distY && e.distX < -e.distY) || (e.distX < e.distY && e.distX > -e.distY)) && sliderOrientation !== 'vertical') { 96 e.preventDefault(); 97 } 98 else if (((e.distX < e.distY && e.distX < -e.distY) || (e.distX > e.distY && e.distX > -e.distY)) && sliderOrientation === 'vertical') { 99 e.preventDefault(); 100 } 101 container.addClass("active"); 102 offsetX = container.offset().left; 103 offsetY = container.offset().top; 104 imgWidth = beforeImg.width(); 105 imgHeight = beforeImg.height(); 106 }; 107 var onMove = function (e) { 108 if (container.hasClass("active")) { 109 sliderPct = getSliderPercentage(e.pageX, e.pageY); 110 adjustSlider(sliderPct); 111 } 112 }; 113 var onMoveEnd = function () { 114 container.removeClass("active"); 115 }; 116 117 var moveTarget = options.move_with_handle_only ? slider : container; 118 moveTarget.on("movestart", onMoveStart); 119 moveTarget.on("move", onMove); 120 moveTarget.on("moveend", onMoveEnd); 121 122 if (options.move_slider_on_hover) { 123 container.on("mouseenter", onMoveStart); 124 container.on("mousemove", onMove); 125 container.on("mouseleave", onMoveEnd); 126 } 127 128 slider.on("touchmove", function (e) { 129 e.preventDefault(); 130 }); 131 132 container.find("img").on("mousedown", function (event) { 133 event.preventDefault(); 134 }); 135 136 if (options.click_to_move) { 137 container.on('click', function (e) { 138 offsetX = container.offset().left; 139 offsetY = container.offset().top; 140 imgWidth = beforeImg.width(); 141 imgHeight = beforeImg.height(); 142 143 sliderPct = getSliderPercentage(e.pageX, e.pageY); 144 adjustSlider(sliderPct); 145 }); 146 } 147 148 $(window).trigger("resize.twentytwenty"); 149 }); 150 }; 151 152})(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.