From 02ce39edb63dd07086022a17c57ca360aecd956f Mon Sep 17 00:00:00 2001 From: Maksim Krylosov Date: Sun, 15 Jan 2017 17:55:41 +0300 Subject: [PATCH] Release v2.1.0 --- README.md | 66 +++-- abigimage.jquery.css | 297 ++++++++++++++++----- abigimage.jquery.js | 540 +++++++++++++++++++++++++++++++-------- abigimage.jquery.min.css | 4 +- abigimage.jquery.min.js | 4 +- bower.json | 2 +- index.html | 111 ++++++-- package.json | 4 +- test.html | 20 ++ tpl/example.tpl.html | 12 +- tpl/index.tpl.html | 33 +++ 11 files changed, 862 insertions(+), 231 deletions(-) create mode 100644 test.html diff --git a/README.md b/README.md index 1db3882..60f064b 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ `ABigImage` is jQuery plugin for viewing big versions of images. -Current version **2.0.1** (2016-06-07). +Current version **2.1.0** (2017-01-15).
@@ -13,8 +13,8 @@ Current version **2.0.1** (2016-06-07).
-* [abigimage.jquery.js](abigimage.jquery.js) (16.2 kB) [min](abigimage.jquery.min.js) (6.7 kB, gzipped 2.5 kB) -* [abigimage.jquery.css](abigimage.jquery.css) (2.6 kB) [min](abigimage.jquery.min.css) (1.5 kB, gzipped 550 bytes) +* [abigimage.jquery.js](abigimage.jquery.js) (26.9 kB) [min](abigimage.jquery.min.js) (10.2 kB, gzipped 3.6 kB) +* [abigimage.jquery.css](abigimage.jquery.css) (6 kB) [min](abigimage.jquery.min.css) (3.1 kB, gzipped 802 bytes) * Fork at [Github](https://github.com/makryl/ABigImage) ## Features @@ -22,14 +22,15 @@ Current version **2.0.1** (2016-06-07). - Fit mobile devices. - Uses CSS3 transform and transition for smooth touch sliding. - Touch slide left or right opens next or previous image, touch slide up or down closes image. -- Multi-touch and double-tap zoom. +- Multi-touch and double-tap zoom, zoom out closes image. - Clicking image opens next one, clicking left side opens previous, clicking right side closes image. - Hotkeys for next, previous and close buttons. - Closing after viewing of all images. - Preloading of next and previous images. +- Images counter. - Uses link's `href` or `data-href` attribute for large images. - Fully customizable styles. -- Customizable bottom area. +- Customizable, scrolling down bottom area. - Customizable `onopen` and `onclose` event. @@ -66,19 +67,23 @@ $(function(){ ### Options -- `fadeIn` - fade in duration or [options](http://api.jquery.com/fadein/) (default: `fast`). -- `fadeOut` - fade out duration or [options](http://api.jquery.com/fadeout/) (default: `fast`). +- `duration` - effects duration (default: `200`). - `slideWidth` - slide width to switch or close image (between 0 and 1, default: 0.4). - `slideVelocity` - slide velocity to switch or close image (pixels per millisecond, default: 0.4). - `zoomMin` - minimal zoom that will hold (default: 1.5). - `zoomMax` - maximal zoom (default: 5). -- `zoomScrollMultiplier` - how much zoom on mouse scroll (default: 1.25). +- `zoomClose` - zoom that will close image (default: 0.9). +- `zoomMoveViewport` - area for mouse moving when zoomed (default: 0.9). +- `zoomVelocity` - zoom velocity on scroll or press button (pixels per millisecond, default: .04). - `doubleTapInterval` - zoom double-tap interval (milliseconds, default: 400). - `prevBtnHtml` - html of "previous" button (default: `←`). -- `closeBtnHtml` - html of "close" button (default: `x`). +- `nextBtnHtml` - html of "next" button (default: `→`). +- `zoomInBtnHtml` - html of "zoom in" button (default: `+`). +- `zoomOutBtnHtml` - html of "zoom out" button (default: `−`). +- `closeBtnHtml` - html of "close" button (default: `×`). - `keyNext` - hotkeys for "next" button (default: 13 enter, 32 space, 39 right, 40 down). - `keyPrev` - hotkeys for "previous" button (default: 8 backspace, 37 left, 38 up). -- `keyNext` - hotkeys for "close" button (default: 27 escape, 35 end, 36 home). +- `keyClose` - hotkeys for "close" button (default: 27 escape, 35 end, 36 home). - `onopen` - function called when image opens. - `onclose` - function called when image closes. @@ -87,18 +92,28 @@ To change styles use CSS classes of plugin's elements: ```html
-
- -
- -
- - - +
+
+ +
+ +
+ + + +
+
+
+
+
+
+
+
+
+
+
+
-
-
-
``` @@ -110,7 +125,10 @@ Function, defined as `onopen` handler, executes in context of plugin, and receiv $('a[href$=".jpg"]').abigimage({ onopen: function (target) { this.bottom.html( - $('img', target).attr('alt') + /* bottom caption */ + $('img', target).attr('alt') + + /* custom bottom area */ + ($('span', target).html() || '') ); } }); @@ -168,8 +186,8 @@ $.abigimage.unbind($myimgs1); ``` ## Changes - -- **2.1.0** - improved zoom positioning, added mouse scroll zoom, fixed prevention of non-plugin's hotkeys. + +- **2.1.0** - improved animations for not fully loaded images, improved zoom positioning, added mouse scroll zoom, added scrolling down bottom area, added zoom out closing, added next and zoom buttons, added loading spinner, added images counter, fixed prevention of non-plugin's hotkeys. - **2.0.0** - fixed multiple plugin instances context, added double-tap zoom, optimized touch event handlers, styles moved to CSS file, license changed to MIT. - **1.3.1** - fixed image caching, added `unbind` method. diff --git a/abigimage.jquery.css b/abigimage.jquery.css index 2b0f5b8..fb7551e 100644 --- a/abigimage.jquery.css +++ b/abigimage.jquery.css @@ -6,147 +6,310 @@ * Copyright (c) 2014-2016 Maksim Krylosov */ -.abigimage-overlay { +/*.abigimage-body {*/ + /*position: fixed;*/ + /*width: 100%;*/ +/*}*/ + +.abigimage-layout { position: fixed; z-index: 100; top: 0; right: 0; bottom: 0; left: 0; - background-color: #000; - border: 1px solid #000; /* android chrome fix O_o */ - opacity: .9; + + /*transition: opacity .2s ease-in-out, height .2s step-end;*/ + height: 0; + opacity: 0; + /*display: none;*/ + + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + -ms-transform: translate3d(0, 0, 0); + -o-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + + overflow: hidden; + overflow-y: auto; } -.abigimage-layout { +.abigimage-layout-active { + /*transition: opacity .2s ease-in-out, height .2s step-start;*/ + height: 100%; + opacity: 1; + /*display: block;*/ +} + +.abigimage-layout-fadeout { + transition: opacity .2s ease-out; + opacity: 0; +} + +/*.abigimage-overscroll {*/ + /*position: fixed;*/ + /*z-index: 100;*/ + /*top: 0;*/ + /*right: 0;*/ + /*bottom: 0;*/ + /*left: 0;*/ + /*overflow-y: scroll;*/ + /*transition: height .2s step-end;*/ + /*height: 0;*/ +/*}*/ + +/*.abigimage-overscroll-active {*/ + /*transition: height .2s step-start;*/ + /*height: 100%;*/ + /*display: block;*/ +/*}*/ + +.abigimage-overlay { position: fixed; z-index: 100; top: 0; right: 0; bottom: 0; left: 0; - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); - line-height: 2.5; + background-color: #000; + background-color: rgba(0, 0, 0, .9); + + /*transition: opacity .2s ease-in-out, height .2s step-end;*/ + height: 0; + opacity: 0; + /*display: none;*/ + + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + -ms-transform: translate3d(0, 0, 0); + -o-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); } -.abigimage-prevBtnBox { - cursor: pointer; +.abigimage-overlay-active { + /*transition: opacity .2s ease-in-out, height .2s step-start;*/ + height: 100%; + opacity: 1; + /*display: block;*/ +} + +.abigimage-wrapper { position: absolute; + left: 0; + right: 0; top: 0; - right: 50%; bottom: 0; - left: 0; + overflow: hidden; +} + +.abigimage-box { + position: absolute; + width: 312.5%; + left: -106.25%; + top: 2.5em; + bottom: 2.5em; } +.abigimage-prevBtnBox, .abigimage-closeBtnBox { cursor: pointer; position: absolute; top: 0; - right: 0; bottom: 0; - left: 50%; } -.abigimage-prevBtn { - color: #fff; - background-color: #000; - opacity: .5; - padding: 0 1em; - border-radius: 0 0 1ex 0; - position: absolute; - top: 0; +.abigimage-prevBtnBox { + right: 50%; left: 0; - transition: all .2s ease-in-out; } +.abigimage-closeBtnBox { + right: 0; + left: 50%; +} + +.abigimage-prevBtn, +.abigimage-nextBtn, +.abigimage-zoomInBtn, +.abigimage-zoomOutBtn, .abigimage-closeBtn { + cursor: pointer; color: #fff; background-color: #000; + background-color: rgba(0, 0, 0, 0); opacity: .5; padding: 0 1em; - border-radius: 0 0 0 1ex; - position: absolute; - top: 0; - right: 0; transition: all .2s ease-in-out; } -.abigimage-prevBtn:hover, .abigimage-prevBtn-hover, -.abigimage-closeBtn:hover, .abigimage-closeBtn-hover { - opacity: 1; +.abigimage-prevBtn, +.abigimage-nextBtn { + float: left; } -.abigimage-box { - position: absolute; - width: 312.5%; - height: 100%; - left: -106.25%; - top: 0; +.abigimage-zoomInBtn, +.abigimage-zoomOutBtn, +.abigimage-closeBtn { + float: right; } -.abigimage-box-zoom { - z-index: 101; +.abigimage-prevBtn:hover, .abigimage-prevBtn-hover, +.abigimage-nextBtn:hover, .abigimage-nextBtn-hover, +.abigimage-closeBtn:hover, .abigimage-closeBtn-hover, +.abigimage-zoomInBtn:hover, .abigimage-zoomOutBtn:hover { + background-color: #000; + background-color: rgba(0, 0, 0, 1); + opacity: 1; } -.abigimage-img { +.abigimage-img, +.abigimage-imgNext, +.abigimage-imgPrev { position: absolute; margin: auto; width: auto; top: 0; - right: 0; bottom: 0; - left: 0; display: block; - cursor: pointer; max-width: 32%; max-height: 100%; + + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + -ms-transform: translate3d(0, 0, 0); + -o-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} + +.abigimage-img { + right: 0; + left: 0; + cursor: pointer; } .abigimage-imgNext { - position: absolute; - margin: auto; - width: auto; - top: 0; right: 0; - bottom: 0; left: 68%; - display: block; - max-width: 32%; - max-height: 100%; + /*opacity: 0;*/ } .abigimage-imgPrev { + right: 68%; + left: 0; + /*opacity: 0;*/ +} + +/*.abigimage-layout-slide .abigimage-imgNext,*/ +/*.abigimage-layout-slide .abigimage-imgPrev {*/ + /*opacity: 1;*/ +/*}*/ + +.abigimage-layout-zoom .abigimage-imgNext, +.abigimage-layout-zoom .abigimage-imgPrev { + display: none !important; +} + +.abigimage-top { position: absolute; - margin: auto; - width: auto; top: 0; - right: 68%; - bottom: 0; left: 0; - display: block; - max-width: 32%; - max-height: 100%; + right: 0; + color: #fff; + line-height: 2.5; + transition: all .2s ease-in-out; + background-color: #000; + background-color: rgba(0, 0, 0, .5); } -.abigimage-bottom { - position: fixed; +.abigimage-counter { + text-align: center; + opacity: .5; + transition: all .2s ease-in-out; + float: left; + padding: 0 1em; +} + +.abigimage-counter:hover { + opacity: 1; +} + +/*.abigimage-spinner {*/ + /*float: right;*/ + /*padding: 0 1em;*/ + /*opacity: 0;*/ + /*transition: all .2s ease-in-out;*/ +/*}*/ + +/*.abigimage-spinner-active {*/ + /*opacity: .5;*/ +/*}*/ + +/*.abigimage-spinner-active:hover {*/ + /*opacity: 1;*/ +/*}*/ + +/*.abigimage-spinner:after {*/ + /*content: ' ';*/ + /*display: inline-block;*/ + /*vertical-align: middle;*/ + /*width: 1em;*/ + /*height: 1em;*/ + /*border: 1px solid;*/ + /*border-bottom: 0;*/ + /*border-radius: 50%;*/ + /*animation: abigimage-spinner .6s linear infinite;*/ +/*}*/ + +/*@keyframes abigimage-spinner {*/ + /*0% { transform: rotate(0deg); }*/ + /*100% { transform: rotate(360deg); }*/ +/*}*/ + +.abigimage-bottomBox { + position: absolute; + left: 0; right: 0; bottom: 0; + height: 2.5em; +} + +.abigimage-bottom { + position: absolute; left: 0; - -webkit-user-select: text; - -moz-user-select: text; - user-select: text; - background-color: #000; + right: 0; + top: 0; color: #fff; + line-height: 2.5; + background-color: #000; opacity: .5; - padding: 0 1em; - text-align: center; transition: all .2s ease-in-out; + text-align: center; + padding: 0 1em; } .abigimage-bottom:hover { opacity: 1; } + +.abigimage-layout-full .abigimage-bottom, +.abigimage-layout-full .abigimage-top { + opacity: 0; +} + +.abigimage-layout-full .abigimage-box { + top: 0; + bottom: 0; +} + +.abigimage-top, +.abigimage-box, +.abigimage-prevBtn, +.abigimage-nextBtn, +.abigimage-zoomInBtn, +.abigimage-zoomOutBtn, +.abigimage-closeBtn { + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} diff --git a/abigimage.jquery.js b/abigimage.jquery.js index ea89a5d..aadf9a9 100644 --- a/abigimage.jquery.js +++ b/abigimage.jquery.js @@ -10,16 +10,86 @@ var last, current, - overlay = $('
').addClass('abigimage-overlay') .appendTo('body') .hide(), - layout = $('
').addClass('abigimage-layout') .appendTo('body') .hide(), - box = $('
').addClass('abigimage-box') .appendTo(layout), + + //overscroll = $('
').addClass('abigimage-overscroll') .appendTo('body'), + overlay = $('
').addClass('abigimage-overlay') .appendTo('body'), + layout = $('
').addClass('abigimage-layout') .appendTo('body'), + wrapper = $('
').addClass('abigimage-wrapper') .appendTo(layout), + box = $('
').addClass('abigimage-box') .appendTo(wrapper), prevBtnBox = $('
').addClass('abigimage-prevBtnBox') .appendTo(box), closeBtnBox = $('
').addClass('abigimage-closeBtnBox').appendTo(box), - prevBtn = $('
').addClass('abigimage-prevBtn') .appendTo(layout), - closeBtn = $('
').addClass('abigimage-closeBtn') .appendTo(layout), - bottom = $('
').addClass('abigimage-bottom') .appendTo(layout), + top = $('
').addClass('abigimage-top') .appendTo(layout), + prevBtn = $('
').addClass('abigimage-prevBtn') .appendTo(top), + nextBtn = $('
').addClass('abigimage-nextBtn') .appendTo(top), + counter = $('
').addClass('abigimage-counter') .appendTo(top), + closeBtn = $('
').addClass('abigimage-closeBtn') .appendTo(top), + zoomOutBtn = $('
').addClass('abigimage-zoomOutBtn') .appendTo(top), + zoomInBtn = $('
').addClass('abigimage-zoomInBtn') .appendTo(top), + //spinner = $('
').addClass('abigimage-spinner') .appendTo(top), + bottomBox = $('
').addClass('abigimage-bottomBox') .appendTo(layout), + bottom = $('
').addClass('abigimage-bottom') .appendTo(bottomBox), + //under = $('
').addClass('abigimage-under') .appendTo(layout), + + cssLayoutActive = 'abigimage-layout-active', + cssLayoutFadeout = 'abigimage-layout-fadeout', + cssLayoutFull = 'abigimage-layout-full', + //cssLayoutSlide = 'abigimage-layout-slide', + cssLayoutZoom = 'abigimage-layout-zoom', + cssOverlayActive = 'abigimage-overlay-active', + cssPrevBtnHover = 'abigimage-prevBtn-hover', + cssNextBtnHover = 'abigimage-nextBtn-hover', + cssCloseBtnHover = 'abigimage-closeBtn-hover', + //cssSpinnerActive = 'abigimage-spinner-active', + boxe = box[0], - $w = $(window); + //bboxe = bottomBox[0], + $w = $(window), + $h = $('html'), + $d = $(document), + $b = $(document.body), + + hpr = null, + bo = null, + //wst = null, + //bt = null, + + sx, + sy, + ss, + mss, + x, + y, + s, + k, + dx, + dy, + iw, + ih, + ww, + wh, + mx, + my, + + ztimer, + zstart, + zsign, + ttimer, + dstart, + start, + width, + height, + minD, + vert, + touches, + intr, + ontr, + sliding = false, + wheellock = false, + wheellocktimer, + zoomlock = false, + zoomlocktimer, + bs = boxe.style, + os = overlay[0].style; $.fn.abigimage = function(options) { var plugin = new ABigImage(this, options); @@ -34,17 +104,20 @@ }; $.fn.abigimage.defaults = { - fadeIn: 'fast', - fadeOut: 'fast', + duration: 200, slideWidth: .4, slideVelocity: .4, zoomMin: 1.5, zoomMax: 5, - zoomScrollMultiplier: 1.25, - zoomMoveViewport: 0.9, + zoomClose: .9, + zoomMoveViewport: .9, + zoomVelocity: .04, doubleTapInterval: 400, prevBtnHtml: '←', - closeBtnHtml: 'x', + nextBtnHtml: '→', + zoomInBtnHtml: '+', + zoomOutBtnHtml: '−', + closeBtnHtml: '×', keyNext: [13 /* enter */, 32 /* space */, 39 /* right */, 40 /* down */], keyPrev: [8 /* backspace */, 37 /* left */, 38 /* up */], keyClose: [27 /* escape */, 35 /* end */, 36 /* home */], @@ -53,14 +126,23 @@ }; $.abigimage = { - overlay: overlay, - layout: layout, - prevBtnBox: prevBtnBox, - prevBtn: prevBtn, - closeBtnBox: closeBtnBox, - closeBtn: closeBtn, - box: box, - bottom: bottom, + overlay: overlay, + layout: layout, + wrapper: wrapper, + box: box, + prevBtnBox: prevBtnBox, + closeBtnBox: closeBtnBox, + top: top, + prevBtn: prevBtn, + nextBtn: nextBtn, + zoomInBtn: zoomInBtn, + zoomOutBtn: zoomOutBtn, + closeBtn: closeBtn, + counter: counter, + //spinner: spinner, + bottomBox: bottomBox, + bottom: bottom, + //under: under, open: function(src, index, sel) { ((sel && sel._abigimage) || current || last).open(src, index); @@ -83,18 +165,18 @@ prevent(event); if (current) current.prev(); }).hover(function() { - prevBtn.addClass('abigimage-prevBtn-hover'); + prevBtn.addClass(cssPrevBtnHover); }, function() { - prevBtn.removeClass('abigimage-prevBtn-hover'); + prevBtn.removeClass(cssPrevBtnHover); }); closeBtnBox.click(function(event) { prevent(event); if (current) current.close(); }).hover(function() { - closeBtn.addClass('abigimage-closeBtn-hover'); + closeBtn.addClass(cssCloseBtnHover); }, function() { - closeBtn.removeClass('abigimage-closeBtn-hover'); + closeBtn.removeClass(cssCloseBtnHover); }); prevBtn.click(function(event) { @@ -102,14 +184,75 @@ if (current) current.prev(); }); + nextBtn.click(function(event) { + prevent(event); + if (current) current.next(); + }); + + var reqAnimFrame = window.requestAnimationFrame + || window.mozRequestAnimationFrame + || window.webkitRequestAnimationFrame + || window.msRequestAnimationFrame + || function(callback){ + setTimeout(function(){ + callback((new Date()).getTime()); + }, 1000 / 60); + }; + + + function zoomAnimationFrame(t) { + if (current && zsign !== null) { + if (zstart) { + zoom(zsign * current.zoomVelocity * (t - zstart)); + } else { + zstart = t; + } + reqAnimFrame(zoomAnimationFrame); + } + } + + zoomInBtn.mousedown(function(event) { + prevent(event); + initSizes(); + zstart = null; + zsign = 1; + reqAnimFrame(zoomAnimationFrame); + }).mouseup(function(event){ + prevent(event); + zsign = null; + }).mouseout(function(){ + zsign = null; + }).click(function(event) { + prevent(event); + if (current) zoom(current.zoomVelocity * current.duration, true); + }); + + zoomOutBtn.mousedown(function(event) { + prevent(event); + initSizes(); + zstart = null; + zsign = -1; + reqAnimFrame(zoomAnimationFrame); + }).mouseup(function(event){ + prevent(event); + zsign = null; + }).mouseout(function(){ + zsign = null; + }).click(function(event) { + prevent(event); + if (current) zoom(-current.zoomVelocity * current.duration, true); + }); + closeBtn.click(function(event) { prevent(event); if (current) current.close(); }); - layout - .on('touchmove', prevent) - .on('wheel', prevent); + //layout + // .on('touchmove', prevent) + // .on('wheel', function(e) { + // e.stopPropagation(); + // }); if (boxe.addEventListener) { function listen(element, event, listener) { // just for minification @@ -127,7 +270,7 @@ listen(boxe, 'transitionend', transitionEnd); listen(boxe, 'wheel', zoomwheel); - listen(boxe, 'mousemove', zoomwheel); + listen(boxe, 'mousemove', zoommousemove); } function ABigImage(elements, options) { @@ -137,15 +280,25 @@ this.overlay = overlay; this.layout = layout; + this.wrapper = wrapper; this.prevBtnBox = prevBtnBox; - this.prevBtn = prevBtn; this.closeBtnBox = closeBtnBox; - this.closeBtn = closeBtn; this.box = box; + this.top = top; + this.prevBtn = prevBtn; + this.nextBtn = nextBtn; + this.zoomInBtn = zoomInBtn; + this.zoomOutBtn = zoomOutBtn; + this.closeBtn = closeBtn; + this.counter = counter; + //this.spinner = spinner; + this.bottomBox = bottomBox; this.bottom = bottom; + //this.under = under; this.index = -1; this.distance = 0; + this.opened = null; } ABigImage.prototype.open = function(src, index) { @@ -168,33 +321,68 @@ } this.index = index; + this.opened = currLink; this.prevBtn.html(this.prevBtnHtml); + this.nextBtn.html(this.nextBtnHtml); + this.zoomInBtn.html(this.zoomInBtnHtml); + this.zoomOutBtn.html(this.zoomOutBtnHtml); this.closeBtn.html(this.closeBtnHtml); this.bottom.html(''); + //this.under.html(''); + this.counter.html(index >= 0 ? (index + 1) + ' / ' + this.elements.length : ''); $('img', this.box).remove(); - this.box.removeClass('abigimage-box-zoom'); + fadeReset(); + //overscroll.addClass('abigimage-overscroll-active'); + this.overlay.addClass(cssOverlayActive) + /*.removeClass('abigimage-overlay-fadeout')*/; + this.layout.addClass(cssLayoutActive) + //.removeClass(cssLayoutSlide) + .removeClass(cssLayoutFadeout) + .scrollTop(0); slideAnimate(0, 0, 1); this.img = createImage('abigimage-img', src) .click(function(event) { prevent(event); if (current) current.next(); - }); + }) + .hover(function() { + nextBtn.addClass(cssNextBtnHover); + }, function() { + nextBtn.removeClass(cssNextBtnHover); + }) + .one('load', function() { checkImagesLoaded(); }); var nextElement = $(this.elements[this.nextIndex()]); - this.imgNext = createImage('abigimage-imgNext', nextElement.data('href') || nextElement.attr('href')); + this.imgNext = createImage('abigimage-imgNext', nextElement.data('href') || nextElement.attr('href')) + .hide() + .one('load', function() { checkImagesLoaded(); }); var prevElement = $(this.elements[this.prevIndex()]); - this.imgPrev = createImage('abigimage-imgPrev', prevElement.data('href') || prevElement.attr('href')); - - overlay.fadeIn(); - layout.fadeIn(); - - $(document).unbind('keydown', documentKeydown).bind('keydown', documentKeydown); + this.imgPrev = createImage('abigimage-imgPrev', prevElement.data('href') || prevElement.attr('href')) + .hide() + .one('load', function() { checkImagesLoaded(); }); + + //this.spinner.toggleClass(cssSpinnerActive, !this.img[0].complete); + checkImagesLoaded(true); + + $d.unbind('keydown', documentKeydown).bind('keydown', documentKeydown); + + //if (wst === null && bt === null) { + // wst = $w.scrollTop(); + // bt = $b.css('top'); + // $b.css('top', (-1 * wst) + 'px').addClass('abigimage-body'); + //} + if (hpr === null && bo === null) { + hpr = $h.css('padding-right'); + bo = $b.css('overflow-y'); + $h.css('padding-right', (parseInt(hpr) + window.innerWidth - $w.width()) + 'px'); + $b.css('overflow-y', 'hidden'); + } - if (this.onopen) this.onopen.call(this, currLink); + if (this.onopen) this.onopen.call(this, this.opened); }; ABigImage.prototype.next = function() { @@ -220,12 +408,25 @@ ABigImage.prototype.close = function() { if (!current) return; - $(document).unbind('keydown', documentKeydown); + $d.unbind('keydown', documentKeydown); - overlay.fadeOut(this.fadeOut); - layout.fadeOut(this.fadeOut, transitionEnd); + //setTimeout(function() { + $h.css('padding-right', hpr); + $b.css('overflow-y', bo); + hpr = null; + bo = null; + //overscroll.removeClass('abigimage-overscroll-active'); + //$b.css('top', bt).removeClass('abigimage-body'); + //$w.scrollTop(wst); + //wst = null; + //bt = null; + //}, current.duration); - if (this.onclose) this.onclose.call(this); + //fadeReset(); + overlay.removeClass(cssOverlayActive); + layout.removeClass(cssLayoutActive); + + if (this.onclose) this.onclose.call(this, this.opened); this.index = -1; this.distance = 0; @@ -286,41 +487,55 @@ event.stopPropagation(); } - var sx, - sy, - ss, - x, - y, - s, - k, - dx, - dy, - iw, - ih, - ww, - wh, - mx, - my, + function checkImagesLoaded(forceNoSlide) { + if (!current) return; - dstart, - start, - width, - height, - minD, - vert, - touches, - intr, - ontr, - bs = boxe.style; + if (!forceNoSlide && sliding) return; + + if (current.imgNext[0].complete) { + current.imgNext.show(); + } + + if (current.imgPrev[0].complete) { + current.imgPrev.show(); + } + + //if (current.img[0].complete && current.imgNext[0].complete && current.imgPrev[0].complete) { + // current.spinner.removeClass(cssSpinnerActive); + //} + } + + function onSlideStart() { + if (!current) return; + + sliding = true; + //current.layout.addClass(cssLayoutSlide); + + //if (!current.img[0].complete || !current.imgNext[0].complete || !current.imgPrev[0].complete) { + // current.spinner.addClass(cssSpinnerActive); + //} + } + + function onSlideEnd() { + if (!current) return; + + sliding = false; + //current.layout.removeClass(cssLayoutSlide); + + checkImagesLoaded(true); + } function touchstart(e) { if (!current) return; + onSlideEnd(); + if (e.touches.length > 1) { k = dis(e); - current.box.addClass('abigimage-box-zoom'); + current.layout.addClass(cssLayoutZoom); } else { vert = null; + mss = s; dstart = start; start = (new Date()).getTime(); width = box.width() * 0.34; @@ -335,6 +550,17 @@ dy = 0; touches = e.touches; prevent(e); + + if (ttimer) { + clearTimeout(ttimer); + ttimer = null; + } + if (e.touches.length == 1) { + ttimer = setTimeout(function() { + current.layout.toggleClass(cssLayoutFull); + ttimer = null; + }, current.doubleTapInterval); + } } function touchmove(e) { @@ -344,6 +570,10 @@ s = ss * (dis(e) / k); if (s < 1) { s = 0.333 * s * s * s + 0.666; + fadeTo(s); + } + if (s > mss) { + mss = s; } } @@ -353,15 +583,24 @@ x = sx + dx; y = sy + dy; - if (s <= current.zoomMin && e.touches.length <= 1) { + if (ttimer && (dx > 1 || dx < -1 || dy > 1 || dy < -1)) { + clearTimeout(ttimer); + ttimer = null; + } + + if (s == 1 && e.touches.length == 1) { if (null === vert) { var dv = Math.abs(dy) - Math.abs(dx); if (Math.abs(dv) > 2) { vert = dv > 0; } + if (vert === false) { + onSlideStart(); + } } if (vert) { x = 0; + fadeTo(1 - Math.abs(dy) / height); } else { y = 0; } @@ -380,9 +619,9 @@ sx = x; sy = y; ss = s; - dx = 0; - dy = 0; - touches = e.touches; + //dx = 0; + //dy = 0; + //touches = e.touches; } else { if (s <= current.zoomMin) { if (time <= 1 || (dx >= -1 && dx <= 1 && dy >= -1 && dy <= 1)) { @@ -398,19 +637,26 @@ x = mx <= 0 ? 0 : Math.max(-mx, Math.min(mx, x)); y = my <= 0 ? 0 : Math.max(-my, Math.min(my, y)); - current.box.addClass('abigimage-box-zoom'); + if (ttimer) { + clearTimeout(ttimer); + ttimer = null; + } + + current.layout.addClass(cssLayoutZoom); slideAnimate(x, y, s, true); } else { - slideAnimate(0, 0, 1, true); + slideBack(); } - } else { - if (vert) { + } else if (mss == 1) { + if (s < current.zoomClose) { + slideClose(); + } else if (vert) { var ady = Math.abs(dy); if (ady > minD) { - slideClose(); + slideClose(dy); } else { if (ady / time > current.slideVelocity) { - slideClose(); + slideClose(dy); } else { slideBack(); } @@ -432,9 +678,16 @@ } } } + } else { + slideBack(); } } else { if (end - dstart <= current.doubleTapInterval) { + if (ttimer) { + clearTimeout(ttimer); + ttimer = null; + } + slideBack(); } else { s = Math.max(1, Math.min(current.zoomMax, s)); @@ -470,29 +723,46 @@ iw = current.img.width() / 2; ih = current.img.height() / 2; ww = $w.width() / 2; - wh = $w.height() / 2; + wh = ($w.height() - current.top.height() - current.bottomBox.height()) / 2; } function slideNext() { slideAnimate(-width, 0, 1, true, function() { current.next(); }); + layout.animate({scrollTop: 0}, current.duration); } function slidePrev() { slideAnimate(width, 0, 1, true, function() { current.prev(); }); + layout.animate({scrollTop: 0}, current.duration); } function slideBack() { - current.box.removeClass('abigimage-box-zoom'); - slideAnimate(0, 0, 1, true); + slideAnimate(0, 0, 1, true, function() { + current.layout.removeClass(cssLayoutZoom); + onSlideEnd(); + }); + fadeTo(1, true); + //overlay.addClass('abigimage-overlay-fadeout'); } - function slideClose() { - slideBack(); - current.close(); + function slideClose(dir) { + if (dir) { + slideAnimate(x, Math.sign(dir) * ($w.height() / 2 + ih), s, true, function() { + current.close(); + }); + } else { + slideAnimate(x, y, 0, true, function() { + current.close(); + }); + } + fadeTo(0, true); + //overlay.addClass('abigimage-overlay-fadeout'); + layout.addClass(cssLayoutFadeout); + //current.close(); } function slideAnimate(tx, ty, ts, transition, onend) { @@ -502,12 +772,29 @@ intr = transition; ontr = onend; var transform = 'scale(' + s + ') translate3d(' + x + 'px, ' + y + 'px, 0)'; - bs.transition = transition ? 'all .2s ease-out' : ''; + bs.transition = transition ? 'all ' + current.duration + 'ms ease-out' : 'none'; bs.webkitTransform = transform; bs.mozTransform = transform; bs.msTransform = transform; bs.oTransform = transform; bs.transform = transform; + + } + + function fadeTo(o, transition) { + os.transition = transition ? 'opacity ' + current.duration + 'ms ease-out' : 'none'; + os.opacity = o; + var transform = 'translate3d(0, 0, 0)'; + os.webkitTransform = transform; + os.mozTransform = transform; + os.msTransform = transform; + os.oTransform = transform; + os.transform = transform; + } + + function fadeReset() { + os.transition = null; + os.opacity = null; } function transitionEnd() { @@ -522,35 +809,82 @@ function zoomwheel(e) { if (!current) return; - initSizes(); + var delta = -e.deltaY || 0; + if (e.deltaMode == 1) { // line + delta *= current.zoomVelocity * current.duration; + } else if (e.deltaMode == 2) { // page + delta *= height; + } - if (e.deltaY > 0) { - s /= current.zoomScrollMultiplier; - } else if (e.deltaY < 0) { - s *= current.zoomScrollMultiplier; + if (layout.scrollTop() || (s == 1 && delta < 0)) { + if (wheellock) { + prevent(e); + } else { + if (zoomlocktimer) { + clearTimeout(zoomlocktimer); + } + zoomlock = true; + zoomlocktimer = setTimeout(function() { + zoomlock = false; + zoomlocktimer = null; + }, current.duration); + } + return; + } else { + if (zoomlock) return; + + if (wheellocktimer) { + clearTimeout(wheellocktimer); + } + wheellock = true; + wheellocktimer = setTimeout(function() { + wheellock = false; + wheellocktimer = null; + }, current.duration); } - s = Math.max(1, Math.min(current.zoomMax, s)); - x = 0; - y = 0; + zoomposition(e, delta); + } + + function zoommousemove(e) { + if (!current) return; + if (s == 1) return; + + zoomposition(e, 0); + } + + function zoomposition(e, delta) { + initSizes(); + + x = (ww - e.clientX) / (current.zoomMoveViewport * ww / iw) - (ww - e.clientX) / s; + y = (wh - e.clientY) / (current.zoomMoveViewport * wh / ih) - (wh - e.clientY) / s; + + zoom(delta, true); + prevent(e); + } + + function zoom(delta, transition) { + if (!current) return; + + s *= (ih + delta) / ih; + s = Math.max(1, Math.min(current.zoomMax, s)); mx = iw - ww / s; my = ih - wh / s; - if (mx > 0) - { - x = (ww - e.clientX) / (current.zoomMoveViewport * ww / iw) - (ww - e.clientX) / s; + if (mx > 0) { x = Math.max(-mx, Math.min(mx, x)); + } else { + x = 0; } - if (my > 0) - { - y = (wh - e.clientY) / (current.zoomMoveViewport * wh / ih) - (wh - e.clientY) / s; + if (my > 0) { y = Math.max(-my, Math.min(my, y)); + } else { + y = 0; } - slideAnimate(x, y, s, true); - prevent(e); + slideAnimate(x, y, s, transition); } }(jQuery)); diff --git a/abigimage.jquery.min.css b/abigimage.jquery.min.css index 2eab55b..135502b 100644 --- a/abigimage.jquery.min.css +++ b/abigimage.jquery.min.css @@ -1,2 +1,2 @@ -/*! abigimage v2.0.1 (2016-06-07) */ -.abigimage-layout,.abigimage-overlay{position:fixed;z-index:100;right:0;left:0;bottom:0}.abigimage-overlay{top:0;background-color:#000;border:1px solid #000;opacity:.9}.abigimage-closeBtn,.abigimage-prevBtn{opacity:.5;top:0;background-color:#000;color:#fff;padding:0 1em;transition:all .2s ease-in-out}.abigimage-layout{top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;line-height:2.5}.abigimage-prevBtnBox{cursor:pointer;position:absolute;top:0;right:50%;bottom:0;left:0}.abigimage-closeBtnBox{cursor:pointer;position:absolute;top:0;right:0;bottom:0;left:50%}.abigimage-prevBtn{border-radius:0 0 1ex;position:absolute;left:0}.abigimage-closeBtn{border-radius:0 0 0 1ex;position:absolute;right:0}.abigimage-closeBtn-hover,.abigimage-closeBtn:hover,.abigimage-prevBtn-hover,.abigimage-prevBtn:hover{opacity:1}.abigimage-box{position:absolute;width:312.5%;height:100%;left:-106.25%;top:0}.abigimage-img,.abigimage-imgNext,.abigimage-imgPrev{position:absolute;margin:auto;width:auto;top:0;display:block;max-width:32%;max-height:100%;bottom:0}.abigimage-box-zoom{z-index:101}.abigimage-img{right:0;left:0;cursor:pointer}.abigimage-imgNext{right:0;left:68%}.abigimage-imgPrev{right:68%;left:0}.abigimage-bottom{position:fixed;right:0;bottom:0;left:0;-webkit-user-select:text;-moz-user-select:text;user-select:text;background-color:#000;color:#fff;opacity:.5;padding:0 1em;text-align:center;transition:all .2s ease-in-out}.abigimage-bottom:hover{opacity:1} \ No newline at end of file +/*! abigimage v2.1.0 (2017-01-15) */ +.abigimage-layout,.abigimage-overlay{position:fixed;z-index:100;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0)}.abigimage-layout,.abigimage-overlay,.abigimage-wrapper{left:0;right:0;top:0;bottom:0}.abigimage-layout{height:0;opacity:0;transform:translate3d(0,0,0);overflow:hidden;overflow-y:auto}.abigimage-layout-active{height:100%;opacity:1}.abigimage-layout-fadeout{transition:opacity .2s ease-out;opacity:0}.abigimage-bottom,.abigimage-counter,.abigimage-top{transition:all .2s ease-in-out}.abigimage-overlay{background-color:#000;background-color:rgba(0,0,0,.9);height:0;opacity:0;transform:translate3d(0,0,0)}.abigimage-overlay-active{height:100%;opacity:1}.abigimage-wrapper{position:absolute;overflow:hidden}.abigimage-box{position:absolute;width:312.5%;left:-106.25%;top:2.5em;bottom:2.5em}.abigimage-closeBtnBox,.abigimage-prevBtnBox{cursor:pointer;position:absolute;top:0;bottom:0}.abigimage-prevBtnBox{right:50%;left:0}.abigimage-closeBtnBox{right:0;left:50%}.abigimage-closeBtn,.abigimage-nextBtn,.abigimage-prevBtn,.abigimage-zoomInBtn,.abigimage-zoomOutBtn{cursor:pointer;color:#fff;background-color:#000;background-color:rgba(0,0,0,0);opacity:.5;padding:0 1em;transition:all .2s ease-in-out}.abigimage-nextBtn,.abigimage-prevBtn{float:left}.abigimage-closeBtn,.abigimage-zoomInBtn,.abigimage-zoomOutBtn{float:right}.abigimage-closeBtn-hover,.abigimage-closeBtn:hover,.abigimage-nextBtn-hover,.abigimage-nextBtn:hover,.abigimage-prevBtn-hover,.abigimage-prevBtn:hover,.abigimage-zoomInBtn:hover,.abigimage-zoomOutBtn:hover{background-color:#000;background-color:rgba(0,0,0,1);opacity:1}.abigimage-img,.abigimage-imgNext,.abigimage-imgPrev{position:absolute;margin:auto;width:auto;top:0;bottom:0;display:block;max-width:32%;max-height:100%;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.abigimage-img{right:0;left:0;cursor:pointer}.abigimage-imgNext{right:0;left:68%}.abigimage-imgPrev{right:68%;left:0}.abigimage-bottom,.abigimage-bottomBox,.abigimage-top{position:absolute;left:0;right:0}.abigimage-layout-zoom .abigimage-imgNext,.abigimage-layout-zoom .abigimage-imgPrev{display:none!important}.abigimage-top{top:0;color:#fff;line-height:2.5;background-color:#000;background-color:rgba(0,0,0,.5)}.abigimage-counter{text-align:center;opacity:.5;float:left;padding:0 1em}.abigimage-counter:hover{opacity:1}.abigimage-bottomBox{bottom:0;height:2.5em}.abigimage-bottom{top:0;color:#fff;line-height:2.5;background-color:#000;opacity:.5;text-align:center;padding:0 1em}.abigimage-bottom:hover{opacity:1}.abigimage-layout-full .abigimage-bottom,.abigimage-layout-full .abigimage-top{opacity:0}.abigimage-layout-full .abigimage-box{top:0;bottom:0}.abigimage-box,.abigimage-closeBtn,.abigimage-nextBtn,.abigimage-prevBtn,.abigimage-top,.abigimage-zoomInBtn,.abigimage-zoomOutBtn{-webkit-user-select:none;-moz-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent} \ No newline at end of file diff --git a/abigimage.jquery.min.js b/abigimage.jquery.min.js index 944fd53..193db68 100644 --- a/abigimage.jquery.min.js +++ b/abigimage.jquery.min.js @@ -1,2 +1,2 @@ -/*! abigimage v2.0.1 (2016-06-07) */ -!function(a){function b(a,b,c){a.addEventListener(b,c)}function c(b,c){a.extend(this,a.fn.abigimage.defaults,c),this.elements=b,this.overlay=v,this.layout=w,this.prevBtnBox=y,this.prevBtn=A,this.closeBtnBox=z,this.closeBtn=B,this.box=x,this.bottom=C,this.index=-1,this.distance=0}function d(b,c){return a("").addClass(b).attr("src",c).appendTo(x)}function e(a){u&&u.key(a.which)&&f(a)}function f(a){a.preventDefault(),a.stopPropagation()}function g(a){u&&(a.touches.length>1?(L=k(a),u.box.addClass("abigimage-box-zoom")):(Z=null,U=V,V=(new Date).getTime(),W=.34*x.width(),X=x.height(),Y=u.slideWidth*W,l()),F=I,G=J,H=K,M=0,N=0,$=a.touches,f(a))}function h(a){if(u){if(a.touches.length>1&&(K=H*(k(a)/L),1>K&&(K=.333*K*K*K+.666)),M=(Q-j($,"X"))/H-(Q-j(a.touches,"X"))/K,N=(R-j($,"Y"))/H-(R-j(a.touches,"Y"))/K,I=F+M,J=G+N,K<=u.zoomMin&&a.touches.length<=1){if(null===Z){var b=Math.abs(N)-Math.abs(M);Math.abs(b)>2&&(Z=b>0)}Z?I=0:J=0}q(I,J,K),f(a)}}function i(a){if(u){var b=(new Date).getTime(),c=b-V;if(a.touches.length)F=I,G=J,H=K,M=0,N=0,$=a.touches;else if(K<=u.zoomMin)if(1>=c||M>=-1&&1>=M&&N>=-1&&1>=N)if(V-U<=u.doubleTapInterval){K=u.zoomMax;var d=j($,"X"),e=j($,"Y");I+=(Q-d)/H-(Q-d)/K,J+=(R-e)/H-(R-e)/K,S=O-Q/K,T=P-R/K,I=0>=S?0:Math.max(-S,Math.min(S,I)),J=0>=T?0:Math.max(-T,Math.min(T,J)),u.box.addClass("abigimage-box-zoom"),q(I,J,K,!0)}else q(0,0,1,!0);else if(Z){var g=Math.abs(N);g>Y?p():g/c>u.slideVelocity?p():o()}else-Y>M?m():M>Y?n():Math.abs(M)/c>u.slideVelocity?0>M?m():n():o();else b-U<=u.doubleTapInterval?o():(K=Math.max(1,Math.min(u.zoomMax,K)),S=O-Q/K,T=P-R/K,I=0>=S?0:Math.max(-S,Math.min(S,I)),J=0>=T?0:Math.max(-T,Math.min(T,J)),q(I,J,K,!0));$=a.touches,f(a)}}function j(a,b){for(var c=0,d=0,e=a.length;e>d;d++)c+=a[d]["client"+b];return c/e}function k(a){return Math.sqrt(Math.pow(a.touches[0].pageX-a.touches[1].pageX,2)+Math.pow(a.touches[0].pageY-a.touches[1].pageY,2))}function l(){O=u.img.width()/2,P=u.img.height()/2,Q=E.width()/2,R=E.height()/2}function m(){q(-W,0,1,!0,function(){u.next()})}function n(){q(W,0,1,!0,function(){u.prev()})}function o(){u.box.removeClass("abigimage-box-zoom"),q(0,0,1,!0)}function p(){o(),u.close()}function q(a,b,c,d,e){I=a,J=b,K=c,_=d,aa=e;var f="scale("+K+") translate3d("+I+"px, "+J+"px, 0)";ba.transition=d?"all .2s ease-out":"",ba.webkitTransform=f,ba.mozTransform=f,ba.msTransform=f,ba.oTransform=f,ba.transform=f}function r(){if(_=!1,aa){var a=aa;aa=null,a()}}function s(a){u&&(l(),a.deltaY>0?K/=u.zoomScrollMultiplier:a.deltaY<0&&(K*=u.zoomScrollMultiplier),K=Math.max(1,Math.min(u.zoomMax,K)),I=0,J=0,S=O-Q/K,T=P-R/K,S>0&&(I=(Q-a.clientX)/(u.zoomMoveViewport*Q/O)-(Q-a.clientX)/K,I=Math.max(-S,Math.min(S,I))),T>0&&(J=(R-a.clientY)/(u.zoomMoveViewport*R/P)-(R-a.clientY)/K,J=Math.max(-T,Math.min(T,J))),q(I,J,K,!0),f(a))}var t,u,v=a("
").addClass("abigimage-overlay").appendTo("body").hide(),w=a("
").addClass("abigimage-layout").appendTo("body").hide(),x=a("
").addClass("abigimage-box").appendTo(w),y=a("
").addClass("abigimage-prevBtnBox").appendTo(x),z=a("
").addClass("abigimage-closeBtnBox").appendTo(x),A=a("
").addClass("abigimage-prevBtn").appendTo(w),B=a("
").addClass("abigimage-closeBtn").appendTo(w),C=a("
").addClass("abigimage-bottom").appendTo(w),D=x[0],E=a(window);a.fn.abigimage=function(b){var d=new c(this,b);return this._abigimage=d,t=d,this.each(function(b){a(this).unbind("click.abigimage").bind("click.abigimage",function(a){f(a),d.open(b)})})},a.fn.abigimage.defaults={fadeIn:"fast",fadeOut:"fast",slideWidth:.4,slideVelocity:.4,zoomMin:1.5,zoomMax:5,zoomScrollMultiplier:1.25,zoomMoveViewport:.9,doubleTapInterval:400,prevBtnHtml:"←",closeBtnHtml:"x",keyNext:[13,32,39,40],keyPrev:[8,37,38],keyClose:[27,35,36],onopen:null,onclose:null},a.abigimage={overlay:v,layout:w,prevBtnBox:y,prevBtn:A,closeBtnBox:z,closeBtn:B,box:x,bottom:C,open:function(a,b,c){(c&&c._abigimage||u||t).open(a,b)},close:function(a){(a&&a._abigimage||u||t).close()},next:function(a){(a&&a._abigimage||u||t).next()},prev:function(a){(a&&a._abigimage||u||t).prev()},unbind:function(a){(a&&a._abigimage||u||t).unbind()}},y.click(function(a){f(a),u&&u.prev()}).hover(function(){A.addClass("abigimage-prevBtn-hover")},function(){A.removeClass("abigimage-prevBtn-hover")}),z.click(function(a){f(a),u&&u.close()}).hover(function(){B.addClass("abigimage-closeBtn-hover")},function(){B.removeClass("abigimage-closeBtn-hover")}),A.click(function(a){f(a),u&&u.prev()}),B.click(function(a){f(a),u&&u.close()}),w.on("touchmove",f).on("wheel",f),D.addEventListener&&(b(D,"touchstart",g),b(D,"touchmove",h),b(D,"touchend",i),b(D,"touchcancel",i),b(D,"webkitTransitionEnd",r),b(D,"mozTransitionEnd",r),b(D,"msTransitionEnd",r),b(D,"oTransitionEnd",r),b(D,"transitionend",r),b(D,"wheel",s),b(D,"mousemove",s)),c.prototype.open=function(b,c){u=this;var g;if("number"==typeof b){if(c=b,c==this.index||0>c||c>this.elements.length-1)return;g=a(this.elements[c]),b=g.data("href")||g.attr("href")}else if("number"!=typeof c)c=this.index;else if(c==this.index)return;this.index=c,this.prevBtn.html(this.prevBtnHtml),this.closeBtn.html(this.closeBtnHtml),this.bottom.html(""),a("img",this.box).remove(),this.box.removeClass("abigimage-box-zoom"),q(0,0,1),this.img=d("abigimage-img",b).click(function(a){f(a),u&&u.next()});var h=a(this.elements[this.nextIndex()]);this.imgNext=d("abigimage-imgNext",h.data("href")||h.attr("href"));var i=a(this.elements[this.prevIndex()]);this.imgPrev=d("abigimage-imgPrev",i.data("href")||i.attr("href")),v.fadeIn(),w.fadeIn(),a(document).unbind("keydown",e).bind("keydown",e),this.onopen&&this.onopen.call(this,g)},c.prototype.next=function(){this.distance==this.elements.length-1?this.close():(++this.distance,this.elements[this.nextIndex()].click())},c.prototype.prev=function(){this.distance==1-this.elements.length?this.close():(--this.distance,this.elements[this.prevIndex()].click())},c.prototype.close=function(){u&&(a(document).unbind("keydown",e),v.fadeOut(this.fadeOut),w.fadeOut(this.fadeOut,r),this.onclose&&this.onclose.call(this),this.index=-1,this.distance=0,u=null)},c.prototype.unbind=function(){this.close(),this.elements.each(function(){a(this).unbind("click.abigimage")})},c.prototype.key=function(a){if(-1!=this.keyNext.indexOf(a))this.next();else if(-1!=this.keyPrev.indexOf(a))this.prev();else{if(-1==this.keyClose.indexOf(a))return!1;this.close()}return!0},c.prototype.nextIndex=function(){var a=this.index+1;return a>=this.elements.length&&(a=0),a},c.prototype.prevIndex=function(){var a=this.index-1;return 0>a&&(a=this.elements.length-1),a};var F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,$,_,aa,ba=D.style}(jQuery); \ No newline at end of file +/*! abigimage v2.1.0 (2017-01-15) */ +!function(a){function b(a){D&&null!==V&&(U?B(V*D.zoomVelocity*(a-U)):U=a,Pa(b))}function c(a,b,c){a.addEventListener(b,c)}function d(b,c){a.extend(this,a.fn.abigimage.defaults,c),this.elements=b,this.overlay=ga,this.layout=ha,this.wrapper=ia,this.prevBtnBox=ka,this.closeBtnBox=la,this.box=ja,this.top=ma,this.prevBtn=na,this.nextBtn=oa,this.zoomInBtn=sa,this.zoomOutBtn=ra,this.closeBtn=qa,this.counter=pa,this.bottomBox=ta,this.bottom=ua,this.index=-1,this.distance=0,this.opened=null}function e(b,c){return a("").addClass(b).attr("src",c).appendTo(ja)}function f(a){D&&D.key(a.which)&&g(a)}function g(a){a.preventDefault(),a.stopPropagation()}function h(a){D&&(a||!Ka)&&(D.imgNext[0].complete&&D.imgNext.show(),D.imgPrev[0].complete&&D.imgPrev.show())}function i(){D&&(Ka=!0)}function j(){D&&(Ka=!1,h(!0))}function k(a){D&&(j(),a.touches.length>1?(L=o(a),D.layout.addClass(ya)):(aa=null,H=K,X=Y,Y=(new Date).getTime(),Z=.34*ja.width(),$=ja.height(),_=D.slideWidth*Z,p()),E=I,F=J,G=K,M=0,N=0,ba=a.touches,g(a),W&&(clearTimeout(W),W=null),1==a.touches.length&&(W=setTimeout(function(){D.layout.toggleClass(xa),W=null},D.doubleTapInterval)))}function l(a){if(D){if(a.touches.length>1&&(K=G*(o(a)/L),1>K&&(K=.333*K*K*K+.666,v(K)),K>H&&(H=K)),M=(Q-n(ba,"X"))/G-(Q-n(a.touches,"X"))/K,N=(R-n(ba,"Y"))/G-(R-n(a.touches,"Y"))/K,I=E+M,J=F+N,W&&(M>1||-1>M||N>1||-1>N)&&(clearTimeout(W),W=null),1==K&&1==a.touches.length){if(null===aa){var b=Math.abs(N)-Math.abs(M);Math.abs(b)>2&&(aa=b>0),aa===!1&&i()}aa?(I=0,v(1-Math.abs(N)/$)):J=0}u(I,J,K),g(a)}}function m(a){if(D){var b=(new Date).getTime(),c=b-Y;if(a.touches.length)E=I,F=J,G=K;else if(K<=D.zoomMin)if(1>=c||M>=-1&&1>=M&&N>=-1&&1>=N)if(Y-X<=D.doubleTapInterval){K=D.zoomMax;var d=n(ba,"X"),e=n(ba,"Y");I+=(Q-d)/G-(Q-d)/K,J+=(R-e)/G-(R-e)/K,S=O-Q/K,T=P-R/K,I=0>=S?0:Math.max(-S,Math.min(S,I)),J=0>=T?0:Math.max(-T,Math.min(T,J)),W&&(clearTimeout(W),W=null),D.layout.addClass(ya),u(I,J,K,!0)}else s();else if(1==H)if(K_?t(N):f/c>D.slideVelocity?t(N):s()}else-_>M?q():M>_?r():Math.abs(M)/c>D.slideVelocity?0>M?q():r():s();else s();else b-X<=D.doubleTapInterval?(W&&(clearTimeout(W),W=null),s()):(K=Math.max(1,Math.min(D.zoomMax,K)),S=O-Q/K,T=P-R/K,I=0>=S?0:Math.max(-S,Math.min(S,I)),J=0>=T?0:Math.max(-T,Math.min(T,J)),u(I,J,K,!0));ba=a.touches,g(a)}}function n(a,b){for(var c=0,d=0,e=a.length;e>d;d++)c+=a[d]["client"+b];return c/e}function o(a){return Math.sqrt(Math.pow(a.touches[0].pageX-a.touches[1].pageX,2)+Math.pow(a.touches[0].pageY-a.touches[1].pageY,2))}function p(){O=D.img.width()/2,P=D.img.height()/2,Q=Ea.width()/2,R=(Ea.height()-D.top.height()-D.bottomBox.height())/2}function q(){u(-Z,0,1,!0,function(){D.next()}),ha.animate({scrollTop:0},D.duration)}function r(){u(Z,0,1,!0,function(){D.prev()}),ha.animate({scrollTop:0},D.duration)}function s(){u(0,0,1,!0,function(){D.layout.removeClass(ya),j()}),v(1,!0)}function t(a){a?u(I,Math.sign(a)*(Ea.height()/2+P),K,!0,function(){D.close()}):u(I,J,0,!0,function(){D.close()}),v(0,!0),ha.addClass(wa)}function u(a,b,c,d,e){I=a,J=b,K=c,ca=d,da=e;var f="scale("+K+") translate3d("+I+"px, "+J+"px, 0)";Na.transition=d?"all "+D.duration+"ms ease-out":"none",Na.webkitTransform=f,Na.mozTransform=f,Na.msTransform=f,Na.oTransform=f,Na.transform=f}function v(a,b){Oa.transition=b?"opacity "+D.duration+"ms ease-out":"none",Oa.opacity=a;var c="translate3d(0, 0, 0)";Oa.webkitTransform=c,Oa.mozTransform=c,Oa.msTransform=c,Oa.oTransform=c,Oa.transform=c}function w(){Oa.transition=null,Oa.opacity=null}function x(){if(ca=!1,da){var a=da;da=null,a()}}function y(a){if(D){var b=-a.deltaY||0;return 1==a.deltaMode?b*=D.zoomVelocity*D.duration:2==a.deltaMode&&(b*=$),ha.scrollTop()||1==K&&0>b?void(La?g(a):(fa&&clearTimeout(fa),Ma=!0,fa=setTimeout(function(){Ma=!1,fa=null},D.duration))):void(Ma||(ea&&clearTimeout(ea),La=!0,ea=setTimeout(function(){La=!1,ea=null},D.duration),A(a,b)))}}function z(a){D&&1!=K&&A(a,0)}function A(a,b){p(),I=(Q-a.clientX)/(D.zoomMoveViewport*Q/O)-(Q-a.clientX)/K,J=(R-a.clientY)/(D.zoomMoveViewport*R/P)-(R-a.clientY)/K,B(b,!0),g(a)}function B(a,b){D&&(K*=(P+a)/P,K=Math.max(1,Math.min(D.zoomMax,K)),S=O-Q/K,T=P-R/K,I=S>0?Math.max(-S,Math.min(S,I)):0,J=T>0?Math.max(-T,Math.min(T,J)):0,u(I,J,K,b))}var C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,$,_,aa,ba,ca,da,ea,fa,ga=a("
").addClass("abigimage-overlay").appendTo("body"),ha=a("
").addClass("abigimage-layout").appendTo("body"),ia=a("
").addClass("abigimage-wrapper").appendTo(ha),ja=a("
").addClass("abigimage-box").appendTo(ia),ka=a("
").addClass("abigimage-prevBtnBox").appendTo(ja),la=a("
").addClass("abigimage-closeBtnBox").appendTo(ja),ma=a("
").addClass("abigimage-top").appendTo(ha),na=a("
").addClass("abigimage-prevBtn").appendTo(ma),oa=a("
").addClass("abigimage-nextBtn").appendTo(ma),pa=a("
").addClass("abigimage-counter").appendTo(ma),qa=a("
").addClass("abigimage-closeBtn").appendTo(ma),ra=a("
").addClass("abigimage-zoomOutBtn").appendTo(ma),sa=a("
").addClass("abigimage-zoomInBtn").appendTo(ma),ta=a("
").addClass("abigimage-bottomBox").appendTo(ha),ua=a("
").addClass("abigimage-bottom").appendTo(ta),va="abigimage-layout-active",wa="abigimage-layout-fadeout",xa="abigimage-layout-full",ya="abigimage-layout-zoom",za="abigimage-overlay-active",Aa="abigimage-prevBtn-hover",Ba="abigimage-nextBtn-hover",Ca="abigimage-closeBtn-hover",Da=ja[0],Ea=a(window),Fa=a("html"),Ga=a(document),Ha=a(document.body),Ia=null,Ja=null,Ka=!1,La=!1,Ma=!1,Na=Da.style,Oa=ga[0].style;a.fn.abigimage=function(b){var c=new d(this,b);return this._abigimage=c,C=c,this.each(function(b){a(this).unbind("click.abigimage").bind("click.abigimage",function(a){g(a),c.open(b)})})},a.fn.abigimage.defaults={duration:200,slideWidth:.4,slideVelocity:.4,zoomMin:1.5,zoomMax:5,zoomClose:.9,zoomMoveViewport:.9,zoomVelocity:.04,doubleTapInterval:400,prevBtnHtml:"←",nextBtnHtml:"→",zoomInBtnHtml:"+",zoomOutBtnHtml:"−",closeBtnHtml:"×",keyNext:[13,32,39,40],keyPrev:[8,37,38],keyClose:[27,35,36],onopen:null,onclose:null},a.abigimage={overlay:ga,layout:ha,wrapper:ia,box:ja,prevBtnBox:ka,closeBtnBox:la,top:ma,prevBtn:na,nextBtn:oa,zoomInBtn:sa,zoomOutBtn:ra,closeBtn:qa,counter:pa,bottomBox:ta,bottom:ua,open:function(a,b,c){(c&&c._abigimage||D||C).open(a,b)},close:function(a){(a&&a._abigimage||D||C).close()},next:function(a){(a&&a._abigimage||D||C).next()},prev:function(a){(a&&a._abigimage||D||C).prev()},unbind:function(a){(a&&a._abigimage||D||C).unbind()}},ka.click(function(a){g(a),D&&D.prev()}).hover(function(){na.addClass(Aa)},function(){na.removeClass(Aa)}),la.click(function(a){g(a),D&&D.close()}).hover(function(){qa.addClass(Ca)},function(){qa.removeClass(Ca)}),na.click(function(a){g(a),D&&D.prev()}),oa.click(function(a){g(a),D&&D.next()});var Pa=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||function(a){setTimeout(function(){a((new Date).getTime())},1e3/60)};sa.mousedown(function(a){g(a),p(),U=null,V=1,Pa(b)}).mouseup(function(a){g(a),V=null}).mouseout(function(){V=null}).click(function(a){g(a),D&&B(D.zoomVelocity*D.duration,!0)}),ra.mousedown(function(a){g(a),p(),U=null,V=-1,Pa(b)}).mouseup(function(a){g(a),V=null}).mouseout(function(){V=null}).click(function(a){g(a),D&&B(-D.zoomVelocity*D.duration,!0)}),qa.click(function(a){g(a),D&&D.close()}),Da.addEventListener&&(c(Da,"touchstart",k),c(Da,"touchmove",l),c(Da,"touchend",m),c(Da,"touchcancel",m),c(Da,"webkitTransitionEnd",x),c(Da,"mozTransitionEnd",x),c(Da,"msTransitionEnd",x),c(Da,"oTransitionEnd",x),c(Da,"transitionend",x),c(Da,"wheel",y),c(Da,"mousemove",z)),d.prototype.open=function(b,c){D=this;var d;if("number"==typeof b){if(c=b,c==this.index||0>c||c>this.elements.length-1)return;d=a(this.elements[c]),b=d.data("href")||d.attr("href")}else if("number"!=typeof c)c=this.index;else if(c==this.index)return;this.index=c,this.opened=d,this.prevBtn.html(this.prevBtnHtml),this.nextBtn.html(this.nextBtnHtml),this.zoomInBtn.html(this.zoomInBtnHtml),this.zoomOutBtn.html(this.zoomOutBtnHtml),this.closeBtn.html(this.closeBtnHtml),this.bottom.html(""),this.counter.html(c>=0?c+1+" / "+this.elements.length:""),a("img",this.box).remove(),w(),this.overlay.addClass(za),this.layout.addClass(va).removeClass(wa).scrollTop(0),u(0,0,1),this.img=e("abigimage-img",b).click(function(a){g(a),D&&D.next()}).hover(function(){oa.addClass(Ba)},function(){oa.removeClass(Ba)}).one("load",function(){h()});var i=a(this.elements[this.nextIndex()]);this.imgNext=e("abigimage-imgNext",i.data("href")||i.attr("href")).hide().one("load",function(){h()});var j=a(this.elements[this.prevIndex()]);this.imgPrev=e("abigimage-imgPrev",j.data("href")||j.attr("href")).hide().one("load",function(){h()}),h(!0),Ga.unbind("keydown",f).bind("keydown",f),null===Ia&&null===Ja&&(Ia=Fa.css("padding-right"),Ja=Ha.css("overflow-y"),Fa.css("padding-right",parseInt(Ia)+window.innerWidth-Ea.width()+"px"),Ha.css("overflow-y","hidden")),this.onopen&&this.onopen.call(this,this.opened)},d.prototype.next=function(){this.distance==this.elements.length-1?this.close():(++this.distance,this.elements[this.nextIndex()].click())},d.prototype.prev=function(){this.distance==1-this.elements.length?this.close():(--this.distance,this.elements[this.prevIndex()].click())},d.prototype.close=function(){D&&(Ga.unbind("keydown",f),Fa.css("padding-right",Ia),Ha.css("overflow-y",Ja),Ia=null,Ja=null,ga.removeClass(za),ha.removeClass(va),this.onclose&&this.onclose.call(this,this.opened),this.index=-1,this.distance=0,D=null)},d.prototype.unbind=function(){this.close(),this.elements.each(function(){a(this).unbind("click.abigimage")})},d.prototype.key=function(a){if(-1!=this.keyNext.indexOf(a))this.next();else if(-1!=this.keyPrev.indexOf(a))this.prev();else{if(-1==this.keyClose.indexOf(a))return!1;this.close()}return!0},d.prototype.nextIndex=function(){var a=this.index+1;return a>=this.elements.length&&(a=0),a},d.prototype.prevIndex=function(){var a=this.index-1;return 0>a&&(a=this.elements.length-1),a}}(jQuery); \ No newline at end of file diff --git a/bower.json b/bower.json index 7a91f7d..6332df2 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jquery-abigimage", - "description": "ABigImage - view big versions of images. Fit mobile devices. Uses CSS3 transform and transition for smooth touch sliding. Touch slide left or right opens next or previous image, touch slide up or down closes image. Multi-touch and double-tap zoom. Clicking image opens next one, clicking left side opens previous, clicking right side closes image. Hotkeys for next, previous and close buttons. Closing after viewing of all images. Preloading of next and previous images. Uses link's `href` or `data-href` attribute for large images. Fully customizable styles. Customizable bottom area. Customizable `onopen` and `onclose` event.", + "description": "ABigImage - view big versions of images. Fit mobile devices. Uses CSS3 transform and transition for smooth touch sliding. Touch slide left or right opens next or previous image, touch slide up or down closes image. Multi-touch and double-tap zoom, zoom out closes image. Clicking image opens next one, clicking left side opens previous, clicking right side closes image. Hotkeys for next, previous and close buttons. Closing after viewing of all images. Preloading of next and previous images. Images counter. Uses link's `href` or `data-href` attribute for large images. Fully customizable styles. Customizable, scrolling down bottom area. Customizable `onopen` and `onclose` event.", "main": "abigimage.jquery.min.js", "authors": [ "Maksim Krylosov (http://aeqdev.com/)" diff --git a/index.html b/index.html index 553a968..b7711a6 100644 --- a/index.html +++ b/index.html @@ -10,8 +10,20 @@ + + + +
+
+
+
+
+
+
+
+
+ + + diff --git a/tpl/example.tpl.html b/tpl/example.tpl.html index c5578d6..445f3ec 100644 --- a/tpl/example.tpl.html +++ b/tpl/example.tpl.html @@ -1,8 +1,11 @@

Example

-

+

First image - Second image + + Second image. Scroll down me, please! +
Under bottom area here.
+
Third image Fourth image

@@ -17,7 +20,10 @@

Example

$('a[href$=".jpg"]').abigimage({ onopen: function(target) { this.bottom.html( - $('img', target).attr('alt') + /* bottom caption */ + $('img', target).attr('alt') + + /* under bottom area */ + ($('span', target).html() || '') ); } }); diff --git a/tpl/index.tpl.html b/tpl/index.tpl.html index 31702a4..740b038 100644 --- a/tpl/index.tpl.html +++ b/tpl/index.tpl.html @@ -10,8 +10,20 @@