From 8cc60c0427e867c2d88c630a9e4a1ebadc78536a Mon Sep 17 00:00:00 2001 From: codecomputerlove Date: Wed, 17 Aug 2011 09:32:20 +0100 Subject: [PATCH] Check in for v2.0.0 --- README.md | 188 +- build.properties | 2 +- build.xml | 157 +- .../icons.png} | Bin .../icons@2x.png} | Bin .../loader.gif} | Bin src/{ => assets}/photoswipe.css | 36 +- src/caption-class.js | 163 - src/caption-toolbar-class.js | 374 - src/change.log | 220 - src/code.photoswipe/cache.class.js | 115 + src/code.photoswipe/cache.js | 78 + .../carousel.class.animation.js | 122 + src/code.photoswipe/carousel.class.js | 863 +++ src/code.photoswipe/carousel.js | 44 + src/code.photoswipe/documentoverlay.class.js | 131 + src/code.photoswipe/documentoverlay.js | 24 + src/code.photoswipe/image.class.js | 141 + src/code.photoswipe/image.js | 26 + src/code.photoswipe/photoswipe.class.js | 1062 +++ src/code.photoswipe/photoswipe.js | 262 + src/code.photoswipe/toolbar.class.js | 511 ++ src/code.photoswipe/toolbar.js | 59 + src/code.photoswipe/touchelement.class.js | 474 ++ src/code.photoswipe/touchelement.js | 42 + src/code.photoswipe/uilayer.class.js | 141 + src/code.photoswipe/uilayer.js | 20 + .../zoompanrotate.class.js} | 196 +- src/code.photoswipe/zoompanrotate.js | 21 + src/code.util/animation.js | 290 + src/code.util/browser.js | 91 + .../dom.jquery.js} | 160 +- src/{util-dom.js => code.util/dom.js} | 205 +- .../events.jquery.js} | 43 +- src/{util-events.js => code.util/events.js} | 85 +- src/code.util/util.js | 239 + src/document-overlay-class.js | 66 - src/element-class.js | 238 - src/examples/01-default.html | 83 + src/examples/02-jquery.html | 84 + src/examples/03-multiple-image-sets.html | 92 + src/examples/04-jquery-mobile.html | 146 + ...e-ajax.html => 05-jquery-mobile-ajax.html} | 68 +- src/examples/06-events.html | 158 + src/examples/07-custom-toolbar.html | 107 + src/examples/08-exclusive-mode.html | 87 + .../09-exclusive-mode-no-thumbnails.html | 68 + src/examples/advanced-setup.html | 182 - src/examples/ajax-gallery1.html | 52 +- src/examples/ajax-gallery2.html | 49 +- src/examples/debug-jquery-mobile.html | 173 + src/examples/debug-jquery.html | 259 + src/examples/debug.html | 392 +- src/examples/events.html | 243 - src/examples/exclusive-mode-with-array.html | 74 - src/examples/exclusive-mode.html | 109 - src/examples/index.html | 148 - .../jquery-engine-animate-enhanced.html | 128 - src/examples/jquery-engine.html | 135 - src/examples/jquery-mobile.css | 6 + src/examples/jquery-mobile.html | 187 - src/examples/jquery-plugin.html | 131 - src/examples/styles.css | 10 +- src/examples/using-meta-data.html | 143 - src/full-size-image-class.js | 98 - src/lib/jquery-1.6.2.min.js | 18 + src/lib/jquery.animate-enhanced.min.js | 9 - .../images/icons-18-black.png | Bin 2138 -> 0 bytes .../images/icons-18-white.png | Bin 2207 -> 0 bytes .../images/icons-36-black.png | Bin 4011 -> 0 bytes .../images/icons-36-white.png | Bin 4343 -> 0 bytes .../jquery.mobile-1.0b1.min.css | 8 - .../jquery.mobile-1.0b1.min.js | 146 - .../images/ajax-loader.png | Bin .../images/icon-search-black.png | Bin .../images/icons-18-black.png | Bin 0 -> 2064 bytes .../images/icons-18-white.png | Bin 0 -> 2200 bytes .../images/icons-36-black.png | Bin 0 -> 3403 bytes .../images/icons-36-white.png | Bin 0 -> 4020 bytes .../jquery.mobile-1.0b2.css} | 347 +- .../jquery.mobile-1.0b2.js} | 6177 +++++++++-------- .../jquery.mobile-1.0b2.min.css | 8 + .../jquery.mobile-1.0b2.min.js | 155 + src/lib/klass.min.js | 8 + src/lib/simple-inheritance.js | 64 - src/lib/simple-inheritance.txt | 4 - src/photoswipe.js | 1518 ---- src/slider-class.js | 408 -- src/slider-item-class.js | 301 - src/toolbar-class.js | 316 - src/util-animation-jQuery.js | 100 - src/util-animation.js | 321 - src/util.js | 275 - src/version-header.txt | 4 - src/viewport-class.js | 478 -- tools/jslint4java-2.0.0/jslint4java-2.0.0.jar | Bin 0 -> 1026207 bytes tools/jsmin/jsmin.0.2.4.jar | Bin 6324 -> 0 bytes 97 files changed, 10710 insertions(+), 10256 deletions(-) rename src/{photoswipe-icons.png => assets/icons.png} (100%) rename src/{photoswipe-icons@2x.png => assets/icons@2x.png} (100%) rename src/{photoswipe-loader.gif => assets/loader.gif} (100%) rename src/{ => assets}/photoswipe.css (83%) delete mode 100644 src/caption-class.js delete mode 100644 src/caption-toolbar-class.js delete mode 100644 src/change.log create mode 100644 src/code.photoswipe/cache.class.js create mode 100644 src/code.photoswipe/cache.js create mode 100644 src/code.photoswipe/carousel.class.animation.js create mode 100644 src/code.photoswipe/carousel.class.js create mode 100644 src/code.photoswipe/carousel.js create mode 100644 src/code.photoswipe/documentoverlay.class.js create mode 100644 src/code.photoswipe/documentoverlay.js create mode 100644 src/code.photoswipe/image.class.js create mode 100644 src/code.photoswipe/image.js create mode 100644 src/code.photoswipe/photoswipe.class.js create mode 100644 src/code.photoswipe/photoswipe.js create mode 100644 src/code.photoswipe/toolbar.class.js create mode 100644 src/code.photoswipe/toolbar.js create mode 100644 src/code.photoswipe/touchelement.class.js create mode 100644 src/code.photoswipe/touchelement.js create mode 100644 src/code.photoswipe/uilayer.class.js create mode 100644 src/code.photoswipe/uilayer.js rename src/{zoom-pan-rotate-class.js => code.photoswipe/zoompanrotate.class.js} (54%) create mode 100644 src/code.photoswipe/zoompanrotate.js create mode 100644 src/code.util/animation.js create mode 100644 src/code.util/browser.js rename src/{util-dom-jQuery.js => code.util/dom.jquery.js} (72%) rename src/{util-dom.js => code.util/dom.js} (71%) rename src/{util-events-jQuery.js => code.util/events.jquery.js} (71%) rename src/{util-events.js => code.util/events.js} (75%) create mode 100644 src/code.util/util.js delete mode 100644 src/document-overlay-class.js delete mode 100644 src/element-class.js create mode 100644 src/examples/01-default.html create mode 100644 src/examples/02-jquery.html create mode 100644 src/examples/03-multiple-image-sets.html create mode 100644 src/examples/04-jquery-mobile.html rename src/examples/{jquery-mobile-ajax.html => 05-jquery-mobile-ajax.html} (50%) create mode 100644 src/examples/06-events.html create mode 100644 src/examples/07-custom-toolbar.html create mode 100644 src/examples/08-exclusive-mode.html create mode 100644 src/examples/09-exclusive-mode-no-thumbnails.html delete mode 100644 src/examples/advanced-setup.html create mode 100644 src/examples/debug-jquery-mobile.html create mode 100644 src/examples/debug-jquery.html delete mode 100644 src/examples/events.html delete mode 100644 src/examples/exclusive-mode-with-array.html delete mode 100644 src/examples/exclusive-mode.html delete mode 100644 src/examples/index.html delete mode 100644 src/examples/jquery-engine-animate-enhanced.html delete mode 100644 src/examples/jquery-engine.html create mode 100644 src/examples/jquery-mobile.css delete mode 100644 src/examples/jquery-mobile.html delete mode 100644 src/examples/jquery-plugin.html delete mode 100644 src/examples/using-meta-data.html delete mode 100644 src/full-size-image-class.js create mode 100644 src/lib/jquery-1.6.2.min.js delete mode 100644 src/lib/jquery.animate-enhanced.min.js delete mode 100644 src/lib/jquery.mobile-1.0b1/images/icons-18-black.png delete mode 100644 src/lib/jquery.mobile-1.0b1/images/icons-18-white.png delete mode 100644 src/lib/jquery.mobile-1.0b1/images/icons-36-black.png delete mode 100644 src/lib/jquery.mobile-1.0b1/images/icons-36-white.png delete mode 100644 src/lib/jquery.mobile-1.0b1/jquery.mobile-1.0b1.min.css delete mode 100644 src/lib/jquery.mobile-1.0b1/jquery.mobile-1.0b1.min.js rename src/lib/{jquery.mobile-1.0b1 => jquery.mobile-1.0b2}/images/ajax-loader.png (100%) rename src/lib/{jquery.mobile-1.0b1 => jquery.mobile-1.0b2}/images/icon-search-black.png (100%) create mode 100644 src/lib/jquery.mobile-1.0b2/images/icons-18-black.png create mode 100644 src/lib/jquery.mobile-1.0b2/images/icons-18-white.png create mode 100644 src/lib/jquery.mobile-1.0b2/images/icons-36-black.png create mode 100644 src/lib/jquery.mobile-1.0b2/images/icons-36-white.png rename src/lib/{jquery.mobile-1.0b1/jquery.mobile-1.0b1.css => jquery.mobile-1.0b2/jquery.mobile-1.0b2.css} (79%) rename src/lib/{jquery.mobile-1.0b1/jquery.mobile-1.0b1.js => jquery.mobile-1.0b2/jquery.mobile-1.0b2.js} (57%) create mode 100644 src/lib/jquery.mobile-1.0b2/jquery.mobile-1.0b2.min.css create mode 100644 src/lib/jquery.mobile-1.0b2/jquery.mobile-1.0b2.min.js create mode 100644 src/lib/klass.min.js delete mode 100644 src/lib/simple-inheritance.js delete mode 100644 src/lib/simple-inheritance.txt delete mode 100644 src/photoswipe.js delete mode 100644 src/slider-class.js delete mode 100644 src/slider-item-class.js delete mode 100644 src/toolbar-class.js delete mode 100644 src/util-animation-jQuery.js delete mode 100644 src/util-animation.js delete mode 100644 src/util.js delete mode 100644 src/version-header.txt delete mode 100644 src/viewport-class.js create mode 100644 tools/jslint4java-2.0.0/jslint4java-2.0.0.jar delete mode 100644 tools/jsmin/jsmin.0.2.4.jar diff --git a/README.md b/README.md index 5475109f7..959a4dc04 100644 --- a/README.md +++ b/README.md @@ -7,21 +7,15 @@ Inspired by the iOS photo viewer and Google images for mobile, PhotoSwipe is a H The current version supports mobile handsets running WebKit based browsers, i.e. iOS, Android and Blackberry 6. -PhotoSwipe also runs on the desktop and has been tested on Chrome, Firefox, Safari and Internet Explorer 8 and above. +PhotoSwipe also runs on the desktop and has been tested on Chrome, Firefox, Safari and Internet Explorer 8 and above and in a limited capacity on Windows Phone 7 (Mango). -VERSION 2.0.0b1 NOW AVAILABLE! ------------------------------- -A beta release of the next version of PhotoSwipe is now available to [download](http://github.com/downloads/codecomputerlove/PhotoSwipe/code.photoswipe-2.0.0b1.zip). +Latest Release v2.0.0 +--------------------- +[Download](http://github.com/downloads/codecomputerlove/PhotoSwipe/code.photoswipe-2.0.0.zip) -This is a brand new version of PhotoSwipe re-written from the ground up. - -THIS VERSION IS FOR TESTING / REVIEW PURPOSES ONLY. - -Unfortunately, to cram in all the great new features, this has meant that how you implement PhotoSwipe had to be modified. I've kept configuration settings etc as close to v1 where possible. - -It would be great to get any feedback on this before we officially launch v2. +This is a brand new version of PhotoSwipe re-written from the ground up. Unfortunately, to cram in all the great new features, this has meant that how you implement PhotoSwipe had to be modified. I've kept configuration settings etc as close to v1 where possible. It's recommended you review the examples to see how to implement v2. New features include: @@ -43,18 +37,7 @@ It's recommended you review the examples to see how to implement v2. New feature And a host of other under the hood amends, tweaks and fixes. - - - -Latest Release v1.0.19 ----------------------- -[Download](http://github.com/downloads/codecomputerlove/PhotoSwipe/code-photoswipe.v1.0.19.zip) - -- Fixed issue with Util.DOM.removeClass - -- Typo in events.html corrected - -- Added hi-res css dedection like how jQuery Mobile does it +If you still require v1, you can find the [last build here](https://github.com/downloads/codecomputerlove/PhotoSwipe/code-photoswipe.v1.0.19.zip) @@ -88,18 +71,19 @@ Features - Comprehensive customisation options: - Presentation controlled via CSS - + - Set whether the gallery loops or not i.e. when you reach the end, is the next image the first image, or does the gallery show a bounce effect to indicate that you have reached the end. - Hide or show captions and toolbar - + - Change caption and toolbar positions - + + - Provide your own toolbar HTML + - Set the speeds of all animations used, from sliding in to fading. - - + Getting Started --------------- @@ -111,116 +95,143 @@ There are two distributions of the library: - The jQuery distribution that uses jQuery as it's engine. -It is recommended for WebKit based mobile devices to use the default distribution. This distribution will run faster. It does not require jQuery (so one less library to download to your mobile device). It also uses CSS3 to achieve animation effects. This is extremely noticable when running on an iOS device as animation will use hardware acceleration and will feel more "native" to the device. The default distribution will also work on desktop WebKit browsers (such as Chrome and Safari) as well as Firefox. - -Use the jQuery distibution if you need to support a wider range of browsers such as Internet Explorer etc. By default, this distribution will not use hardware acceleration for animation on iOS devices so is noticably slower. You can however override the default animation functionality in jQuery by including the excellent [Animate Enhanced](https://github.com/benbarnett/jQuery-Animate-Enhanced) library (example included). +It is recommended for WebKit based mobile devices to use the default distribution. This negates a lot of the overhead from using jQuery. It does not require jQuery (so one less library to download to your mobile device!). The default distribution will also work on desktop WebKit browsers (such as Chrome and Safari) as well as Firefox 4 and above. -Both default and jQuery distribution come with a jQuery plugin wrapper to bind elements to the gallery. So for the default distribution, if you really need to, you can still use jQuery to find your images in your HTML document, hook into the jQuery DOM ready event and use the jQuery PhotoSwipe plugin to display the library. The gallery will still be running on the default optimised engine, but you have the convience of jQuery to set things up should you need to. +Use the jQuery distibution if you need to support a wider range of browsers such as Internet Explorer etc. Getting Started - Default Distribution -------------------------------------- -See "examples/index.html". +See "examples/01-default.html". -This example assumes no jQuery at all and is heavily optimised for WebKit and Mozilla browsers. +This example assumes no jQuery at all and is heavily optimised for WebKit and Mozilla browsers. PhotoSwipe.attach takes two parameters, an array of HTML elements and optional options. // Set up PhotoSwipe with all anchor tags in the Gallery container document.addEventListener('DOMContentLoaded', function(){ - Code.photoSwipe('a', '#Gallery'); + var myPhotoSwipe = PhotoSwipe.attach( window.document.querySelectorAll('#Gallery a'), { enableMouseWheel: false , enableKeyboard: false } ); }, false); - - -Getting Started - Default Distribution (with jQuery plugin) ------------------------------------------------------------ - -See "examples/jquery-plugin.html". -This example assumes you want to use the convience of jQuery for initiating the gallery, but still the optimised engine for WebKit and Mozilla browsers. - $(document).ready(function(){ - - $("#Gallery a").photoSwipe(); - - }); +PhotoSwipe can be initiated without being attached to HTML elements. See "examples/09-exclusive-mode-no-thumbnails.html" for more information. + + - Getting Started - Default Distribution (with jQuery engine) ----------------------------------------------------------- -See "examples/jquery-engine.html". +See "examples/02-jquery.html". + + // Set up PhotoSwipe with all anchor tags in the Gallery container + $(document).ready(function(){ + + var myPhotoSwipe = $("#Gallery a").photoSwipe({ enableMouseWheel: false , enableKeyboard: false }); + + }); + -This example assumes you want to use jQuery for the gallery's engine as well as initiating the gallery. It is not advised to use this approach if you are targetting mobile WebKit based devices. - Options ------- -- **fadeInSpeed**: The speed of any fading-in elements in milliseconds. Default "250" +- **allowUserZoom**: Allow the user to zoom / pan around images. Default = true + +- **autoStartSlideshow**: Automatically starts the slideshow mode when PhotoSwipe is activated. Default = false + +- **allowRotationOnUserZoom**: iOS only - Allow the user to rotate images whilst zooming / panning. Default = false + +- **backButtonHideEnabled**: This will hide the gallery when the user hits the back button. Useful for Android and Blackberry. Works in BB6, Android v2.1 and above and iOS 4 and above. Default = true + +- **captionAndToolbarAutoHideDelay**: How long to wait before the caption and toolbar automatically disappear. Default = 5000. Set to 0 to prevent auto disappearing + +- **captionAndToolbarFlipPosition**: Place the caption at the bottom and the toolbar at the top. Default = false + +- **captionAndToolbarHide**: Hide the caption and toolbar. Default = false + +- **captionAndToolbarOpacity**: The opacity of the caption and toolbar. Default = 0.8 + +- **captionAndToolbarShowEmptyCaptions**: Shows a blank caption area even if a caption cannot be found for the current image. Default = true + +- **cacheMode**: Code.PhotoSwipe.Cache.Mode.normal (default) or Code.PhotoSwipe.Cache.Mode.aggressive. Changes how PhotoSwipe manages it's cache. Aggressive will purposely set images that are not either the current, next or previous to be an empty "spacer" type image. This helps on older iOS versions if you have excessively large images. In the main, normal should suffice + +- **doubleTapSpeed**: Double tap speed in milliseconds. Default = 300 + +- **doubleTapZoomLevel**: When the user double taps an image, the default "zoom-in" level. Default = 2.5 + +- **enableDrag**: Enables dragging the next / previous image into view. Default = true -- **fadeOutSpeed**: The speed of any fading-out elements in milliseconds. Default "500" +- **enableKeyboard**: Enables keyboard support. Default = true -- **slideSpeed**: How fast images slide into view in milliseconds. Default "250" - -- **swipeThreshold**: How many pixels your finger has to move across the screen to register a swipe gesture. Default "50" +- **enableMouseWheel**: Enables mouse wheel support. Default = true -- **swipeTimeThreshold**: A swipe must take no longer than this value in milli-seconds to be registered as a swipe gesture. Default "250" +- **fadeInSpeed**: The speed of any fading-in elements in milliseconds. Default = 250 -- **loop**: Whether the gallery auto-loops back to the beginning when you reach the end. Default "true" +- **fadeOutSpeed**: The speed of any fading-out elements in milliseconds. Default = 250 -- **slideshowDelay**: The delay between showing the next image when in slideshow mode. Default "3000" - -- **imageScaleMethod**: How images will fit onto the screen. Either "fit", "fitNoUpscale" or "zoom". "fit" ensures the image always fits the screen. "fitNoUpscale" works like "fit" but will never upscale the image. "zoom" the image will always fill the full screen, this may cause the image to be "zoomed" in and cropped. Default "fit" +- **imageScaleMethod**: How images will fit onto the screen. Either "fit", "fitNoUpscale" or "zoom". "fit" ensures the image always fits the screen. "fitNoUpscale" works like "fit" but will never upscale the image. "zoom" the image will always fill the full screen, this may cause the image to be "zoomed" in and cropped. Default = "fit" -- **preventHide**: Once PhotoSwipe is active, prevents the user closing it. Useful for "exclusive mode" (see examples/exclusive-mode.html). Default "false" +- **invertMouseWheel**: By default, moving the mouse wheel down will move to the next image, up to the previous. Setting this to true reverses this. Default = false -- **zIndex**: The intial zIndex for PhotoSwipe. Default "1000" +- **jQueryMobile**:Whether PhotoSwipe is integrated into a jQuery Mobile project or not. By default, PhotoSwipe will try and work this out for you -- **backButtonHideEnabled**: This will hide the gallery when the user hits the back button. Useful for Android and Blackberry. Works in BB6, Android v2.1 and above and iOS 4 and above. Default "true" +- **jQueryMobileDialogHash**: The window hash tag used by jQuery Mobile and dialog pages. Default = "&ui-state=dialog" -- **allowUserZoom**: Allow the user to zoom / pan around images. Default "true" +- **loop**: Whether the gallery auto-loops back to the beginning when you reach the end. Default = true -- **allowRotationOnUserZoom**: iOS only - Allow the user to rotate images whilst zooming / panning. Default "true" +- **margin**: The margin between each image in pixels. Default = 20 -- **maxUserZoom**: The maximum a user can zoom into an image. Default 5.0 (set to zero for this to be ignored) +- **maxUserZoom**: The maximum a user can zoom into an image. Default = 5.0 (set to zero for this to be ignored) -- **minUserZoom**: The minimum a user can zoom out of an image. Default 0.5 (set to zero for this to be ignored) +- **minUserZoom**: The minimum a user can zoom out of an image. Default = 0.5 (set to zero for this to be ignored) -- **adjustUserPanToZoom**: Adjusts the speed of panning to match the current zoom value. Default "true" +- **mouseWheelSpeed**: How responsive the mouse wheel is. Default = 500 -- **doubleClickSpeed**: Double click speed. Default "300" (in milliseconds) +- **nextPreviousSlideSpeed**: How fast images are displayed when the next/previous buttons are clicked in milliseconds. Default = 0 (immediately) -- **doubleClickZoom**: When the user double clicks an image, the default "zoom-in" level. Default 2.5 +- **preventHide**: Prevents the user closing PhotoSwipe. Also hides the "close" button from the toolbar. Useful for "exclusive mode" (see examples/08-exclusive-mode.html). Default = false -- **captionAndToolbarHide**: Hide the caption and toolbar. Default "false" +- **preventSlideshow**: Prevents the slideshow being activated. Also hides the "play" button from the toolbar. Default = false -- **captionAndToolbarHideOnSwipe**: Hide the caption and toolbar when you swipe to the next image. Default "true" +- **slideshowDelay**: The delay between showing the next image when in slideshow mode in milliseconds. Default = 3000 -- **captionAndToolbarFlipPosition**: Place the caption at the bottom and the toolbar at the top. Default "false" +- **slideSpeed**: How fast images slide into view in milliseconds. Default = 250 -- **captionAndToolbarAutoHideDelay**: How long to wait before the caption and toolbar automatically disappear. Default "5000". Set to "0" to prevent auto disappearing +- **swipeThreshold**: How many pixels your finger has to move across the screen to register a swipe gesture. Default = 50 -- **captionAndToolbarOpacity**: The opacity of the caption and toolbar. Default "0.8" +- **swipeTimeThreshold**: A swipe must take no longer than this value in milliseconds to be registered as a swipe gesture. Default = 250 -- **captionAndToolbarShowEmptyCaptions**: Shows a blank caption area even if a caption cannot be found for the current image. Default "false" +- **slideTimingFunction**: Easing function used when sliding. Default = "ease-out -- **jQueryMobile**: Whether PhotoSwipe is integrated into a jQuery Mobile project or not. By default, PhotoSwipe will try and work this out for you. +- **zIndex**: The intial zIndex for PhotoSwipe. Default = 1000 -- **jQueryMobileDialogHash**: The window hash tag used by jQuery Mobile and dialog pages. Default "&ui-state=dialog". + + +Options - Custom Functions +-------------------------- + +You can provide your own functions to tell PhotoSwipe how to work with your mark up etc. + +- **getToolbar**: Function that returns the HTML string to be used for the toolbar content - **getImageSource**: Function to specify how the gallery obatins image sources. By default, the gallery assumes you send it a list of images with each image wrapped in an anchor tag. The anchor tag will contain the URL to the full size image. You can change this e.g. if you supply a list of images without an anchor tag, and supply the full size URL on the image's "rel" attribute: - Code.photoSwipe('a', '#Gallery', { + + document.addEventListener('DOMContentLoaded', function(){ - getImageSource: function(el){ - return el.getAttribute('rel'); - } + var myPhotoSwipe = PhotoSwipe.attach( window.document.querySelectorAll('#Gallery a'), { + + getImageSource: function(el){ + return el.getAttribute('rel'); + } + + } ); - }); - + }, false); + + - **getImageCaption**: Like "getImageSource", function to specify how the gallery obatins image captions. By default, the gallery looks for an image's "alt" tag. @@ -233,8 +244,9 @@ Options } } - - + + + Keyboard controls for desktop browsers -------------------------------------- @@ -245,3 +257,5 @@ Keyboard controls for desktop browsers - **Escape**: Close gallery - **Space bar**: Show toolbar / caption if they have faded from view. If both are hidden via the configuration, space bar will close the gallery + +- **Enter**: Start slideshow \ No newline at end of file diff --git a/build.properties b/build.properties index 59e51d552..0801c58dd 100644 --- a/build.properties +++ b/build.properties @@ -5,7 +5,7 @@ project.description = PhotoSwipe project.src.dir = src -project.build.version = 1.0.19 +project.build.version = 2.0.0 project.build.year = 2011 project.build.workdir = work diff --git a/build.xml b/build.xml index af9dd5f0f..b0d7d2e40 100644 --- a/build.xml +++ b/build.xml @@ -1,16 +1,17 @@ - - - - + + + + + @@ -24,13 +25,12 @@ - - + @@ -43,92 +43,116 @@ - + + + + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - - - - + + + - + - - - - + + + - - - - - - - + - + + - + + - + + - + + - + + - + + - + + - + + - + @@ -142,26 +166,6 @@ - - - - - - - - - - - - - - - - - - @@ -181,10 +185,10 @@ - - - - + + + + @@ -195,9 +199,8 @@ - - + \ No newline at end of file diff --git a/src/photoswipe-icons.png b/src/assets/icons.png similarity index 100% rename from src/photoswipe-icons.png rename to src/assets/icons.png diff --git a/src/photoswipe-icons@2x.png b/src/assets/icons@2x.png similarity index 100% rename from src/photoswipe-icons@2x.png rename to src/assets/icons@2x.png diff --git a/src/photoswipe-loader.gif b/src/assets/loader.gif similarity index 100% rename from src/photoswipe-loader.gif rename to src/assets/loader.gif diff --git a/src/photoswipe.css b/src/assets/photoswipe.css similarity index 83% rename from src/photoswipe.css rename to src/assets/photoswipe.css index b196e4bf6..fa77b2152 100644 --- a/src/photoswipe.css +++ b/src/assets/photoswipe.css @@ -1,30 +1,31 @@ /* - * PhotoSwipe - http://www.photoswipe.com/ - * Copyright (c) 2011 by Code Computerlove (http://www.codecomputerlove.com) + * photoswipe.css + * Copyright (c) %%year%% by Code Computerlove (http://www.codecomputerlove.com) * Licensed under the MIT license * - * Default styles for SwipeGallery + * Default styles for PhotoSwipe * Avoid any position or dimension based styles * where possible, unless specified already here. * The gallery automatically works out gallery item * positions etc. */ -body.ps-active + +body.ps-active, body.ps-building { - -webkit-text-size-adjust: none; + background: #000; overflow: hidden; } body.ps-active * { -webkit-tap-highlight-color: rgba(255, 255, 255, 0); + display: none; } body.ps-active *:focus { outline: 0; } - /* Document overlay */ div.ps-document-overlay { @@ -32,11 +33,12 @@ div.ps-document-overlay } -/* Viewport */ -div.ps-viewport -{ +/* UILayer */ +div.ps-uilayer { + background: #000; cursor: pointer; + } @@ -44,12 +46,13 @@ div.ps-viewport div.ps-zoom-pan-rotate{ background: #000; } +div.ps-zoom-pan-rotate * { display: block; } -/* Slider */ -div.ps-slider-item-loading +/* Carousel */ +div.ps-carousel-item-loading { - background: url(photoswipe-loader.gif) no-repeat center center; + background: url(loader.gif) no-repeat center center; } @@ -65,6 +68,7 @@ div.ps-caption font-family: "Lucida Grande", Helvetica, Arial,Verdana, sans-serif; text-align: center; } +div.ps-caption * { display: block; } div.ps-caption-bottom { @@ -76,6 +80,7 @@ div.ps-caption-bottom div.ps-caption-content { padding: 13px; + display: block; } @@ -94,6 +99,9 @@ div.ps-toolbar display: table; table-layout: fixed; } +div.ps-toolbar * { + display: block; +} div.ps-toolbar-top { @@ -112,7 +120,7 @@ div.ps-toolbar div div.ps-toolbar-content width: 44px; height: 44px; margin: 0 auto 0; - background-image: url(photoswipe-icons.png); + background-image: url(icons.png); background-repeat: no-repeat; } @@ -157,6 +165,6 @@ div.ps-toolbar-play div.ps-toolbar-content -o-background-size: 176px 88px; -webkit-background-size: 176px 88px; background-size: 176px 88px; - background-image: url(photoswipe-icons@2x.png); + background-image: url(icons@2x.png); } } \ No newline at end of file diff --git a/src/caption-class.js b/src/caption-class.js deleted file mode 100644 index 9459a3174..000000000 --- a/src/caption-class.js +++ /dev/null @@ -1,163 +0,0 @@ -// PhotoSwipe - http://www.photoswipe.com/ -// Copyright (c) %%year%% by Code Computerlove (http://www.codecomputerlove.com) -// Licensed under the MIT license -// version: %%version%% - -(function(window, Util){ - - /* - * Class: Code.PhotoSwipe.CaptionClass - */ - Code.PhotoSwipe.CaptionClass = Code.PhotoSwipe.ElementClass.extend({ - - contentEl: null, - - touchMoveHandler: null, - - captionValue: null, - - - /* - * Function: init - */ - init: function(options){ - - this.settings = { - position: 'top', - zIndex: 1000 - }; - - Util.extend(this.settings, options); - - this._super(this.settings); - - this.captionValue = ''; - - this.touchMoveHandler = this.onTouchMove.bind(this); - - // Create element and append to body - var cssClass = Code.PhotoSwipe.CaptionClass.CssClasses.caption; - if (this.settings.position === 'bottom'){ - cssClass = cssClass + ' ' + Code.PhotoSwipe.CaptionClass.CssClasses.bottom; - } - - this.el = Util.DOM.createElement('div', { 'class': cssClass }, ''); - Util.DOM.setStyle(this.el, { - left: 0, - position: 'absolute', - overflow: 'hidden', - zIndex: this.settings.zIndex, - opacity: 0 - }); - Util.DOM.hide(this.el); - Util.DOM.appendToBody(this.el); - - this.contentEl = Util.DOM.createElement('div', { 'class': Code.PhotoSwipe.CaptionClass.CssClasses.content }, ''); - Util.DOM.appendChild(this.contentEl, this.el); - - }, - - - - /* - * Function: addEventHandlers - */ - addEventHandlers: function(){ - - if (Util.browser.touchSupported){ - Util.Events.add(this.el, 'touchmove', this.touchMoveHandler); - } - - }, - - - - /* - * Function: removeEventHandlers - */ - removeEventHandlers: function(){ - - if (Util.browser.touchSupported){ - Util.Events.remove(this.el, 'touchmove', this.touchMoveHandler); - } - - }, - - - - /* - * Function: onTouch - */ - onTouchMove: function(e){ - - e.preventDefault(); - - }, - - - - /* - * Function: resetPosition - */ - resetPosition: function(){ - - var top; - - if (this.settings.position === 'bottom') { - top = Util.DOM.windowHeight() - Util.DOM.outerHeight(this.el) + Util.DOM.windowScrollTop(); - } - else { - top = Util.DOM.windowScrollTop(); - } - - Util.DOM.setStyle(this.el, 'top', top + 'px'); - Util.DOM.width(this.el, Util.DOM.bodyOuterWidth()); - - }, - - - - /* - * Function: setCaptionValue - */ - setCaptionValue: function(captionValue){ - - Util.DOM.removeChildren(this.contentEl); - - captionValue = Util.coalesce(captionValue, '\u00A0'); - - if (Util.isObject(captionValue)){ - Util.DOM.appendChild(captionValue, this.contentEl); - } - else{ - if (captionValue === ''){ - captionValue = '\u00A0'; - } - Util.DOM.appendText(captionValue, this.contentEl); - } - - this.captionValue = (captionValue === '\u00A0') ? '' : captionValue; - - //Util.DOM.show(this.el); - //var height = Util.DOM.height(this.el); - //Util.DOM.hide(this.el); - //console.log(height); - - } - - - - }); - - - Code.PhotoSwipe.CaptionClass.CssClasses = { - caption: 'ps-caption', - bottom: 'ps-caption-bottom', - content: 'ps-caption-content' - }; - -}) -( - window, - Code.PhotoSwipe.Util -); diff --git a/src/caption-toolbar-class.js b/src/caption-toolbar-class.js deleted file mode 100644 index 7e998fb9e..000000000 --- a/src/caption-toolbar-class.js +++ /dev/null @@ -1,374 +0,0 @@ -// PhotoSwipe - http://www.photoswipe.com/ -// Copyright (c) %%year%% by Code Computerlove (http://www.codecomputerlove.com) -// Licensed under the MIT license -// version: %%version%% - -(function(window, Util, CaptionClass, ToolbarClass){ - - /* - * Class: Code.PhotoSwipe.CaptionToolbarClass - */ - Code.PhotoSwipe.CaptionToolbarClass = SimpleClass.extend({ - - toolbar: null, - caption: null, - - isHidden: null, - - hasAddedEventHandlers: null, - - toolbarClickEventHandler: null, - - - /* - * Function: init - */ - init: function(options){ - - this.settings = { - opacity: 0.8, - fadeInSpeed: 250, - fadeOutSpeed: 500, - autoHideDelay: 5000, - flipPosition: false, - showEmptyCaptions: true, - hideClose: false, - zIndex: 1000 - }; - - Util.extend(this.settings, options); - - this.isHidden = true; - this.hasAddedEventHandlers = false; - - this.toolbarClickEventHandler = this.onToolbarClick.bind(this); - - this.caption = new CaptionClass({ - fadeInSpeed: this.settings.fadeInSpeed, - fadeOutSpeed: this.settings.fadeOutSpeed, - opacity: this.settings.opacity, - position: (this.settings.flipPosition) ? 'bottom' : 'top', - zIndex: this.settings.zIndex - }); - - - this.toolbar = new ToolbarClass({ - fadeInSpeed: this.settings.fadeInSpeed, - fadeOutSpeed: this.settings.fadeOutSpeed, - opacity: this.settings.opacity, - position: (this.settings.flipPosition) ? 'top' : 'bottom', - hideClose: this.settings.hideClose, - zIndex: this.settings.zIndex+1 - }); - - }, - - - - /* - * Function: resetPosition - */ - resetPosition: function(){ - - this.caption.resetPosition(); - this.toolbar.resetPosition(); - - }, - - - - /* - * Function: addEventHandlers - */ - addEventHandlers: function(){ - - if (this.hasAddedEventHandlers){ - return; - } - - Util.Events.add(this.toolbar, ToolbarClass.EventTypes.onClick, this.toolbarClickEventHandler); - - this.hasAddedEventHandlers = true; - - }, - - - - /* - * Function: removeEventHandlers - */ - removeEventHandlers: function(){ - - Util.Events.remove(this.toolbar, ToolbarClass.EventTypes.onClick, this.toolbarClickEventHandler); - this.hasAddedEventHandlers = false; - - }, - - - - /* - * Function: fadeIn - */ - fadeIn: function(){ - - this.stopAutoHideTimeout(); - this.stopFade(); - - if (this.isHidden){ - - this.isHidden = false; - - // Already hidden so fade in - this.fadeInCaption(); - - this.toolbar.fadeIn(); - - window.setTimeout( - this.onFadeIn.bind(this), - this.settings.fadeInSpeed - ); - - } - else{ - - // Not hidden, just check caption is visible - if (this.caption.isHidden){ - this.fadeInCaption(); - } - - // Reset the autoHideTimeout - this.resetAutoHideTimeout(); - - } - - }, - - - - showCaption: function(){ - - if (this.caption.captionValue === ''){ - - // Caption is empty - if (this.settings.showEmptyCaptions){ - this.caption.show(); - } - - } - else{ - this.caption.show(); - } - - }, - - - - /* - * Function: fadeInCaption - */ - fadeInCaption: function(){ - - if (this.caption.captionValue === ''){ - // Caption is empty - if (this.settings.showEmptyCaptions){ - this.caption.fadeIn(); - } - } - else{ - this.caption.fadeIn(); - } - - }, - - - - /* - * Function: onFadeIn - */ - onFadeIn: function(){ - - this.addEventHandlers(); - this.resetAutoHideTimeout(); - - Util.Events.fire(this, { - type: Code.PhotoSwipe.CaptionToolbarClass.EventTypes.onShow, - target: this - }); - - }, - - - - /* - * Function: fadeOut - */ - fadeOut: function(){ - - this.stopAutoHideTimeout(); - this.stopFade(); - - this.isHidden = true; - - this.caption.fadeOut(); - this.toolbar.fadeOut(); - - window.setTimeout( - this.onFadeOut.bind(this), - this.settings.fadeOutSpeed - ); - - }, - - - /* - * Function: onFadeOut - */ - onFadeOut: function(){ - - Util.Events.fire(this, { - type: Code.PhotoSwipe.CaptionToolbarClass.EventTypes.onHide, - target: this - }); - - }, - - - - /* - * Function: stopFade - */ - stopFade: function(){ - - this.caption.stopFade(); - this.toolbar.stopFade(); - - }, - - - /* - * Function: hide - */ - hide: function(){ - - this.stopAutoHideTimeout(); - this.stopFade(); - - this.isHidden = true; - this.removeEventHandlers(); - - this.caption.hide(); - this.toolbar.hide(); - - Util.Events.fire(this, { - type: Code.PhotoSwipe.CaptionToolbarClass.EventTypes.onHide, - target: this - }); - - }, - - - - /* - * Function: setCaptionValue - */ - setCaptionValue: function(captionValue){ - - this.caption.setCaptionValue(captionValue); - - if (this.caption.captionValue === '' && !this.settings.showEmptyCaptions){ - // The caption is empty and we don't want to show empty caption - this.caption.fadeOut(); - } - - - }, - - - - /* - * Function: resetAutoHideTimeout - */ - resetAutoHideTimeout: function(){ - - if (this.isHidden){ - return; - } - - this.stopAutoHideTimeout(); - - if (this.settings.autoHideDelay > 0){ - - this.autoHideTimeout = window.setTimeout( - this.fadeOut.bind(this), - this.settings.autoHideDelay - ); - - } - - }, - - - - /* - * Function: stopAutoHideTimeout - */ - stopAutoHideTimeout: function(){ - - if (!Util.isNothing(this.autoHideTimeout)){ - window.clearTimeout(this.autoHideTimeout); - } - - }, - - - - /* - * Function: onToolbarClick - */ - onToolbarClick: function(e){ - - Util.Events.fire(this, { - type: Code.PhotoSwipe.ToolbarClass.EventTypes.onClick, - target: this, - action: e.action - }); - - }, - - - - /* - * Function: setNextState - */ - setNextState: function (disable) { - - this.toolbar.setNextState(disable); - - }, - - - - /* - * Function: setPreviousState - */ - setPreviousState: function (disable) { - - this.toolbar.setPreviousState(disable); - - } - - - }); - - Code.PhotoSwipe.CaptionToolbarClass.EventTypes = { - onShow: 'PhotoSwipeCaptionToolbarClassOnShow', - onHide: 'PhotoSwipeCaptionToolbarClassOnHide' - }; - -}) -( - window, - Code.PhotoSwipe.Util, - Code.PhotoSwipe.CaptionClass, - Code.PhotoSwipe.ToolbarClass -); diff --git a/src/change.log b/src/change.log deleted file mode 100644 index 7eea682c7..000000000 --- a/src/change.log +++ /dev/null @@ -1,220 +0,0 @@ -1.0.0 07.04.11 - Ste Brennan ----------------------------- -Initial release - - -1.0.1 11.04.11 - Ste Brennan ----------------------------- -Major update: - -- Fading of caption and toolbar more like iOS photo view by default. - -- Individual settings of toolbar and caption consolidated into "captionAndToolbarHide, captionAndToolbarHideOnSwipe, captionAndToolbarFlipPosition, captionAndToolbarAutoHideDelay, captionAndToolbarOpacity, captionAndToolbarShowEmptyCaptions". This was done to simplify logic and reduce a timeout. Previous caption and toolbar settings are not longer valid. - -- Fixed "zoom" for imageScaleMethod. - -- Fixed issue where loop was set to false and slideshow was active. - -- Fixed issue with placement of caption if at the bottom - - - -1.0.2 14.04.11 - Ste Brennan ----------------------------- - -- PhotoSwipe now dispatches the following events which you can listen out for in your code (see examples/events.html) - * onShow: When the gallery is displayed - * onHide: When the gallery is hidden - * onShowNext: When the gallery has been issued the command to show the next image - * onShowPrevious: When the gallery has been issued the command to show the previous image - * onDisplayImage: When the gallery displays an image. Typically fired after onShowNext and onShowPrevious - * onResetPosition: When the gallery resets the size and position of itself. Typically fired after device orientation change or window resize - * onSlideshowStart: When the gallery has started the slideshow - * onSlideshowStop: When the gallery has stopped the slideshow - -- Added "exclusive mode". This means the user will only be able to interact with PhotoSwipe, and not the underlying document. They will be unable to close PhotoSwipe once it is active. (see examples/exclusive-mode.html) - -- Fixed Issue #1 - Line break in thumbnail anchor can cause a JS error - - - -1.0.3 18.04.11 - Ste Brennan ----------------------------- - -- Fixed issue with orientation change not triggering on Android - -- Added new zIndex setting. Lets you specify the starting zIndex for PhotoSwipe - -- Reduced the number of times the internal function "resetPosition" was being fired - -- Fixed issue with show and hide of toolbar / caption. Has occasionally locking up - -- Now compliled with Google Closure. Overall smaller file size - - - -1.0.4 20.04.11 - Ste Brennan ----------------------------- - -- Experimental "zoom/pan/rotate" for iOS devices - -- Fixed issue2. Can now click on "clickable" elements added to a caption on touch screen devices - -- Speed improvements for Android and Blackberry devices - -- "Flicker" when using toolbar buttons to show next and previous on Android devices fixed - - - -1.0.5 28.04.11 - Ste Brennan ----------------------------- - -- Fixed lack of hardware acceleration when running via UIWebView or running as a full screen web app in iOS devices - -- Fixed device orientation issue with Android - -- Added custom "meta data" that can be attached to each full size image - -- Now runs with jquery.animate-enhanced [https://github.com/benbarnett/jQuery-Animate-Enhanced]. This addes hardware acceleration if using the jQuery DOM engine and jQuery animate functions - -- Fixed issues with touch events and the jQuery engine. These issues where introduced in v1.0.4. - -- Added the following new events: - - - onBeforeShow - - onBeforeHide - - onBeforeCaptionAndToolbarShow - - onBeforeCaptionAndToolbarHide - - -1.0.6 04.05.11 - Ste Brennan ----------------------------- - -- Fixed issue with toolbar on Android 2.1-update1 - -- Toolbar buttons now more responsive (uses touchstart event rather than click, Android and iOS only) - -- Added new event "onViewportClick" - -- Added new setting "backButtonHideEnabled" (default true). This will hide the gallery when the user hits the back button. Useful for Android and Blackberry. Works in BB6, Android v2.1 and above and iOS 4 and above - - -1.0.7 16.05.11 - Ste Brennan ----------------------------- - -- Update util-dom-jQuery.js. Wrong window dimensions returned. - -- Added new "isActive" flag. You can check the active status of PhotoSwipe by "Code.PhotoSwipe.Current.isActive" - -- Added jQuery Mobile example. There is still an issue with this however. You have to set "backButtonHideEnabled = false" as it interferes with jQuery Mobile's history handling. This needs reviewing. - -- Better "Exclusive Mode" example. - -- Fixed issue where the toolbar was causing an error on zoom and rotate in iOS. - - -1.0.8 19.05.11 - Ste Brennan ----------------------------- - -- Tighter integration with jQuery Mobile. Back button now working fine. - -- Updated jQuery Mobile example. - -- Updated example images in-line with new branding. - -- Updated toolbar icons and added hi-res icons for retina display. - - -1.0.10 30.05.11 - Ste Brennan ------------------------------ - -- Now works with jQuery 1.6.1 - - -1.0.11 09.06.11 - Ste Brennan ------------------------------ - -- Panning speed with zoomed images now runs at correct speed thanks to heardfrom [https://github.com/heardfrom] and cilogi[https://github.com/cilogi] - -- Added maximum and minimum user zoom settings - -- Should now play nicely if including MooTools thanks to chameron [https://github.com/chameron] - - -1.0.12 09.06.11 - Ste Brennan ------------------------------ - -- Fixed issues with Chrome 12 - -- Added the following new events "onCaptionEndToolbarShow" and "onCaptionEndToolbarHide" - -- Fixed issue with position of caption when placed at the bottom - -- Events now pass target value (should always equal the current instance of PhotoSwipe) - -- Added new "using-meta-data.html" example - -- Updated to jQuery Animate Enhanced v0.75 - - -1.0.13 09.06.11 - Ste Brennan ------------------------------ - -- Upgraded to jQuery Mobile 1.0 beta - -- Added new "double tap" feature. Double tapping an image will zoom the image in and allow the user to pan around. This is still experimental and works on iOS (pinch and zoom still works), Android, BlackBerry, Chrome and Firefox 4 and above - - -1.0.14 24.06.11 - Ste Brennan ------------------------------ - -- "Double tap" to zoom and pan around an image now working in IE9 - -- Major rewrite of how events are handled internally. - - -1.0.15 02.07.11 - Ste Brennan ------------------------------ - -- Fixed issues with new event handler. Keyboard control should work again in the non-jQuery version - -- Added change to a resuse issue reported with jQuery Mobile - - -1.0.16 05.07.11 - Ste Brennan ------------------------------ - -- Added new option to the imageScaleMethod setting "fitNoUpscale". This will ensure the image fits into the viewport but it won't upscale the image - -- Added new example "jquery-mobile-ajax.html" - - -1.0.17 05.07.11 - Ste Brennan ------------------------------ - -- Fixed issues with "events.html" example - - -1.0.18 08.07.11 - Ste Brennan ------------------------------ - -- Now sized correctly if your HTML body has padding on it - -- Fixed issued with jQuery and listening to PhotoSwipe events - was throwing up a "too much recursion" error - -- Have had to change the way you listen to events. Use "Code.PhotoSwipe.Current.addEventHandler" not Code.PhotoSwipe.Current.addEventListener. This is related to the above fix - -- Upgraded to jQuery 1.6.2 - -- Upgraded to jQuery Animate Enhanced v0.76 - - -1.0.19 14.07.11 - Ste Brennan ------------------------------ -- Fixed issue with Util.DOM.removeClass - -- Typo in events.html corrected - -- Added hi-res css dedection like how jQuery Mobile does it - - diff --git a/src/code.photoswipe/cache.class.js b/src/code.photoswipe/cache.class.js new file mode 100644 index 000000000..04498e370 --- /dev/null +++ b/src/code.photoswipe/cache.class.js @@ -0,0 +1,115 @@ +// Copyright (c) %%year%% by Code Computerlove (http://www.codecomputerlove.com) +// Licensed under the MIT license +// version: %%version%% + +(function(window, klass, Util, Image){ + + + Util.registerNamespace('Code.PhotoSwipe.Cache'); + var PhotoSwipe = window.Code.PhotoSwipe; + + + + PhotoSwipe.Cache.CacheClass = klass({ + + + + images: null, + settings: null, + + + + /* + * Function: dispose + */ + dispose: function(){ + + var prop, i; + + if (!Util.isNothing(this.images)){ + for (i=0; i 0){ + Util.DOM.setStyle(itemEl, { + marginRight: this.settings.margin + 'px' + }); + } + + Util.DOM.appendChild(itemEl, this.contentEl); + + } + + + Util.DOM.appendToBody(this.el); + + }, + + + + + /* + * Function: resetPosition + */ + resetPosition: function(){ + + var + width = Util.DOM.windowWidth(), + height = Util.DOM.windowHeight(), + itemWidth = (this.settings.margin > 0) ? width + this.settings.margin : width, + itemEls = Util.DOM.find('.' + PhotoSwipe.Carousel.CssClasses.item, this.contentEl), + contentWidth = itemWidth * itemEls.length, + i, + itemEl, imageEl; + + + // Set the height and width to fill the document + Util.DOM.setStyle(this.el, { + top: Util.DOM.windowScrollTop() + 'px', + width: width, + height: height + }); + + + // Set the height and width of the content el + Util.DOM.setStyle(this.contentEl, { + width: contentWidth, + height: height + }); + + + // Set the height and width of item elements + for (i=0; i maxWidth){ + scale = maxWidth / newWidth; + newWidth = Math.round(newWidth * scale); + newHeight = Math.round(newHeight * scale); + } + + if (newHeight > maxHeight){ + scale = maxHeight / newHeight; + newHeight = Math.round(newHeight * scale); + newWidth = Math.round(newWidth * scale); + } + + } + else{ + + if (imageEl.isLandscape) { + // Ensure the width fits the screen + scale = maxWidth / imageEl.naturalWidth; + } + else { + // Ensure the height fits the screen + scale = maxHeight / imageEl.naturalHeight; + } + + newWidth = Math.round(imageEl.naturalWidth * scale); + newHeight = Math.round(imageEl.naturalHeight * scale); + + if (this.settings.imageScaleMethod === 'zoom'){ + + scale = 1; + if (newHeight < maxHeight){ + scale = maxHeight /newHeight; + } + else if (newWidth < maxWidth){ + scale = maxWidth /newWidth; + } + + if (scale !== 1) { + newWidth = Math.round(newWidth * scale); + newHeight = Math.round(newHeight * scale); + } + + } + else if (this.settings.imageScaleMethod === 'fit') { + // Rescale again to ensure full image fits into the viewport + scale = 1; + if (newWidth > maxWidth) { + scale = maxWidth / newWidth; + } + else if (newHeight > maxHeight) { + scale = maxHeight / newHeight; + } + if (scale !== 1) { + newWidth = Math.round(newWidth * scale); + newHeight = Math.round(newHeight * scale); + } + } + + } + + newTop = Math.round( ((maxHeight - newHeight) / 2) ) + 'px'; + newLeft = Math.round( ((maxWidth - newWidth) / 2) ) + 'px'; + + Util.DOM.setStyle(imageEl, { + position: 'absolute', + width: newWidth, + height: newHeight, + top: newTop, + left: newLeft, + display: 'block' + }); + + }, + + + + /* + * Function: setContentLeftPosition + */ + setContentLeftPosition: function(){ + + var + width = Util.DOM.windowWidth(), + itemEls = this.getItemEls(), + left = 0; + + if (this.settings.loop){ + left = (width + this.settings.margin) * -1; + } + else{ + + if (this.currentCacheIndex === this.cache.images.length-1){ + left = ((itemEls.length-1) * (width + this.settings.margin)) * -1; + } + else if (this.currentCacheIndex > 0){ + left = (width + this.settings.margin) * -1; + } + + } + + Util.DOM.setStyle(this.contentEl, { + left: left + 'px' + }); + + }, + + + + /* + * Function: + */ + show: function(index){ + + this.currentCacheIndex = index; + this.resetPosition(); + this.setImages(false); + Util.DOM.show(this.el); + + Util.Animation.resetTranslate(this.contentEl); + var + itemEls = this.getItemEls(), + i; + for (i=0; i this.cache.images.length-1){ + nextCacheIndex = 0; + } + if (previousCacheIndex < 0){ + previousCacheIndex = this.cache.images.length-1; + } + + cacheImages = this.cache.getImages([ + previousCacheIndex, + this.currentCacheIndex, + nextCacheIndex + ]); + + if (!ignoreCurrent){ + // Current + this.addCacheImageToItemEl(cacheImages[1], itemEls[1]); + } + // Next + this.addCacheImageToItemEl(cacheImages[2], itemEls[2]); + // Previous + this.addCacheImageToItemEl(cacheImages[0], itemEls[0]); + + } + else{ + + if (itemEls.length === 1){ + if (!ignoreCurrent){ + // Current + cacheImages = this.cache.getImages([ + this.currentCacheIndex + ]); + this.addCacheImageToItemEl(cacheImages[0], itemEls[0]); + } + } + else if (itemEls.length === 2){ + + if (this.currentCacheIndex === 0){ + cacheImages = this.cache.getImages([ + this.currentCacheIndex, + this.currentCacheIndex + 1 + ]); + if (!ignoreCurrent){ + this.addCacheImageToItemEl(cacheImages[0], itemEls[0]); + } + this.addCacheImageToItemEl(cacheImages[1], itemEls[1]); + } + else{ + cacheImages = this.cache.getImages([ + this.currentCacheIndex - 1, + this.currentCacheIndex + ]); + if (!ignoreCurrent){ + this.addCacheImageToItemEl(cacheImages[1], itemEls[1]); + } + this.addCacheImageToItemEl(cacheImages[0], itemEls[0]); + } + + } + else{ + + if (this.currentCacheIndex === 0){ + cacheImages = this.cache.getImages([ + this.currentCacheIndex, + this.currentCacheIndex + 1, + this.currentCacheIndex + 2 + ]); + if (!ignoreCurrent){ + this.addCacheImageToItemEl(cacheImages[0], itemEls[0]); + } + this.addCacheImageToItemEl(cacheImages[1], itemEls[1]); + this.addCacheImageToItemEl(cacheImages[2], itemEls[2]); + } + else if (this.currentCacheIndex === this.cache.images.length-1){ + cacheImages = this.cache.getImages([ + this.currentCacheIndex - 2, + this.currentCacheIndex - 1, + this.currentCacheIndex + ]); + if (!ignoreCurrent){ + // Current + this.addCacheImageToItemEl(cacheImages[2], itemEls[2]); + } + this.addCacheImageToItemEl(cacheImages[1], itemEls[1]); + this.addCacheImageToItemEl(cacheImages[0], itemEls[0]); + } + else{ + cacheImages = this.cache.getImages([ + this.currentCacheIndex - 1, + this.currentCacheIndex, + this.currentCacheIndex + 1 + ]); + + if (!ignoreCurrent){ + // Current + this.addCacheImageToItemEl(cacheImages[1], itemEls[1]); + } + // Next + this.addCacheImageToItemEl(cacheImages[2], itemEls[2]); + // Previous + this.addCacheImageToItemEl(cacheImages[0], itemEls[0]); + } + + } + + } + + }, + + + + /* + * Function: addCacheImageToItemEl + */ + addCacheImageToItemEl: function(cacheImage, itemEl){ + + Util.DOM.addClass(itemEl, PhotoSwipe.Carousel.CssClasses.itemLoading); + + Util.DOM.removeChildren(itemEl); + + Util.DOM.setStyle(cacheImage.imageEl, { + display: 'none' + }); + Util.DOM.appendChild(cacheImage.imageEl, itemEl); + + Util.Animation.resetTranslate(cacheImage.imageEl); + + Util.Events.add(cacheImage, PhotoSwipe.Image.EventTypes.onLoad, this.imageLoadHandler); + + cacheImage.load(); + + }, + + + + /* + * Function: slideCarousel + */ + slideCarousel: function(point, action, speed){ + + if (this.isSliding){ + return; + } + + var + width = Util.DOM.windowWidth() + this.settings.margin, + diffX, + slideBy; + + speed = Util.coalesce(speed, this.settings.slideSpeed); + + if (window.Math.abs(diffX) < 1){ + return; + } + + + switch (action){ + + case PhotoSwipe.TouchElement.ActionTypes.swipeLeft: + + slideBy = width * -1; + break; + + case PhotoSwipe.TouchElement.ActionTypes.swipeRight: + + slideBy = width; + break; + + default: + + diffX = point.x - this.touchStartPoint.x; + + if (window.Math.abs(diffX) > width / 2){ + slideBy = (diffX > 0) ? width : width * -1; + } + else{ + slideBy = 0; + } + break; + + } + + if (slideBy < 0){ + this.lastSlideByAction = PhotoSwipe.Carousel.SlideByAction.next; + } + else if (slideBy > 0){ + this.lastSlideByAction = PhotoSwipe.Carousel.SlideByAction.previous; + } + else{ + this.lastSlideByAction = PhotoSwipe.Carousel.SlideByAction.current; + } + + // Check for non-looping carousels + // If we are at the start or end, spring back to the current item element + if (!this.settings.loop){ + if ( (this.lastSlideByAction === PhotoSwipe.Carousel.SlideByAction.previous && this.currentCacheIndex === 0 ) || (this.lastSlideByAction === PhotoSwipe.Carousel.SlideByAction.next && this.currentCacheIndex === this.cache.images.length-1) ){ + slideBy = 0; + this.lastSlideByAction = PhotoSwipe.Carousel.SlideByAction.current; + } + } + + this.isSliding = true; + this.doSlideCarousel(slideBy, speed); + + }, + + + + /* + * Function: + */ + moveCarousel: function(point){ + + if (this.isSliding){ + return; + } + + if (!this.settings.enableDrag){ + return; + } + + this.doMoveCarousel(point.x - this.touchStartPoint.x); + + }, + + + + /* + * Function: getItemEls + */ + getItemEls: function(){ + + return Util.DOM.find('.' + PhotoSwipe.Carousel.CssClasses.item, this.contentEl); + + }, + + + + /* + * Function: previous + */ + previous: function(){ + + this.stopSlideshow(); + this.slideCarousel({x:0, y:0}, PhotoSwipe.TouchElement.ActionTypes.swipeRight, this.settings.nextPreviousSlideSpeed); + + }, + + + + /* + * Function: next + */ + next: function(){ + + this.stopSlideshow(); + this.slideCarousel({x:0, y:0}, PhotoSwipe.TouchElement.ActionTypes.swipeLeft, this.settings.nextPreviousSlideSpeed); + + }, + + + + /* + * Function: slideshowNext + */ + slideshowNext: function(){ + + this.slideCarousel({x:0, y:0}, PhotoSwipe.TouchElement.ActionTypes.swipeLeft); + + }, + + + + + /* + * Function: startSlideshow + */ + startSlideshow: function(){ + + this.stopSlideshow(); + + this.isSlideshowActive = true; + + this.slideshowTimeout = window.setTimeout(this.slideshowNext.bind(this), this.settings.slideshowDelay); + + Util.Events.fire(this, { + type: PhotoSwipe.Carousel.EventTypes.onSlideshowStart, + target: this + }); + + }, + + + + /* + * Function: stopSlideshow + */ + stopSlideshow: function(){ + + if (!Util.isNothing(this.slideshowTimeout)){ + + window.clearTimeout(this.slideshowTimeout); + this.slideshowTimeout = null; + this.isSlideshowActive = false; + + Util.Events.fire(this, { + type: PhotoSwipe.Carousel.EventTypes.onSlideshowStop, + target: this + }); + + } + + }, + + + + /* + * Function: onSlideByEnd + */ + onSlideByEnd: function(e){ + + if (Util.isNothing(this.isSliding)){ + return; + } + + var itemEls = this.getItemEls(); + + this.isSliding = false; + + if (this.lastSlideByAction === PhotoSwipe.Carousel.SlideByAction.next){ + this.currentCacheIndex = this.currentCacheIndex + 1; + } + else if (this.lastSlideByAction === PhotoSwipe.Carousel.SlideByAction.previous){ + this.currentCacheIndex = this.currentCacheIndex - 1; + } + + if (this.settings.loop){ + + if (this.lastSlideByAction === PhotoSwipe.Carousel.SlideByAction.next){ + // Move first to the last + Util.DOM.appendChild(itemEls[0], this.contentEl); + } + else if (this.lastSlideByAction === PhotoSwipe.Carousel.SlideByAction.previous){ + // Move the last to the first + Util.DOM.insertBefore(itemEls[itemEls.length-1], itemEls[0], this.contentEl); + } + + if (this.currentCacheIndex < 0){ + this.currentCacheIndex = this.cache.images.length - 1; + } + else if (this.currentCacheIndex === this.cache.images.length){ + this.currentCacheIndex = 0; + } + + } + else{ + + if (this.cache.images.length > 3){ + + if (this.currentCacheIndex > 1 && this.currentCacheIndex < this.cache.images.length-2){ + if (this.lastSlideByAction === PhotoSwipe.Carousel.SlideByAction.next){ + // Move first to the last + Util.DOM.appendChild(itemEls[0], this.contentEl); + } + else if (this.lastSlideByAction === PhotoSwipe.Carousel.SlideByAction.previous){ + // Move the last to the first + Util.DOM.insertBefore(itemEls[itemEls.length-1], itemEls[0], this.contentEl); + } + } + else if (this.currentCacheIndex === 1){ + if (this.lastSlideByAction === PhotoSwipe.Carousel.SlideByAction.previous){ + // Move the last to the first + Util.DOM.insertBefore(itemEls[itemEls.length-1], itemEls[0], this.contentEl); + } + } + else if (this.currentCacheIndex === this.cache.images.length-2){ + if (this.lastSlideByAction === PhotoSwipe.Carousel.SlideByAction.next){ + // Move first to the last + Util.DOM.appendChild(itemEls[0], this.contentEl); + } + } + + } + + + } + + if (this.lastSlideByAction !== PhotoSwipe.Carousel.SlideByAction.current){ + this.setContentLeftPosition(); + this.setImages(true); + } + + + Util.Events.fire(this, { + type: PhotoSwipe.Carousel.EventTypes.onSlideByEnd, + target: this, + action: this.lastSlideByAction, + cacheIndex: this.currentCacheIndex + }); + + + if (this.isSlideshowActive){ + + if (this.lastSlideByAction !== PhotoSwipe.Carousel.SlideByAction.current){ + this.startSlideshow(); + } + else{ + this.stopSlideshow(); + } + + } + + + }, + + + + /* + * Function: onTouch + */ + onTouch: function(action, point){ + + this.stopSlideshow(); + + switch(action){ + + case PhotoSwipe.TouchElement.ActionTypes.touchStart: + this.touchStartPoint = point; + this.touchStartPosition = { + x: window.parseInt(Util.DOM.getStyle(this.contentEl, 'left'), 0), + y: window.parseInt(Util.DOM.getStyle(this.contentEl, 'top'), 0) + }; + break; + + case PhotoSwipe.TouchElement.ActionTypes.touchMove: + this.moveCarousel(point); + break; + + case PhotoSwipe.TouchElement.ActionTypes.touchEnd: + case PhotoSwipe.TouchElement.ActionTypes.swipeLeft: + case PhotoSwipe.TouchElement.ActionTypes.swipeRight: + this.slideCarousel(point, action); + break; + + case PhotoSwipe.TouchElement.ActionTypes.tap: + break; + + case PhotoSwipe.TouchElement.ActionTypes.doubleTap: + break; + + + } + + }, + + + + /* + * Function: onImageLoad + */ + onImageLoad: function(e){ + + var cacheImage = e.target; + + if (!Util.isNothing(cacheImage.imageEl.parentNode)){ + Util.DOM.removeClass(cacheImage.imageEl.parentNode, PhotoSwipe.Carousel.CssClasses.itemLoading); + Util.Events.remove(cacheImage, PhotoSwipe.Image.EventTypes.onLoad, this.imageLoadHandler); + this.resetImagePosition(cacheImage.imageEl); + } + + } + + + + }); + + + +} +( + window, + window.klass, + window.Code.Util, + window.Code.PhotoSwipe.TouchElement +)); \ No newline at end of file diff --git a/src/code.photoswipe/carousel.js b/src/code.photoswipe/carousel.js new file mode 100644 index 000000000..7713d2fbb --- /dev/null +++ b/src/code.photoswipe/carousel.js @@ -0,0 +1,44 @@ +// Copyright (c) %%year%% by Code Computerlove (http://www.codecomputerlove.com) +// Licensed under the MIT license +// version: %%version%% + +(function(window, klass, Util){ + + + Util.registerNamespace('Code.PhotoSwipe.Carousel'); + var PhotoSwipe = window.Code.PhotoSwipe; + + + + PhotoSwipe.Carousel.EventTypes = { + + onSlideByEnd: 'PhotoSwipeCarouselOnSlideByEnd', + onSlideshowStart: 'PhotoSwipeCarouselOnSlideshowStart', + onSlideshowStop: 'PhotoSwipeCarouselOnSlideshowStop' + + }; + + + + PhotoSwipe.Carousel.CssClasses = { + carousel: 'ps-carousel', + content: 'ps-carousel-content', + item: 'ps-carousel-item', + itemLoading: 'ps-carousel-item-loading' + }; + + + + PhotoSwipe.Carousel.SlideByAction = { + previous: 'previous', + current: 'current', + next: 'next' + }; + + +} +( + window, + window.klass, + window.Code.Util +)); \ No newline at end of file diff --git a/src/code.photoswipe/documentoverlay.class.js b/src/code.photoswipe/documentoverlay.class.js new file mode 100644 index 000000000..52486344b --- /dev/null +++ b/src/code.photoswipe/documentoverlay.class.js @@ -0,0 +1,131 @@ +// Copyright (c) %%year%% by Code Computerlove (http://www.codecomputerlove.com) +// Licensed under the MIT license +// version: %%version%% + +(function(window, klass, Util){ + + + Util.registerNamespace('Code.PhotoSwipe.DocumentOverlay'); + var PhotoSwipe = window.Code.PhotoSwipe; + + + + PhotoSwipe.DocumentOverlay.DocumentOverlayClass = klass({ + + + + el: null, + settings: null, + initialBodyHeight: null, + + + + /* + * Function: dispose + */ + dispose: function(){ + + var prop; + + Util.Animation.stop(this.el); + Util.DOM.removeChild(this.el, this.el.parentNode); + + for (prop in this) { + if (Util.objectHasProperty(this, prop)) { + this[prop] = null; + } + } + + }, + + + + /* + * Function: initialize + */ + initialize: function(options){ + + this.settings = options; + + this.el = Util.DOM.createElement( + 'div', + { + 'class': PhotoSwipe.DocumentOverlay.CssClasses.documentOverlay + }, + '' + ); + Util.DOM.setStyle(this.el, { + display: 'block', + position: 'absolute', + left: 0, + top: 0, + zIndex: this.settings.zIndex + }); + + Util.DOM.hide(this.el); + Util.DOM.appendToBody(this.el); + + Util.Animation.resetTranslate(this.el); + + // Store this value incase the body dimensions change to zero! + // I've seen it happen! :D + this.initialBodyHeight = Util.DOM.bodyOuterHeight(); + + + }, + + + + /* + * Function: resetPosition + */ + resetPosition: function(){ + + var + width = Util.DOM.windowWidth(), + height = Util.DOM.bodyOuterHeight() * 2; // This covers extra height added by photoswipe + + if (height < 1){ + height = this.initialBodyHeight; + } + + + if (Util.DOM.windowHeight() > height){ + height = Util.DOM.windowHeight(); + } + + Util.DOM.setStyle(this.el, { + width: width, + height: height, + top: (this.settings.jQueryMobile) ? Util.DOM.windowScrollTop() + 'px' : '0px' + }); + + }, + + + + /* + * Function: fadeIn + */ + fadeIn: function(speed, callback){ + + this.resetPosition(); + + Util.DOM.setStyle(this.el, 'opacity', 0); + Util.DOM.show(this.el); + + Util.Animation.fadeIn(this.el, speed, callback); + + } + + + }); + + + +} +( + window, + window.klass, + window.Code.Util +)); \ No newline at end of file diff --git a/src/code.photoswipe/documentoverlay.js b/src/code.photoswipe/documentoverlay.js new file mode 100644 index 000000000..19bb58cd1 --- /dev/null +++ b/src/code.photoswipe/documentoverlay.js @@ -0,0 +1,24 @@ +// Copyright (c) %%year%% by Code Computerlove (http://www.codecomputerlove.com) +// Licensed under the MIT license +// version: %%version%% + +(function(window, klass, Util){ + + + Util.registerNamespace('Code.PhotoSwipe.DocumentOverlay'); + var PhotoSwipe = window.Code.PhotoSwipe; + + + + PhotoSwipe.DocumentOverlay.CssClasses = { + documentOverlay: 'ps-document-overlay' + }; + + + +} +( + window, + window.klass, + window.Code.Util +)); \ No newline at end of file diff --git a/src/code.photoswipe/image.class.js b/src/code.photoswipe/image.class.js new file mode 100644 index 000000000..14e5fedc9 --- /dev/null +++ b/src/code.photoswipe/image.class.js @@ -0,0 +1,141 @@ +// Copyright (c) %%year%% by Code Computerlove (http://www.codecomputerlove.com) +// Licensed under the MIT license +// version: %%version%% + +(function(window, klass, Util){ + + + Util.registerNamespace('Code.PhotoSwipe.Image'); + var PhotoSwipe = window.Code.PhotoSwipe; + + + + PhotoSwipe.Image.ImageClass = klass({ + + + + refObj: null, + imageEl: null, + src: null, + caption: null, + metaData: null, + naturalWidth: null, + naturalHeight: null, + isLandscape: null, + isLoading: null, + imageLoadHandler: null, + + + + /* + * Function: dispose + */ + dispose: function(){ + + var prop, i; + + this.shrinkImage(); + + for (prop in this) { + if (Util.objectHasProperty(this, prop)) { + this[prop] = null; + } + } + + }, + + + + /* + * Function: initialize + */ + initialize: function(refObj, src, caption, metaData){ + + this.refObj = refObj; + this.src = src; + this.caption = caption; + this.metaData = metaData; + this.naturalWidth = 0; + this.naturalHeight = 0; + this.isLandscape = false; + this.isLoading = false; + + this.imageEl = new window.Image(); + + this.imageLoadHandler = this.onImageLoad.bind(this); + + }, + + + + /* + * Function: load + */ + load: function(){ + + if (this.imageEl.src === this.src){ + Util.Events.fire(this, { + type: PhotoSwipe.Image.EventTypes.onLoad, + target: this + }); + return; + } + + this.imageEl.isLoading = true; + this.imageEl.onload = this.imageLoadHandler; + this.imageEl.src = this.src; + + }, + + + + /* + * Function: shrinkImage + */ + shrinkImage: function(){ + + if (Util.isNothing(this.imageEl)){ + return; + } + + if (this.imageEl.src === this.src){ + this.imageEl.src = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs='; + if (!Util.isNothing(this.imageEl.parentNode)){ + Util.DOM.removeChild(this.imageEl, this.imageEl.parentNode); + } + } + + }, + + + + /* + * Function: onImageLoad + */ + onImageLoad: function(e){ + + this.imageEl.onload = null; + this.imageEl.naturalWidth = Util.coalesce(this.imageEl.naturalWidth, this.imageEl.width); + this.imageEl.naturalHeight = Util.coalesce(this.imageEl.naturalHeight, this.imageEl.height); + this.imageEl.isLandscape = (this.imageEl.naturalWidth > this.imageEl.naturalHeight); + this.imageEl.isLoading = false; + + Util.Events.fire(this, { + type: PhotoSwipe.Image.EventTypes.onLoad, + target: this + }); + + } + + + + }); + + + +} +( + window, + window.klass, + window.Code.Util +)); \ No newline at end of file diff --git a/src/code.photoswipe/image.js b/src/code.photoswipe/image.js new file mode 100644 index 000000000..e54a9e758 --- /dev/null +++ b/src/code.photoswipe/image.js @@ -0,0 +1,26 @@ +// Copyright (c) %%year%% by Code Computerlove (http://www.codecomputerlove.com) +// Licensed under the MIT license +// version: %%version%% + +(function(window, klass, Util){ + + + Util.registerNamespace('Code.PhotoSwipe.Image'); + var PhotoSwipe = window.Code.PhotoSwipe; + + + + PhotoSwipe.Image.EventTypes = { + + onLoad: 'onLoad' + + }; + + + +} +( + window, + window.klass, + window.Code.Util +)); \ No newline at end of file diff --git a/src/code.photoswipe/photoswipe.class.js b/src/code.photoswipe/photoswipe.class.js new file mode 100644 index 000000000..a9dfc8d28 --- /dev/null +++ b/src/code.photoswipe/photoswipe.class.js @@ -0,0 +1,1062 @@ +// Copyright (c) %%year%% by Code Computerlove (http://www.codecomputerlove.com) +// Licensed under the MIT license +// version: %%version%% + +(function(window, klass, Util, Cache, DocumentOverlay, Carousel, Toolbar, UILayer, ZoomPanRotate){ + + + Util.registerNamespace('Code.PhotoSwipe'); + var PhotoSwipe = window.Code.PhotoSwipe; + + + PhotoSwipe.PhotoSwipeClass = klass({ + + + + settings: null, + isBackEventSupported: null, + backButtonClicked: null, + currentIndex: null, + originalImages: null, + mouseWheelStartTime: null, + + + + // Components + cache: null, + documentOverlay: null, + carousel: null, + uiLayer: null, + toolbar: null, + zoomPanRotate: null, + + + + // Handlers + windowOrientationChangeHandler: null, + windowScrollHandler: null, + windowHashChangeHandler: null, + keyDownHandler: null, + windowOrientationEventName: null, + uiLayerTouchHandler: null, + carouselSlideByEndHandler: null, + carouselSlideshowStartHandler: null, + carouselSlideshowStopHandler: null, + toolbarClickHandler: null, + toolbarBeforeShowHandler: null, + toolbarShowHandler: null, + toolbarBeforeHideHandler: null, + toolbarHideHandler: null, + mouseWheelHandler: null, + + + + /* + * Function: dispose + */ + dispose: function(){ + + var prop; + + Util.Events.remove(this, PhotoSwipe.EventTypes.onBeforeShow); + Util.Events.remove(this, PhotoSwipe.EventTypes.onShow); + Util.Events.remove(this, PhotoSwipe.EventTypes.onBeforeHide); + Util.Events.remove(this, PhotoSwipe.EventTypes.onHide); + Util.Events.remove(this, PhotoSwipe.EventTypes.onDisplayImage); + Util.Events.remove(this, PhotoSwipe.EventTypes.onResetPosition); + Util.Events.remove(this, PhotoSwipe.EventTypes.onSlideshowStart); + Util.Events.remove(this, PhotoSwipe.EventTypes.onSlideshowStop); + Util.Events.remove(this, PhotoSwipe.EventTypes.onTouch); + Util.Events.remove(this, PhotoSwipe.EventTypes.onBeforeCaptionAndToolbarShow); + Util.Events.remove(this, PhotoSwipe.EventTypes.onCaptionAndToolbarShow); + Util.Events.remove(this, PhotoSwipe.EventTypes.onBeforeCaptionAndToolbarHide); + Util.Events.remove(this, PhotoSwipe.EventTypes.onCaptionAndToolbarHide); + + this.removeEventHandlers(); + + if (!Util.isNothing(this.documentOverlay)){ + this.documentOverlay.dispose(); + } + + if (!Util.isNothing(this.carousel)){ + this.carousel.dispose(); + } + + if (!Util.isNothing(this.uiLayer)){ + this.uiLayer.dispose(); + } + + if (!Util.isNothing(this.toolbar)){ + this.toolbar.dispose(); + } + + this.destroyZoomPanRotate(); + + if (!Util.isNothing(this.cache)){ + this.cache.dispose(); + } + + for (prop in this) { + if (Util.objectHasProperty(this, prop)) { + this[prop] = null; + } + } + + }, + + + + /* + * Function: initialize + */ + initialize: function(images, options){ + + this.originalImages = images; + + if (Util.Browser.isAndroid){ + if (window.navigator.userAgent.indexOf('2.1') > -1){ + this.isBackEventSupported = true; + } + } + + if (!this.isBackEventSupported){ + this.isBackEventSupported = Util.objectHasProperty(window, 'onhashchange'); + } + + + this.settings = { + + // General + fadeInSpeed: 250, + fadeOutSpeed: 250, + preventHide: false, + preventSlideshow: false, + zIndex: 1000, + backButtonHideEnabled: true, + enableKeyboard: true, + enableMouseWheel: true, + mouseWheelSpeed: 350, + autoStartSlideshow: false, + jQueryMobile: ( !Util.isNothing(window.jQuery) && !Util.isNothing(window.jQuery.mobile) ), + jQueryMobileDialogHash: '&ui-state=dialog', + + + // Carousel + loop: true, + slideSpeed: 250, + nextPreviousSlideSpeed: 0, + enableDrag: true, + swipeThreshold: 50, + swipeTimeThreshold: 250, + slideTimingFunction: 'ease-out', + slideshowDelay: 3000, + doubleTapSpeed: 250, + margin: 20, + imageScaleMethod: 'fit', // Either "fit", "fitNoUpscale" or "zoom", + + // Toolbar + captionAndToolbarHide: false, + captionAndToolbarFlipPosition: false, + captionAndToolbarAutoHideDelay: 5000, + captionAndToolbarOpacity: 0.8, + captionAndToolbarShowEmptyCaptions: true, + getToolbar: PhotoSwipe.Toolbar.getToolbar, + + + // ZoomPanRotate + allowUserZoom: true, + allowRotationOnUserZoom: false, + maxUserZoom: 5.0, + minUserZoom: 0.5, + doubleTapZoomLevel: 2.5, + + + // Cache + getImageSource: PhotoSwipe.Cache.Functions.getImageSource, + getImageCaption: PhotoSwipe.Cache.Functions.getImageCaption, + getImageMetaData: PhotoSwipe.Cache.Functions.getImageMetaData, + cacheMode: PhotoSwipe.Cache.Mode.normal + + }; + + Util.extend(this.settings, options); + + if (this.settings.preventHide){ + this.settings.backButtonHideEnabled = false; + } + + this.cache = new Cache.CacheClass(images, this.settings); + + }, + + + + /* + * Function: show + */ + show: function(obj){ + + var i; + + // Work out what the starting index is + if (Util.isNumber(obj)){ + this.currentIndex = obj; + } + else{ + + this.currentIndex = -1; + for (i=0; i this.originalImages.length-1){ + throw "Code.PhotoSwipe.PhotoSwipeClass.show: Starting index out of range"; + } + + + // Set this instance to be the active instance + PhotoSwipe.setActivateInstance(this); + + // Create components + Util.DOM.addClass(window.document.body, PhotoSwipe.CssClasses.buildingBody); + this.createComponents(); + + + Util.Events.fire(this, { + type: PhotoSwipe.EventTypes.onBeforeShow, + target: this + }); + + + // Fade in the document overlay + this.documentOverlay.fadeIn(this.settings.fadeInSpeed, this.onDocumentOverlayFadeIn.bind(this)); + + }, + + + + /* + * Function: createComponents + */ + createComponents: function(){ + + this.documentOverlay = new DocumentOverlay.DocumentOverlayClass(this.settings); + this.carousel = new Carousel.CarouselClass(this.cache, this.settings); + this.uiLayer = new UILayer.UILayerClass(this.settings); + if (!this.settings.captionAndToolbarHide){ + this.toolbar = new Toolbar.ToolbarClass(this.cache, this.settings); + } + + }, + + + + /* + * Function: resetPosition + */ + resetPosition: function(){ + + this.destroyZoomPanRotate(); + + this.documentOverlay.resetPosition(); + this.carousel.resetPosition(); + + if (!Util.isNothing(this.toolbar)){ + this.toolbar.resetPosition(); + } + + this.uiLayer.resetPosition(); + + Util.Events.fire(this, { + type: PhotoSwipe.EventTypes.onResetPosition, + target: this + }); + + }, + + + + /* + * Function: addEventHandler + */ + addEventHandler: function(type, handler){ + + Util.Events.add(this, type, handler); + + }, + + + + /* + * Function: addEventHandlers + */ + addEventHandlers: function(){ + + if (Util.isNothing(this.windowOrientationChangeHandler)){ + + this.windowOrientationChangeHandler = this.onWindowOrientationChange.bind(this); + this.windowScrollHandler = this.onWindowScroll.bind(this); + this.keyDownHandler = this.onKeyDown.bind(this); + this.windowHashChangeHandler = this.onWindowHashChange.bind(this); + this.uiLayerTouchHandler = this.onUILayerTouch.bind(this); + this.carouselSlideByEndHandler = this.onCarouselSlideByEnd.bind(this); + this.carouselSlideshowStartHandler = this.onCarouselSlideshowStart.bind(this); + this.carouselSlideshowStopHandler = this.onCarouselSlideshowStop.bind(this); + this.toolbarClickHandler = this.onToolbarClick.bind(this); + this.toolbarBeforeShowHandler = this.onToolbarBeforeShow.bind(this); + this.toolbarShowHandler = this.onToolbarShow.bind(this); + this.toolbarBeforeHideHandler = this.onToolbarBeforeHide.bind(this); + this.toolbarHideHandler = this.onToolbarHide.bind(this); + this.mouseWheelHandler = this.onMouseWheel.bind(this); + + } + + // Set window handlers + if (Util.Browser.android){ + // For some reason, resize was more stable than orientationchange in Android + this.orientationEventName = 'resize'; + } + else{ + var supportsOrientationChange = !Util.isNothing(window.onorientationchange); + this.orientationEventName = supportsOrientationChange ? 'orientationchange' : 'resize'; + } + + Util.Events.add(window, this.orientationEventName, this.windowOrientationChangeHandler); + Util.Events.add(window, 'scroll', this.windowScrollHandler); + + if (this.settings.enableKeyboard){ + Util.Events.add(window.document, 'keydown', this.keyDownHandler); + } + + if (this.isBackEventSupported && this.settings.backButtonHideEnabled){ + + this.windowHashChangeHandler = this.onWindowHashChange.bind(this); + + if (this.settings.jQueryMobile){ + window.location.hash = this.settings.jQueryMobileDialogHash; + } + else{ + this.currentHistoryHashValue = 'PhotoSwipe' + new Date().getTime().toString(); + window.location.hash = this.currentHistoryHashValue; + } + + Util.Events.add(window, 'hashchange', this.windowHashChangeHandler); + + } + + if (this.settings.enableMouseWheel){ + Util.Events.add(window, 'mousewheel', this.mouseWheelHandler); + } + + Util.Events.add(this.uiLayer, PhotoSwipe.TouchElement.EventTypes.onTouch, this.uiLayerTouchHandler); + Util.Events.add(this.carousel, Carousel.EventTypes.onSlideByEnd, this.carouselSlideByEndHandler); + Util.Events.add(this.carousel, Carousel.EventTypes.onSlideshowStart, this.carouselSlideshowStartHandler); + Util.Events.add(this.carousel, Carousel.EventTypes.onSlideshowStop, this.carouselSlideshowStopHandler); + + if (!Util.isNothing(this.toolbar)){ + Util.Events.add(this.toolbar, Toolbar.EventTypes.onClick, this.toolbarClickHandler); + Util.Events.add(this.toolbar, Toolbar.EventTypes.onBeforeShow, this.toolbarBeforeShowHandler); + Util.Events.add(this.toolbar, Toolbar.EventTypes.onShow, this.toolbarShowHandler); + Util.Events.add(this.toolbar, Toolbar.EventTypes.onBeforeHide, this.toolbarBeforeHideHandler); + Util.Events.add(this.toolbar, Toolbar.EventTypes.onHide, this.toolbarHideHandler); + } + + }, + + + + /* + * Function: removeEventHandlers + */ + removeEventHandlers: function(){ + + Util.Events.remove(window, this.orientationEventName, this.windowOrientationChangeHandler); + Util.Events.remove(window, 'scroll', this.windowScrollHandler); + + if (this.settings.enableKeyboard){ + Util.Events.remove(window.document, 'keydown', this.keyDownHandler); + } + + if (this.isBackEventSupported && this.settings.backButtonHideEnabled){ + Util.Events.remove(window, 'hashchange', this.windowHashChangeHandler); + } + + Util.Events.remove(this.uiLayer, PhotoSwipe.TouchElement.EventTypes.onTouch, this.uiLayerTouchHandler); + Util.Events.remove(this.carousel, Carousel.EventTypes.onSlideByEnd, this.carouselSlideByEndHandler); + Util.Events.remove(this.carousel, Carousel.EventTypes.onSlideshowStart, this.carouselSlideshowStartHandler); + Util.Events.remove(this.carousel, Carousel.EventTypes.onSlideshowStop, this.carouselSlideshowStopHandler); + + if (this.settings.enableMouseWheel){ + Util.Events.remove(window, 'mousewheel', this.mouseWheelHandler); + } + + if (!Util.isNothing(this.toolbar)){ + Util.Events.remove(this.toolbar, Toolbar.EventTypes.onClick, this.toolbarClickHandler); + Util.Events.remove(this.toolbar, Toolbar.EventTypes.onBeforeShow, this.toolbarBeforeShowHandler); + Util.Events.remove(this.toolbar, Toolbar.EventTypes.onShow, this.toolbarShowHandler); + Util.Events.remove(this.toolbar, Toolbar.EventTypes.onBeforeHide, this.toolbarBeforeHideHandler); + Util.Events.remove(this.toolbar, Toolbar.EventTypes.onHide, this.toolbarHideHandler); + } + + }, + + + + + /* + * Function: hide + */ + hide: function(){ + + if (this.settings.preventHide){ + return; + } + + this.removeEventHandlers(); + + Util.Events.fire(this, { + type: PhotoSwipe.EventTypes.onBeforeHide, + target: this + }); + + this.uiLayer.dispose(); + this.uiLayer = null; + + if (!Util.isNothing(this.toolbar)){ + this.toolbar.dispose(); + this.toolbar = null; + } + + this.carousel.dispose(); + this.carousel = null; + + Util.DOM.removeClass(window.document.body, PhotoSwipe.CssClasses.activeBody); + + this.documentOverlay.dispose(); + this.documentOverlay = null; + + // Deactive this instance + PhotoSwipe.unsetActivateInstance(); + + Util.Events.fire(this, { + type: PhotoSwipe.EventTypes.onHide, + target: this + }); + + this.goBackInHistory(); + + }, + + + + /* + * Function: goBackInHistory + */ + goBackInHistory: function(){ + + if (this.isBackEventSupported && this.settings.backButtonHideEnabled){ + if ( !this.backButtonClicked ){ + window.history.back(); + } + } + + }, + + + + /* + * Function: play + */ + play: function(){ + + if (!this.settings.preventSlideshow){ + if (!Util.isNothing(this.carousel)){ + this.fadeOutToolbarIfVisible(); + this.carousel.startSlideshow(); + } + } + + }, + + + + /* + * Function: stop + */ + stop: function(){ + + if (!Util.isNothing(this.carousel)){ + this.carousel.stopSlideshow(); + } + + }, + + + + /* + * Function: previous + */ + previous: function(){ + + if (!Util.isNothing(this.carousel)){ + this.carousel.previous(); + } + + }, + + + + /* + * Function: next + */ + next: function(){ + + if (!Util.isNothing(this.carousel)){ + this.carousel.next(); + } + + }, + + + + /* + * Function: toggleToolbar + */ + toggleToolbar: function(){ + + if (!Util.isNothing(this.toolbar)){ + this.toolbar.toggleVisibility(this.currentIndex); + } + + }, + + + + /* + * Function: fadeOutToolbarIfVisible + */ + fadeOutToolbarIfVisible: function(){ + + if (!Util.isNothing(this.toolbar) && this.toolbar.isVisible && this.settings.captionAndToolbarAutoHideDelay > 0){ + this.toolbar.fadeOut(); + } + + }, + + + + /* + * Function: createZoomPanRotate + */ + createZoomPanRotate: function(){ + + this.stop(); + + if (this.canUserZoom() && !this.isZoomActive()){ + + this.zoomPanRotate = new ZoomPanRotate.ZoomPanRotateClass( + this.settings, + this.cache.images[this.currentIndex], + this.uiLayer + ); + + this.fadeOutToolbarIfVisible(); + + } + + }, + + + + /* + * Function: destroyZoomPanRotate + */ + destroyZoomPanRotate: function(){ + + if (!Util.isNothing(this.zoomPanRotate)){ + this.zoomPanRotate.dispose(); + this.zoomPanRotate = null; + } + + }, + + + + /* + * Function: canUserZoom + */ + canUserZoom: function(){ + + if (!Util.Browser.isCSSTransformSupported){ + return false; + } + + if (!this.settings.allowUserZoom){ + return false; + } + + if (this.carousel.isSliding){ + return false; + } + + var cacheImage = this.cache.images[this.currentIndex]; + + if (Util.isNothing(cacheImage)){ + return false; + } + + if (cacheImage.isLoading){ + return false; + } + + return true; + + }, + + + + /* + * Function: isZoomActive + */ + isZoomActive: function(){ + + return (!Util.isNothing(this.zoomPanRotate)); + + }, + + + + /* + * Function: getCurrentImage + */ + getCurrentImage: function(){ + + return this.cache.images[this.currentIndex]; + + }, + + + + /* + * Function: onDocumentOverlayFadeIn + */ + onDocumentOverlayFadeIn: function(e){ + + window.setTimeout(function(){ + + Util.DOM.removeClass(window.document.body, PhotoSwipe.CssClasses.buildingBody); + Util.DOM.addClass(window.document.body, PhotoSwipe.CssClasses.activeBody); + + this.addEventHandlers(); + + this.carousel.show(this.currentIndex); + this.uiLayer.show(); + + if (this.settings.autoStartSlideshow){ + this.play(); + } + else if (!Util.isNothing(this.toolbar)){ + this.toolbar.show(this.currentIndex); + } + + Util.Events.fire(this, { + type: PhotoSwipe.EventTypes.onShow, + target: this + }); + + }.bind(this), 250); + + + }, + + + + /* + * Function: onWindowScroll + */ + onWindowScroll: function(e){ + + this.resetPosition(); + + }, + + + + /* + * Function: onWindowOrientationChange + */ + onWindowOrientationChange: function(e){ + + this.resetPosition(); + + }, + + + + /* + * Function: onWindowHashChange + */ + onWindowHashChange: function(e){ + + var compareHash = '#' + + ((this.settings.jQueryMobile) ? this.settings.jQueryMobileDialogHash : this.currentHistoryHashValue); + + if (window.location.hash !== compareHash){ + this.backButtonClicked = true; + this.hide(); + } + + }, + + + + /* + * Function: onKeyDown + */ + onKeyDown: function(e){ + + if (e.keyCode === 37) { // Left + e.preventDefault(); + this.previous(); + } + else if (e.keyCode === 39) { // Right + e.preventDefault(); + this.next(); + } + else if (e.keyCode === 38 || e.keyCode === 40) { // Up and down + e.preventDefault(); + } + else if (e.keyCode === 27) { // Escape + e.preventDefault(); + this.hide(); + } + else if (e.keyCode === 32) { // Spacebar + if (!this.settings.hideToolbar){ + this.toggleToolbar(); + } + else{ + this.hide(); + } + e.preventDefault(); + } + else if (e.keyCode === 13) { // Enter + e.preventDefault(); + this.play(); + } + + }, + + + + /* + * Function: onUILayerTouch + */ + onUILayerTouch: function(e){ + + if (this.isZoomActive()){ + + switch (e.action){ + + case PhotoSwipe.TouchElement.ActionTypes.gestureChange: + this.zoomPanRotate.zoomRotate(e.scale, (this.settings.allowRotationOnUserZoom) ? e.rotation : 0); + break; + + case PhotoSwipe.TouchElement.ActionTypes.gestureEnd: + this.zoomPanRotate.setStartingScaleAndRotation(e.scale, (this.settings.allowRotationOnUserZoom) ? e.rotation : 0); + break; + + case PhotoSwipe.TouchElement.ActionTypes.touchStart: + this.zoomPanRotate.panStart(e.point); + break; + + case PhotoSwipe.TouchElement.ActionTypes.touchMove: + this.zoomPanRotate.pan(e.point); + break; + + case PhotoSwipe.TouchElement.ActionTypes.doubleTap: + this.destroyZoomPanRotate(); + this.toggleToolbar(); + break; + + case PhotoSwipe.TouchElement.ActionTypes.swipeLeft: + this.destroyZoomPanRotate(); + this.next(); + this.toggleToolbar(); + break; + + case PhotoSwipe.TouchElement.ActionTypes.swipeRight: + this.destroyZoomPanRotate(); + this.previous(); + this.toggleToolbar(); + break; + } + + } + else{ + + switch (e.action){ + + case PhotoSwipe.TouchElement.ActionTypes.touchMove: + case PhotoSwipe.TouchElement.ActionTypes.swipeLeft: + case PhotoSwipe.TouchElement.ActionTypes.swipeRight: + + // Hide the toolbar if need be + this.fadeOutToolbarIfVisible(); + + // Pass the touch onto the carousel + this.carousel.onTouch(e.action, e.point); + break; + + case PhotoSwipe.TouchElement.ActionTypes.touchStart: + case PhotoSwipe.TouchElement.ActionTypes.touchEnd: + + // Pass the touch onto the carousel + this.carousel.onTouch(e.action, e.point); + break; + + case PhotoSwipe.TouchElement.ActionTypes.tap: + this.toggleToolbar(); + break; + + case PhotoSwipe.TouchElement.ActionTypes.doubleTap: + + // Take into consideration the window scroll + e.point.x -= Util.DOM.windowScrollLeft(); + e.point.y -= Util.DOM.windowScrollTop(); + + // Just make sure that if the user clicks out of the image + // that the image does not pan out of view! + var + cacheImageEl = this.cache.images[this.currentIndex].imageEl, + + imageTop = window.parseInt(Util.DOM.getStyle(cacheImageEl, 'top'), 10), + imageLeft = window.parseInt(Util.DOM.getStyle(cacheImageEl, 'left'), 10), + imageRight = imageLeft + Util.DOM.width(cacheImageEl), + imageBottom = imageTop + Util.DOM.height(cacheImageEl); + + if (e.point.x < imageLeft){ + e.point.x = imageLeft; + } + else if (e.point.x > imageRight){ + e.point.x = imageRight; + } + + if (e.point.y < imageTop){ + e.point.y = imageTop; + } + else if (e.point.y > imageBottom){ + e.point.y = imageBottom; + } + + this.createZoomPanRotate(); + if (this.isZoomActive()){ + this.zoomPanRotate.zoomAndPanToPoint(this.settings.doubleTapZoomLevel, e.point); + } + + break; + + case PhotoSwipe.TouchElement.ActionTypes.gestureStart: + this.createZoomPanRotate(); + break; + } + + + } + + Util.Events.fire(this, { + type: PhotoSwipe.EventTypes.onTouch, + target: this, + point: e.point, + action: e.action + }); + + }, + + + + /* + * Function: onCarouselSlideByEnd + */ + onCarouselSlideByEnd: function(e){ + + this.currentIndex = e.cacheIndex; + + if (!Util.isNothing(this.toolbar)){ + this.toolbar.setCaption(this.currentIndex); + this.toolbar.setToolbarStatus(this.currentIndex); + } + + Util.Events.fire(this, { + type: PhotoSwipe.EventTypes.onDisplayImage, + target: this, + action: e.action, + index: e.cacheIndex + }); + + }, + + + + /* + * Function: onToolbarClick + */ + onToolbarClick: function(e){ + + switch(e.action){ + + case Toolbar.ToolbarAction.next: + this.next(); + break; + + case Toolbar.ToolbarAction.previous: + this.previous(); + break; + + case Toolbar.ToolbarAction.close: + this.hide(); + break; + + case Toolbar.ToolbarAction.play: + this.play(); + break; + + } + + }, + + + + /* + * Function: onMouseWheel + */ + onMouseWheel: function(e){ + + var + delta = Util.Events.getWheelDelta(e), + dt = e.timeStamp - (this.mouseWheelStartTime || 0); + + if (dt < this.settings.mouseWheelSpeed) { + return; + } + + this.mouseWheelStartTime = e.timeStamp; + + if (this.settings.invertMouseWheel){ + delta = delta * -1; + } + + if (delta < 0){ + this.next(); + } + else if (delta > 0){ + this.previous(); + } + + }, + + + + /* + * Function: onCarouselSlideshowStart + */ + onCarouselSlideshowStart: function(e){ + + Util.Events.fire(this, { + type: PhotoSwipe.EventTypes.onSlideshowStart, + target: this + }); + + }, + + + + /* + * Function: onCarouselSlideshowStop + */ + onCarouselSlideshowStop: function(e){ + + Util.Events.fire(this, { + type: PhotoSwipe.EventTypes.onSlideshowStop, + target: this + }); + + }, + + + + /* + * Function: onToolbarBeforeShow + */ + onToolbarBeforeShow: function(e){ + + Util.Events.fire(this, { + type: PhotoSwipe.EventTypes.onBeforeCaptionAndToolbarShow, + target: this + }); + + }, + + + + /* + * Function: onToolbarShow + */ + onToolbarShow: function(e){ + + Util.Events.fire(this, { + type: PhotoSwipe.EventTypes.onCaptionAndToolbarShow, + target: this + }); + + }, + + + + /* + * Function: onToolbarBeforeHide + */ + onToolbarBeforeHide: function(e){ + + Util.Events.fire(this, { + type: PhotoSwipe.EventTypes.onBeforeCaptionAndToolbarHide, + target: this + }); + + }, + + + + /* + * Function: onToolbarHide + */ + onToolbarHide: function(e){ + + Util.Events.fire(this, { + type: PhotoSwipe.EventTypes.onCaptionAndToolbarHide, + target: this + }); + + } + + + }); + + + +} +( + window, + window.klass, + window.Code.Util, + window.Code.PhotoSwipe.Cache, + window.Code.PhotoSwipe.DocumentOverlay, + window.Code.PhotoSwipe.Carousel, + window.Code.PhotoSwipe.Toolbar, + window.Code.PhotoSwipe.UILayer, + window.Code.PhotoSwipe.ZoomPanRotate +)); \ No newline at end of file diff --git a/src/code.photoswipe/photoswipe.js b/src/code.photoswipe/photoswipe.js new file mode 100644 index 000000000..c8f36c986 --- /dev/null +++ b/src/code.photoswipe/photoswipe.js @@ -0,0 +1,262 @@ +// Copyright (c) %%year%% by Code Computerlove (http://www.codecomputerlove.com) +// Licensed under the MIT license +// version: %%version%% + +(function(window, Util){ + + + Util.registerNamespace('Code.PhotoSwipe'); + var PhotoSwipe = window.Code.PhotoSwipe; + + + + PhotoSwipe.CssClasses = { + buildingBody: 'ps-building', + activeBody: 'ps-active' + }; + + + + PhotoSwipe.EventTypes = { + + onBeforeShow: 'PhotoSwipeOnBeforeShow', + onShow: 'PhotoSwipeOnShow', + onBeforeHide: 'PhotoSwipeOnBeforeHide', + onHide: 'PhotoSwipeOnHide', + onDisplayImage: 'PhotoSwipeOnDisplayImage', + onResetPosition: 'PhotoSwipeOnResetPosition', + onSlideshowStart: 'PhotoSwipeOnSlideshowStart', + onSlideshowStop: 'PhotoSwipeOnSlideshowStop', + onTouch: 'PhotoSwipeOnTouch', + onBeforeCaptionAndToolbarShow: 'PhotoSwipeOnBeforeCaptionAndToolbarShow', + onCaptionAndToolbarShow: 'PhotoSwipeOnCaptionAndToolbarShow', + onBeforeCaptionAndToolbarHide: 'PhotoSwipeOnBeforeCaptionAndToolbarHide', + onCaptionAndToolbarHide: 'PhotoSwipeOnCaptionAndToolbarHide' + + }; + + + + PhotoSwipe.instances = []; + PhotoSwipe.activeInstance = null; + + + + /* + * Function: Code.PhotoSwipe.setActivateInstance + */ + PhotoSwipe.setActivateInstance = function(instance){ + + if (!Util.isNothing(PhotoSwipe.activeInstance)){ + throw 'Code.PhotoSwipe.activateInstance: Unable to active instance as another instance is already active'; + } + + PhotoSwipe.activeInstance = instance; + + }; + + + + /* + * Function: Code.PhotoSwipe.unsetActivateInstance + */ + PhotoSwipe.unsetActivateInstance = function(){ + + PhotoSwipe.activeInstance = null; + + }; + + + + /* + * Function: Code.PhotoSwipe.attach + */ + PhotoSwipe.attach = function(images, options){ + + var i, instance, image; + + instance = PhotoSwipe.createInstance(images, options); + + // Add click event handlers if applicable + for (i=0; i 0){ + // Set a timeout to hide the toolbar + this.clearTimeout(); + this.timeout = window.setTimeout(this.fadeOut.bind(this), this.settings.captionAndToolbarAutoHideDelay); + } + + }, + + + + /* + * Function: clearTimeout + */ + clearTimeout: function(){ + + if (!Util.isNothing(this.timeout)){ + window.clearTimeout(this.timeout); + this.timeout = null; + } + + }, + + + + /* + * Function: fadeOut + */ + fadeOut: function(){ + + this.clearTimeout(); + + Util.Events.fire(this, { + type: PhotoSwipe.Toolbar.EventTypes.onBeforeHide, + target: this + }); + + Util.Animation.fadeOut(this.toolbarEl, this.settings.fadeOutSpeed); + Util.Animation.fadeOut(this.captionEl, this.settings.fadeOutSpeed, this.fadeOutHandler); + + this.isVisible = false; + + }, + + + + /* + * Function: addEventHandlers + */ + addEventHandlers: function(){ + + if (Util.Browser.isTouchSupported){ + if (!Util.Browser.blackberry){ + // Had an issue with touchstart, animation and Blackberry. BB will default to click + Util.Events.add(this.toolbarEl, 'touchstart', this.touchStartHandler); + } + Util.Events.add(this.toolbarEl, 'touchmove', this.touchMoveHandler); + Util.Events.add(this.captionEl, 'touchmove', this.touchMoveHandler); + } + Util.Events.add(this.toolbarEl, 'click', this.clickHandler); + + }, + + + + /* + * Function: removeEventHandlers + */ + removeEventHandlers: function(){ + + if (Util.Browser.isTouchSupported){ + if (!Util.Browser.blackberry){ + // Had an issue with touchstart, animation and Blackberry. BB will default to click + Util.Events.remove(this.toolbarEl, 'touchstart', this.touchStartHandler); + } + Util.Events.remove(this.toolbarEl, 'touchmove', this.touchMoveHandler); + Util.Events.remove(this.captionEl, 'touchmove', this.touchMoveHandler); + } + Util.Events.remove(this.toolbarEl, 'click', this.clickHandler); + + }, + + + + /* + * Function: handleClick + */ + handleClick: function(e){ + + this.clearTimeout(); + + var action; + + if (e.target === this.nextEl || Util.DOM.isChildOf(e.target, this.nextEl)){ + action = PhotoSwipe.Toolbar.ToolbarAction.next; + } + else if (e.target === this.previousEl || Util.DOM.isChildOf(e.target, this.previousEl)){ + action = PhotoSwipe.Toolbar.ToolbarAction.previous; + } + else if (e.target === this.closeEl || Util.DOM.isChildOf(e.target, this.closeEl)){ + action = PhotoSwipe.Toolbar.ToolbarAction.close; + } + else if (e.target === this.playEl || Util.DOM.isChildOf(e.target, this.playEl)){ + action = PhotoSwipe.Toolbar.ToolbarAction.play; + } + + this.setTimeout(); + + if (Util.isNothing(action)){ + return; + } + + Util.Events.fire(this, { + type: PhotoSwipe.Toolbar.EventTypes.onClick, + target: this, + action: action + }); + + }, + + + + /* + * Function: setCaption + */ + setCaption: function(index){ + + Util.DOM.removeChildren(this.captionContentEl); + + this.currentCaption = Util.coalesce(this.cache.images[index].caption, '\u00A0'); + + if (Util.isObject(this.currentCaption)){ + Util.DOM.appendChild(this.currentCaption, this.captionContentEl); + } + else{ + if (this.currentCaption === ''){ + this.currentCaption = '\u00A0'; + } + Util.DOM.appendText(this.currentCaption, this.captionContentEl); + } + + this.currentCaption = (this.currentCaption === '\u00A0') ? '' : this.currentCaption; + + }, + + + + /* + * Function: showToolbar + */ + showToolbar: function(){ + + Util.DOM.setStyle(this.toolbarEl, { + opacity: this.settings.captionAndToolbarOpacity + }); + Util.DOM.show(this.toolbarEl); + + }, + + + + /* + * Function: showCaption + */ + showCaption: function(){ + + if (this.currentCaption === '' || this.captionContentEl.childNodes.length < 1){ + // Empty caption + if (!this.settings.captionAndToolbarShowEmptyCaptions){ + Util.DOM.hide(this.captionEl); + return; + } + } + Util.DOM.setStyle(this.captionEl, { + opacity: this.settings.captionAndToolbarOpacity + }); + Util.DOM.show(this.captionEl); + + }, + + + + /* + * Function: setToolbarStatus + */ + setToolbarStatus: function(index){ + + if (this.settings.loop){ + return; + } + + if (index > 0 && index < this.cache.images.length-1){ + Util.DOM.removeClass(this.previousEl, PhotoSwipe.Toolbar.CssClasses.previousDisabled); + Util.DOM.removeClass(this.nextEl, PhotoSwipe.Toolbar.CssClasses.nextDisabled); + return; + } + + if (index === 0){ + if (!Util.isNothing(this.previousEl)){ + Util.DOM.addClass(this.previousEl, PhotoSwipe.Toolbar.CssClasses.previousDisabled); + } + } + + if (index === this.cache.images.length-1){ + if (!Util.isNothing(this.nextEl)){ + Util.DOM.addClass(this.nextEl, PhotoSwipe.Toolbar.CssClasses.nextDisabled); + } + } + + }, + + + + /* + * Function: onFadeOut + */ + onFadeOut: function(){ + + Util.DOM.hide(this.toolbarEl); + Util.DOM.hide(this.captionEl); + + Util.Events.fire(this, { + type: PhotoSwipe.Toolbar.EventTypes.onHide, + target: this + }); + + }, + + + + /* + * Function: onTouchStart + */ + onTouchStart: function(e){ + + e.preventDefault(); + Util.Events.remove(this.toolbarEl, 'click', this.clickHandler); + this.handleClick(e); + + }, + + + + /* + * Function: onTouchMove + */ + onTouchMove: function(e){ + + e.preventDefault(); + + }, + + + + /* + * Function: onClick + */ + onClick: function(e){ + + e.preventDefault(); + this.handleClick(e); + + } + + + }); + + + +} +( + window, + window.klass, + window.Code.Util +)); \ No newline at end of file diff --git a/src/code.photoswipe/toolbar.js b/src/code.photoswipe/toolbar.js new file mode 100644 index 000000000..8e065289b --- /dev/null +++ b/src/code.photoswipe/toolbar.js @@ -0,0 +1,59 @@ +// Copyright (c) %%year%% by Code Computerlove (http://www.codecomputerlove.com) +// Licensed under the MIT license +// version: %%version%% + +(function(window, klass, Util){ + + + Util.registerNamespace('Code.PhotoSwipe.Toolbar'); + var PhotoSwipe = window.Code.PhotoSwipe; + + + PhotoSwipe.Toolbar.CssClasses = { + toolbar: 'ps-toolbar', + toolbarContent: 'ps-toolbar-content', + toolbarTop: 'ps-toolbar-top', + caption: 'ps-caption', + captionBottom: 'ps-caption-bottom', + captionContent: 'ps-caption-content', + close: 'ps-toolbar-close', + play: 'ps-toolbar-play', + previous: 'ps-toolbar-previous', + previousDisabled: 'ps-toolbar-previous-disabled', + next: 'ps-toolbar-next', + nextDisabled: 'ps-toolbar-next-disabled' + }; + + + + PhotoSwipe.Toolbar.ToolbarAction = { + close: 'close', + play: 'play', + next: 'next', + previous: 'previous' + }; + + + + PhotoSwipe.Toolbar.EventTypes = { + onClick: 'PhotoSwipeToolbarOnClick', + onBeforeShow: 'PhotoSwipeToolbarOnBeforeShow', + onShow: 'PhotoSwipeToolbarOnShow', + onBeforeHide: 'PhotoSwipeToolbarOnBeforeHide', + onHide: 'PhotoSwipeToolbarOnHide' + }; + + + + PhotoSwipe.Toolbar.getToolbar = function(){ + + return '
'; + + }; + +} +( + window, + window.klass, + window.Code.Util +)); \ No newline at end of file diff --git a/src/code.photoswipe/touchelement.class.js b/src/code.photoswipe/touchelement.class.js new file mode 100644 index 000000000..bec7a2d02 --- /dev/null +++ b/src/code.photoswipe/touchelement.class.js @@ -0,0 +1,474 @@ +// Copyright (c) %%year%% by Code Computerlove (http://www.codecomputerlove.com) +// Licensed under the MIT license +// version: %%version%% + +(function(window, klass, Util){ + + + Util.registerNamespace('Code.PhotoSwipe.TouchElement'); + var PhotoSwipe = window.Code.PhotoSwipe; + + + PhotoSwipe.TouchElement.TouchElementClass = klass({ + + + + el: null, + touchSettings: null, + touchStartPoint: null, + touchEndPoint: null, + touchStartTime: null, + doubleTapTimeout: null, + + touchStartHandler: null, + touchMoveHandler: null, + touchEndHandler: null, + + mouseDownHandler: null, + mouseMoveHandler: null, + mouseUpHandler: null, + mouseOutHandler: null, + + gestureStartHandler: null, + gestureChangeHandler: null, + gestureEndHandler: null, + + + + + /* + * Function: initialize + */ + initialize: function(options){ + + this.touchSettings = { + swipeThreshold: 50, + swipeTimeThreshold: 250, + doubleTapSpeed: 250 + }; + + Util.extend(this.touchSettings, options); + + this.touchStartPoint = { x: 0, y: 0 }; + this.touchEndPoint = { x: 0, y: 0 }; + + }, + + + + /* + * Function: addEventHandlers + */ + addEventHandlers: function(){ + + if (Util.isNothing(this.touchStartHandler)){ + this.touchStartHandler = this.onTouchStart.bind(this); + this.touchMoveHandler = this.onTouchMove.bind(this); + this.touchEndHandler = this.onTouchEnd.bind(this); + this.mouseDownHandler = this.onMouseDown.bind(this); + this.mouseMoveHandler = this.onMouseMove.bind(this); + this.mouseUpHandler = this.onMouseUp.bind(this); + this.mouseOutHandler = this.onMouseOut.bind(this); + this.gestureStartHandler = this.onGestureStart.bind(this); + this.gestureChangeHandler = this.onGestureChange.bind(this); + this.gestureEndHandler = this.onGestureEnd.bind(this); + } + + Util.Events.add(this.el, 'touchstart', this.touchStartHandler); + Util.Events.add(this.el, 'touchmove', this.touchMoveHandler); + Util.Events.add(this.el, 'touchend', this.touchEndHandler); + + Util.Events.add(this.el, 'mousedown', this.mouseDownHandler); + + if (Util.Browser.isGestureSupported){ + Util.Events.add(this.el, 'gesturestart', this.gestureStartHandler); + Util.Events.add(this.el, 'gesturechange', this.gestureChangeHandler); + Util.Events.add(this.el, 'gestureend', this.gestureEndHandler); + } + + }, + + + + /* + * Function: removeEventHandlers + */ + removeEventHandlers: function(){ + + Util.Events.remove(this.el, 'touchstart', this.touchStartHandler); + Util.Events.remove(this.el, 'touchmove', this.touchMoveHandler); + Util.Events.remove(this.el, 'touchend', this.touchEndHandler); + Util.Events.remove(this.el, 'mousedown', this.mouseDownHandler); + + if (Util.Browser.isGestureSupported){ + Util.Events.remove(this.el, 'gesturestart', this.gestureStartHandler); + Util.Events.remove(this.el, 'gesturechange', this.gestureChangeHandler); + Util.Events.remove(this.el, 'gestureend', this.gestureEndHandler); + } + + }, + + + + /* + * Function: getTouchPoint + */ + getTouchPoint: function(touches){ + + return { + x: touches[0].pageX, + y: touches[0].pageY + }; + + }, + + + + /* + * Function: fireTouchEvent + */ + fireTouchEvent: function(){ + + var + action, + distX = 0, + distY = 0, + dist = 0, + self, + endTime, + diffTime; + + distX = this.touchEndPoint.x - this.touchStartPoint.x; + distY = this.touchEndPoint.y - this.touchStartPoint.y; + dist = Math.sqrt( (distX * distX) + (distY * distY) ); + + endTime = new Date(); + diffTime = endTime - this.touchStartTime; + + // See if there was a swipe gesture + if (diffTime <= this.touchSettings.swipeTimeThreshold){ + + if (window.Math.abs(distX) >= this.touchSettings.swipeThreshold){ + + Util.Events.fire(this, { + type: PhotoSwipe.TouchElement.EventTypes.onTouch, + target: this, + point: this.touchEndPoint, + action: (distX < 0) ? PhotoSwipe.TouchElement.ActionTypes.swipeLeft : PhotoSwipe.TouchElement.ActionTypes.swipeRight + }); + return; + + } + + + if (window.Math.abs(distY) >= this.touchSettings.swipeThreshold){ + + Util.Events.fire(this, { + type: PhotoSwipe.TouchElement.EventTypes.onTouch, + target: this, + point: this.touchEndPoint, + action: (distY < 0) ? PhotoSwipe.TouchElement.ActionTypes.swipeUp : PhotoSwipe.TouchElement.ActionTypes.swipeDown + }); + return; + + } + + } + + + if (dist > 1){ + Util.Events.fire(this, { + type: PhotoSwipe.TouchElement.EventTypes.onTouch, + target: this, + action: PhotoSwipe.TouchElement.ActionTypes.touchEnd, + point: this.touchEndPoint + }); + return; + } + + + if (Util.isNothing(this.doubleTapTimeout)){ + + self = this; + this.doubleTapTimeout = window.setTimeout(function(){ + + self.doubleTapTimeout = null; + + Util.Events.fire(self, { + type: PhotoSwipe.TouchElement.EventTypes.onTouch, + target: self, + point: this.touchEndPoint, + action: PhotoSwipe.TouchElement.ActionTypes.tap + }); + + }, this.touchSettings.doubleTapSpeed); + + return; + + } + else{ + + window.clearTimeout(this.doubleTapTimeout); + this.doubleTapTimeout = null; + + Util.Events.fire(this, { + type: PhotoSwipe.TouchElement.EventTypes.onTouch, + target: this, + point: this.touchEndPoint, + action: PhotoSwipe.TouchElement.ActionTypes.doubleTap + }); + + } + + }, + + + + /* + * Function: onTouchStart + */ + onTouchStart: function(e){ + + e.preventDefault(); + + // No longer need mouse events + Util.Events.remove(this.el, 'mousedown', this.mouseDownHandler); + + var + touchEvent = Util.Events.getTouchEvent(e), + touches = touchEvent.touches; + + if (touches.length > 1){ + this.isGesture = true; + return; + } + + this.touchStartTime = new Date(); + this.isGesture = false; + this.touchStartPoint = this.getTouchPoint(touches); + + Util.Events.fire(this, { + type: PhotoSwipe.TouchElement.EventTypes.onTouch, + target: this, + action: PhotoSwipe.TouchElement.ActionTypes.touchStart, + point: this.touchStartPoint + }); + + }, + + + + /* + * Function: onTouchMove + */ + onTouchMove: function(e){ + + e.preventDefault(); + + if (this.isGesture){ + return; + } + + var + touchEvent = Util.Events.getTouchEvent(e), + touches = touchEvent.touches; + + Util.Events.fire(this, { + type: PhotoSwipe.TouchElement.EventTypes.onTouch, + target: this, + action: PhotoSwipe.TouchElement.ActionTypes.touchMove, + point: this.getTouchPoint(touches) + }); + + }, + + + + /* + * Function: onTouchEnd + */ + onTouchEnd: function(e){ + + if (this.isGesture){ + return; + } + + e.preventDefault(); + + // http://backtothecode.blogspot.com/2009/10/javascript-touch-and-gesture-events.html + // iOS removed the current touch from e.touches on "touchend" + // Need to look into e.changedTouches + + var + touchEvent = Util.Events.getTouchEvent(e), + touches = (!Util.isNothing(touchEvent.changedTouches)) ? touchEvent.changedTouches : touchEvent.touches; + + this.touchEndPoint = this.getTouchPoint(touches); + + this.fireTouchEvent(); + + }, + + + + /* + * Function: onMouseDown + */ + onMouseDown: function(e){ + + e.preventDefault(); + + // No longer need touch events + Util.Events.remove(this.el, 'touchstart', this.mouseDownHandler); + Util.Events.remove(this.el, 'touchmove', this.touchMoveHandler); + Util.Events.remove(this.el, 'touchend', this.touchEndHandler); + + // Add move/up/out + Util.Events.add(this.el, 'mousemove', this.mouseMoveHandler); + Util.Events.add(this.el, 'mouseup', this.mouseUpHandler); + Util.Events.add(this.el, 'mouseout', this.mouseOutHandler); + + this.touchStartTime = new Date(); + this.isGesture = false; + this.touchStartPoint = Util.Events.getMousePosition(e); + + Util.Events.fire(this, { + type: PhotoSwipe.TouchElement.EventTypes.onTouch, + target: this, + action: PhotoSwipe.TouchElement.ActionTypes.touchStart, + point: this.touchStartPoint + }); + + }, + + + + /* + * Function: onMouseMove + */ + onMouseMove: function(e){ + + e.preventDefault(); + + Util.Events.fire(this, { + type: PhotoSwipe.TouchElement.EventTypes.onTouch, + target: this, + action: PhotoSwipe.TouchElement.ActionTypes.touchMove, + point: Util.Events.getMousePosition(e) + }); + + }, + + + + /* + * Function: onMouseUp + */ + onMouseUp: function(e){ + + e.preventDefault(); + + Util.Events.remove(this.el, 'mousemove', this.mouseMoveHandler); + Util.Events.remove(this.el, 'mouseup', this.mouseUpHandler); + Util.Events.remove(this.el, 'mouseout', this.mouseOutHandler); + + this.touchEndPoint = Util.Events.getMousePosition(e); + + this.fireTouchEvent(); + + }, + + + + /* + * Function: onMouseOut + */ + onMouseOut: function(e){ + + e.preventDefault(); + + Util.Events.remove(this.el, 'mousemove', this.mouseMoveHandler); + Util.Events.remove(this.el, 'mouseup', this.mouseUpHandler); + Util.Events.remove(this.el, 'mouseout', this.mouseOutHandler); + + this.touchEndPoint = Util.Events.getMousePosition(e); + + this.fireTouchEvent(); + + }, + + + + /* + * Function: onGestureStart + */ + onGestureStart: function(e){ + + e.preventDefault(); + + var touchEvent = Util.Events.getTouchEvent(e); + + Util.Events.fire(this, { + type: PhotoSwipe.TouchElement.EventTypes.onTouch, + target: this, + action: PhotoSwipe.TouchElement.ActionTypes.gestureStart, + scale: touchEvent.scale, + rotation: touchEvent.rotation + }); + + }, + + + + /* + * Function: onGestureChange + */ + onGestureChange: function(e){ + + e.preventDefault(); + + var touchEvent = Util.Events.getTouchEvent(e); + + Util.Events.fire(this, { + type: PhotoSwipe.TouchElement.EventTypes.onTouch, + target: this, + action: PhotoSwipe.TouchElement.ActionTypes.gestureChange, + scale: touchEvent.scale, + rotation: touchEvent.rotation + }); + + }, + + + + /* + * Function: onGestureEnd + */ + onGestureEnd: function(e){ + + e.preventDefault(); + + var touchEvent = Util.Events.getTouchEvent(e); + + Util.Events.fire(this, { + type: PhotoSwipe.TouchElement.EventTypes.onTouch, + target: this, + action: PhotoSwipe.TouchElement.ActionTypes.gestureEnd, + scale: touchEvent.scale, + rotation: touchEvent.rotation + }); + + } + + + + }); + + + +} +( + window, + window.klass, + window.Code.Util +)); \ No newline at end of file diff --git a/src/code.photoswipe/touchelement.js b/src/code.photoswipe/touchelement.js new file mode 100644 index 000000000..ba5f2b79c --- /dev/null +++ b/src/code.photoswipe/touchelement.js @@ -0,0 +1,42 @@ +// Copyright (c) %%year%% by Code Computerlove (http://www.codecomputerlove.com) +// Licensed under the MIT license +// version: %%version%% + +(function(window, klass, Util){ + + + Util.registerNamespace('Code.PhotoSwipe.TouchElement'); + var PhotoSwipe = window.Code.PhotoSwipe; + + + PhotoSwipe.TouchElement.EventTypes = { + + onTouch: 'CodePhotoSwipeTouchElementOnTouch' + + }; + + + PhotoSwipe.TouchElement.ActionTypes = { + + touchStart: 'touchStart', + touchMove: 'touchMove', + touchEnd: 'touchEnd', + tap: 'tap', + doubleTap: 'doubleTap', + swipeLeft: 'swipeLeft', + swipeRight: 'swipeRight', + swipeUp: 'swipeUp', + swipeDown: 'swipeDown', + gestureStart: 'gestureStart', + gestureChange: 'gestureChange', + gestureEnd: 'gestureEnd' + + }; + + +} +( + window, + window.klass, + window.Code.Util +)); \ No newline at end of file diff --git a/src/code.photoswipe/uilayer.class.js b/src/code.photoswipe/uilayer.class.js new file mode 100644 index 000000000..f79aa67b6 --- /dev/null +++ b/src/code.photoswipe/uilayer.class.js @@ -0,0 +1,141 @@ +// Copyright (c) %%year%% by Code Computerlove (http://www.codecomputerlove.com) +// Licensed under the MIT license +// version: %%version%% + +(function(window, klass, Util, TouchElement){ + + + Util.registerNamespace('Code.PhotoSwipe.UILayer'); + var PhotoSwipe = window.Code.PhotoSwipe; + + + PhotoSwipe.UILayer.UILayerClass = TouchElement.TouchElementClass.extend({ + + + + el: null, + settings: null, + + + + /* + * Function: dispose + */ + dispose: function(){ + + var prop; + + this.removeEventHandlers(); + + Util.DOM.removeChild(this.el, this.el.parentNode); + + for (prop in this) { + if (Util.objectHasProperty(this, prop)) { + this[prop] = null; + } + } + + }, + + + + /* + * Function: initialize + */ + initialize: function(options){ + + this.settings = options; + + this.supr({ + swipeThreshold: this.settings.swipeThreshold, + swipeTimeThreshold: this.settings.swipeTimeThreshold, + doubleTapSpeed: this.settings.doubleTapSpeed + }); + + // Main container + this.el = Util.DOM.createElement( + 'div', + { + 'class': PhotoSwipe.UILayer.CssClasses.uiLayer + }, + '' + ); + Util.DOM.setStyle(this.el, { + display: 'block', + position: 'absolute', + left: 0, + top: 0, + overflow: 'hidden', + zIndex: this.settings.zIndex, + opacity: 0 + }); + Util.DOM.hide(this.el); + + Util.DOM.appendToBody(this.el); + + }, + + + + /* + * Function: resetPosition + */ + resetPosition: function(){ + + // Set the height and width to fill the document + Util.DOM.setStyle(this.el, { + top: Util.DOM.windowScrollTop() + 'px', + width: Util.DOM.windowWidth(), + height: Util.DOM.windowHeight() + }); + + + }, + + + + /* + * Function: show + */ + show: function(){ + + this.resetPosition(); + Util.DOM.show(this.el); + this.addEventHandlers(); + + }, + + + + /* + * Function: addEventHandlers + */ + addEventHandlers: function(){ + + this.supr(); + + }, + + + + /* + * Function: removeEventHandlers + */ + removeEventHandlers: function(){ + + this.supr(); + + } + + + }); + + + +} +( + window, + window.klass, + window.Code.Util, + window.Code.PhotoSwipe.TouchElement +)); \ No newline at end of file diff --git a/src/code.photoswipe/uilayer.js b/src/code.photoswipe/uilayer.js new file mode 100644 index 000000000..a30d29c99 --- /dev/null +++ b/src/code.photoswipe/uilayer.js @@ -0,0 +1,20 @@ +// Copyright (c) %%year%% by Code Computerlove (http://www.codecomputerlove.com) +// Licensed under the MIT license +// version: %%version%% + +(function(window, klass, Util){ + + + Util.registerNamespace('Code.PhotoSwipe.UILayer'); + var PhotoSwipe = window.Code.PhotoSwipe; + + PhotoSwipe.UILayer.CssClasses = { + uiLayer: 'ps-uilayer' + }; + +} +( + window, + window.klass, + window.Code.Util +)); \ No newline at end of file diff --git a/src/zoom-pan-rotate-class.js b/src/code.photoswipe/zoompanrotate.class.js similarity index 54% rename from src/zoom-pan-rotate-class.js rename to src/code.photoswipe/zoompanrotate.class.js index 5dd6e05fd..d39975926 100644 --- a/src/zoom-pan-rotate-class.js +++ b/src/code.photoswipe/zoompanrotate.class.js @@ -1,39 +1,58 @@ -// PhotoSwipe - http://www.photoswipe.com/ // Copyright (c) %%year%% by Code Computerlove (http://www.codecomputerlove.com) // Licensed under the MIT license // version: %%version%% -(function(window, Util){ +(function(window, klass, Util){ - /* - * Class: Code.PhotoSwipe.ZoomPanRotateClass - */ - Code.PhotoSwipe.ZoomPanRotateClass = Code.PhotoSwipe.ElementClass.extend({ - + + Util.registerNamespace('Code.PhotoSwipe.ZoomPanRotate'); + var PhotoSwipe = window.Code.PhotoSwipe; + + + PhotoSwipe.ZoomPanRotate.ZoomPanRotateClass = klass({ + + el: null, + settings: null, containerEl: null, imageEl: null, - parentEl: null, transformSettings: null, panStartingPoint: null, + transformEl: null, + /* - * Function: init + * Function: dispose */ - init: function(options, parentEl, imageEl){ + dispose: function(){ + + var prop; - this.settings = { - maxZoom: 5.0, - minZoom: 0.5, - adjustPanToZoom: true - }; + Util.DOM.removeChild(this.el, this.el.parentNode); - Util.extend(this.settings, options); + for (prop in this) { + if (Util.objectHasProperty(this, prop)) { + this[prop] = null; + } + } - this._super(options); - - this.parentEl = parentEl; - this.imageEl = imageEl.cloneNode(false); + }, + + + + /* + * Function: initialize + */ + initialize: function(options, cacheImage, uiLayer){ + + this.settings = options; + + this.imageEl = cacheImage.imageEl.cloneNode(false); + Util.DOM.setStyle(this.imageEl, { + + zIndex: 1 + + }); this.transformSettings = { @@ -48,34 +67,47 @@ }; - // Create element and append to body - this.el = Util.DOM.createElement('div', { 'class': Code.PhotoSwipe.ZoomPanRotateClass.CssClasses.documentOverlay }, ''); + + this.el = Util.DOM.createElement( + 'div', + { + 'class': PhotoSwipe.ZoomPanRotate.CssClasses.zoomPanRotate + }, + '' + ); Util.DOM.setStyle(this.el, { left: 0, - top: 0, + top: Util.DOM.windowScrollTop() + 'px', position: 'absolute', - // Odd, for Android 2.2 & above, if you don't specify a zIndex, scaling does not work! - zIndex: 1 + width: Util.DOM.windowWidth(), + height: Util.DOM.windowHeight(), + zIndex: this.settings.zIndex, + display: 'block' }); - Util.DOM.width(this.el, Util.DOM.bodyOuterWidth()); - Util.DOM.height(this.el, Util.DOM.windowHeight()); - this.containerEl = Util.DOM.createElement('div'); - Util.DOM.setStyle(this.containerEl, { - left: 0, - top: 0, - position: 'absolute' - }); - Util.DOM.width(this.containerEl, Util.DOM.bodyWidth()); - Util.DOM.height(this.containerEl, Util.DOM.windowHeight()); - Util.DOM.appendChild(this.imageEl, this.containerEl); - Util.DOM.appendChild(this.containerEl, this.el); - Util.DOM.appendChild(this.el, this.parentEl); + Util.DOM.insertBefore(this.el, uiLayer.el, document.body); + - if (Util.browser.isiOS){ - Util.DOM.resetTranslate(this.containerEl); - Util.DOM.resetTranslate(this.imageEl); + if (Util.Browser.iOS){ + this.containerEl = Util.DOM.createElement('div'); + Util.DOM.setStyle(this.containerEl, { + left: 0, + top: 0, + width: Util.DOM.windowWidth(), + height: Util.DOM.windowHeight(), + position: 'absolute', + zIndex: 1 + }); + Util.DOM.appendChild(this.imageEl, this.containerEl); + Util.DOM.appendChild(this.containerEl, this.el); + Util.Animation.resetTranslate(this.containerEl); + Util.Animation.resetTranslate(this.imageEl); + this.transformEl = this.containerEl; + } + else{ + Util.DOM.appendChild(this.imageEl, this.el); + this.transformEl = this.imageEl; } }, @@ -83,16 +115,17 @@ /* - * Function: setStartingTranslateFromCurrentTranform + * Function: setStartingTranslateFromCurrentTransform */ - setStartingTranslateFromCurrentTranform: function(){ + setStartingTranslateFromCurrentTransform: function(){ var - transformValue = Util.coalesce(this.containerEl.style.webkitTransform, this.containerEl.style.MozTransform, this.containerEl.style.transform); + transformValue = Util.coalesce(this.transformEl.style.webkitTransform, this.transformEl.style.MozTransform, this.transformEl.style.transform), + transformExploded; if (!Util.isNothing(transformValue)){ - var transformExploded = transformValue.match( /translate\((.*?)\)/ ); + transformExploded = transformValue.match( /translate\((.*?)\)/ ); if (!Util.isNothing(transformExploded)){ @@ -115,11 +148,11 @@ var scale = this.transformSettings.startingScale * scaleValue; - if (this.settings.minZoom !== 0 && scale < this.settings.minZoom){ - scale = this.settings.minZoom; + if (this.settings.minUserZoom !== 0 && scale < this.settings.minUserZoom){ + scale = this.settings.minUserZoom; } - else if (this.settings.maxZoom !== 0 && scale > this.settings.maxZoom){ - scale = this.settings.maxZoom; + else if (this.settings.maxUserZoom !== 0 && scale > this.settings.maxUserZoom){ + scale = this.settings.maxUserZoom; } return scale; @@ -132,7 +165,7 @@ * Function: setStartingScaleAndRotation */ setStartingScaleAndRotation: function(scaleValue, rotationValue){ - + this.transformSettings.startingScale = this.getScale(scaleValue); this.transformSettings.startingRotation = @@ -146,9 +179,9 @@ * Function: zoomRotate */ zoomRotate: function(scaleValue, rotationValue){ - - this.transformSettings.scale = this.getScale(scaleValue);; - + + this.transformSettings.scale = this.getScale(scaleValue); + this.transformSettings.rotation = this.transformSettings.startingRotation + rotationValue; @@ -163,8 +196,8 @@ */ panStart: function(point){ - this.setStartingTranslateFromCurrentTranform(); - + this.setStartingTranslateFromCurrentTransform(); + this.panStartingPoint = { x: point.x, y: point.y @@ -182,9 +215,8 @@ var dx = point.x - this.panStartingPoint.x, dy = point.y - this.panStartingPoint.y, - dxScaleAdjust = (this.settings.adjustPanToZoom) ? dx / this.transformSettings.scale : dx, - dyScaleAdjust = dy / this.transformSettings.scale ? dy / this.transformSettings.scale : dy ; - + dxScaleAdjust = dx / this.transformSettings.scale , + dyScaleAdjust = dy / this.transformSettings.scale; this.transformSettings.translateX = this.transformSettings.startingTranslateX + dxScaleAdjust; @@ -197,24 +229,13 @@ }, + /* + * Function: zoomAndPanToPoint */ zoomAndPanToPoint: function(scaleValue, point){ - - /* - var self = this; - setTimeout(function(){ - - Util.DOM.setStyle(self.containerEl, { - background: 'blue', - webkitTransform: 'scale(2.0)', - MozTransform: 'scale(2.0)' - }); - - }, 500); - */ - + this.panStart({ x: Util.DOM.bodyWidth() / 2, y: Util.DOM.windowHeight() / 2 @@ -223,8 +244,8 @@ var dx = point.x - this.panStartingPoint.x, dy = point.y - this.panStartingPoint.y, - dxScaleAdjust = (this.settings.adjustPanToZoom) ? dx / this.transformSettings.scale : dx, - dyScaleAdjust = dy / this.transformSettings.scale ? dy / this.transformSettings.scale : dy; + dxScaleAdjust = dx / this.transformSettings.scale, + dyScaleAdjust = dy / this.transformSettings.scale; this.transformSettings.translateX = (this.transformSettings.startingTranslateX + dxScaleAdjust) * -1; @@ -250,35 +271,22 @@ var transform = 'scale(' + this.transformSettings.scale + ') rotate(' + (this.transformSettings.rotation % 360) + 'deg) translate(' + window.parseInt(this.transformSettings.translateX, 10) + 'px, ' + window.parseInt(this.transformSettings.translateY, 10) + 'px)'; - Util.DOM.setStyle(this.containerEl, { + Util.DOM.setStyle(this.transformEl, { webkitTransform: transform, MozTransform: transform, msTransform: transform, transform: transform }); - }, - - - - /* - * Function: removeFromDOM - */ - removeFromDOM: function(){ - - Util.DOM.removeChild(this.el, this.parentEl); - } }); - Code.PhotoSwipe.ZoomPanRotateClass.CssClasses = { - documentOverlay: 'ps-zoom-pan-rotate' - }; - -}) + +} ( - window, - Code.PhotoSwipe.Util -); + window, + window.klass, + window.Code.Util +)); \ No newline at end of file diff --git a/src/code.photoswipe/zoompanrotate.js b/src/code.photoswipe/zoompanrotate.js new file mode 100644 index 000000000..0f32f881d --- /dev/null +++ b/src/code.photoswipe/zoompanrotate.js @@ -0,0 +1,21 @@ +// Copyright (c) %%year%% by Code Computerlove (http://www.codecomputerlove.com) +// Licensed under the MIT license +// version: %%version%% + +(function(window, klass, Util){ + + + Util.registerNamespace('Code.PhotoSwipe.ZoomPanRotate'); + var PhotoSwipe = window.Code.PhotoSwipe; + + PhotoSwipe.ZoomPanRotate.CssClasses = { + zoomPanRotate: 'ps-zoom-pan-rotate' + }; + + +} +( + window, + window.klass, + window.Code.Util +)); \ No newline at end of file diff --git a/src/code.util/animation.js b/src/code.util/animation.js new file mode 100644 index 000000000..9fcfe6c41 --- /dev/null +++ b/src/code.util/animation.js @@ -0,0 +1,290 @@ +// Copyright (c) %%year%% by Code Computerlove (http://www.codecomputerlove.com) +// Licensed under the MIT license +// version: %%version%% + +(function (window, Util) { + + Util.extend(Util, { + + Animation: { + + _applyTransitionDelay: 50, + + _transitionEndLabel: (window.document.documentElement.style.webkitTransition !== undefined) ? "webkitTransitionEnd" : "transitionend", + + _transitionEndHandler: null, + + _transitionPrefix: (window.document.documentElement.style.webkitTransition !== undefined) ? "webkitTransition" : (window.document.documentElement.style.MozTransition !== undefined) ? "MozTransition" : "transition", + + _transformLabel: (window.document.documentElement.style.webkitTransform !== undefined) ? "webkitTransform" : (window.document.documentElement.style.MozTransition !== undefined) ? "MozTransform" : "transform", + + + /* + * Function: _getTransitionEndHandler + */ + _getTransitionEndHandler: function(){ + + if (Util.isNothing(this._transitionEndHandler)){ + this._transitionEndHandler = this._onTransitionEnd.bind(this); + } + + return this._transitionEndHandler; + + }, + + + + /* + * Function: stop + */ + stop: function(el){ + + if (Util.Browser.isCSSTransformSupported){ + var + property = el.style[this._transitionPrefix + 'Property'], + callbackLabel = (property !== '') ? 'ccl' + property + 'callback' : 'cclallcallback', + style = {}; + + Util.Events.remove(el, this._transitionEndLabel, this._getTransitionEndHandler()); + if (Util.isNothing(el.callbackLabel)){ + delete el.callbackLabel; + } + + style[this._transitionPrefix + 'Property'] = ''; + style[this._transitionPrefix + 'Duration'] = ''; + style[this._transitionPrefix + 'TimingFunction'] = ''; + style[this._transitionPrefix + 'Delay'] = ''; + style[this._transformLabel] = ''; + + Util.DOM.setStyle(el, style); + } + else if (!Util.isNothing(window.jQuery)){ + + window.jQuery(el).stop(true, true); + + } + + + }, + + + + /* + * Function: fadeIn + */ + fadeIn: function(el, speed, callback, timingFunction){ + + var opacity = Util.DOM.getStyle(el, 'opacity'); + + if (opacity >= 1){ + Util.DOM.setStyle(el, 'opacity', 0); + } + + if (Util.Browser.isCSSTransformSupported){ + + this._applyTransition(el, 'opacity', 1, speed, callback, timingFunction); + + } + else if (!Util.isNothing(window.jQuery)){ + + window.jQuery(el).fadeTo(speed, 1, callback); + + } + + }, + + + + /* + * Function: fadeOut + */ + fadeOut: function(el, speed, callback, timingFunction){ + + if (Util.Browser.isCSSTransformSupported){ + + this._applyTransition(el, 'opacity', 0, speed, callback, timingFunction); + + } + else{ + + window.jQuery(el).fadeTo(speed, 0, callback); + + } + + }, + + + + /* + * Function: slideBy + */ + slideBy: function(el, x, y, speed, callback, timingFunction){ + + var style = {}; + + x = Util.coalesce(x, 0); + y = Util.coalesce(y, 0); + timingFunction = Util.coalesce(timingFunction, 'ease-out'); + + style[this._transitionPrefix + 'Property'] = 'all'; + style[this._transitionPrefix + 'Delay'] = '0'; + + if (speed === 0){ + style[this._transitionPrefix + 'Duration'] = ''; + style[this._transitionPrefix + 'TimingFunction'] = ''; + } + else{ + style[this._transitionPrefix + 'Duration'] = speed + 'ms'; + style[this._transitionPrefix + 'TimingFunction'] = Util.coalesce(timingFunction, 'ease-out'); + + Util.Events.add(el, this._transitionEndLabel, this._getTransitionEndHandler()); + + } + + style[this._transformLabel] = (Util.Browser.is3dSupported) ? 'translate3d(' + x + 'px, ' + y + 'px, 0px)' : 'translate(' + x + 'px, ' + y + 'px)'; + + if (!Util.isNothing(callback)){ + el.cclallcallback = callback; + } + + Util.DOM.setStyle(el, style); + + if (speed === 0){ + window.setTimeout(function(){ + this._leaveTransforms(el); + }.bind(this), this._applyTransitionDelay); + } + + }, + + + + /* + * Function: + */ + resetTranslate: function(el){ + + var style = {}; + style[this._transformLabel] = style[this._transformLabel] = (Util.Browser.is3dSupported) ? 'translate3d(0px, 0px, 0px)' : 'translate(0px, 0px)'; + Util.DOM.setStyle(el, style); + + }, + + + + /* + * Function: _applyTransition + */ + _applyTransition: function(el, property, val, speed, callback, timingFunction){ + + var style = {}; + + timingFunction = Util.coalesce(timingFunction, 'ease-in'); + + style[this._transitionPrefix + 'Property'] = property; + style[this._transitionPrefix + 'Duration'] = speed + 'ms'; + style[this._transitionPrefix + 'TimingFunction'] = timingFunction; + style[this._transitionPrefix + 'Delay'] = '0'; + + Util.Events.add(el, this._transitionEndLabel, this._getTransitionEndHandler()); + + Util.DOM.setStyle(el, style); + + if (!Util.isNothing(callback)){ + el['ccl' + property + 'callback'] = callback; + } + + window.setTimeout(function(){ + Util.DOM.setStyle(el, property, val); + }, this._applyTransitionDelay); + + }, + + + + /* + * Function: _onTransitionEnd + */ + _onTransitionEnd: function(e){ + + Util.Events.remove(e.currentTarget, this._transitionEndLabel, this._getTransitionEndHandler()); + this._leaveTransforms(e.currentTarget); + + }, + + + + /* + * Function: _leaveTransforms + */ + _leaveTransforms: function(el){ + + var + property = el.style[this._transitionPrefix + 'Property'], + callbackLabel = (property !== '') ? 'ccl' + property + 'callback' : 'cclallcallback', + callback, + transform = Util.coalesce(el.style.webkitTransform, el.style.MozTransform, el.style.transform), + transformMatch, + transformExploded, + domX = window.parseInt(Util.DOM.getStyle(el, 'left'), 0), + domY = window.parseInt(Util.DOM.getStyle(el, 'top'), 0), + transformedX, + transformedY, + style = {}; + + if (transform !== ''){ + if (Util.Browser.is3dSupported){ + transformMatch = transform.match( /translate3d\((.*?)\)/ ); + } + else{ + transformMatch = transform.match( /translate\((.*?)\)/ ); + } + if (!Util.isNothing(transformMatch)){ + transformExploded = transformMatch[1].split(', '); + transformedX = window.parseInt(transformExploded[0], 0); + transformedY = window.parseInt(transformExploded[1], 0); + } + } + + style[this._transitionPrefix + 'Property'] = ''; + style[this._transitionPrefix + 'Duration'] = ''; + style[this._transitionPrefix + 'TimingFunction'] = ''; + style[this._transitionPrefix + 'Delay'] = ''; + + Util.DOM.setStyle(el, style); + + window.setTimeout(function(){ + + if(!Util.isNothing(transformExploded)){ + + style = {}; + style[this._transformLabel] = ''; + style.left = (domX + transformedX) + 'px'; + style.top = (domY + transformedY) + 'px'; + + Util.DOM.setStyle(el, style); + + } + + if (!Util.isNothing(el[callbackLabel])){ + callback = el[callbackLabel]; + delete el[callbackLabel]; + callback(el); + } + + }.bind(this), this._applyTransitionDelay); + + } + + + } + + + }); + + +} +( + window, + window.Code.Util +)); diff --git a/src/code.util/browser.js b/src/code.util/browser.js new file mode 100644 index 000000000..6acdb918d --- /dev/null +++ b/src/code.util/browser.js @@ -0,0 +1,91 @@ +// Copyright (c) %%year%% by Code Computerlove (http://www.codecomputerlove.com) +// Licensed under the MIT license +// version: %%version%% + +(function(window, Util) { + + Util.Browser = { + + ua: null, + version: null, + webkit: null, + opera: null, + msie: null, + chrome: null, + mozilla: null, + + android: null, + blackberry: null, + iPad: null, + iPhone: null, + iOS: null, + + is3dSupported: null, + isCSSTransformSupported: null, + isTouchSupported: null, + isGestureSupported: null, + + + _detect: function(){ + + this.ua = window.navigator.userAgent; + this.version = (this.ua.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || []); + this.webkit = /webkit/i.test(this.ua); + this.opera = /opera/i.test(this.ua); + this.msie = /msie/i.test(this.ua) && !this.opera; + this.chrome = /Chrome/i.test(this.ua); + this.mozilla = /mozilla/i.test(this.ua) && !/(compatible|webkit)/.test(this.ua); + this.android = /android/i.test(this.ua); + this.blackberry = /blackberry/i.test(this.ua); + this.iPad = /(iPad).*OS\s([\d_]+)/.test(this.ua); + this.iPhone = !this.ipad && /(iPhone\sOS)\s([\d_]+)/.test(this.ua); + this.iOS = this.iPad || this.iPhone; + + var testEl = document.createElement('div'); + this.is3dSupported = !Util.isNothing(testEl.style.WebkitPerspective); + this.isCSSTransformSupported = ( !Util.isNothing(testEl.style.WebkitTransform) || !Util.isNothing(testEl.style.MozTransform) || !Util.isNothing(testEl.style.transformProperty) ); + //!Util.isNothing(testEl.style.msTransform) + this.isTouchSupported = this.isEventSupported('touchstart'); + this.isGestureSupported = this.isEventSupported('gesturestart'); + + }, + + + _eventTagNames: { + 'select':'input', + 'change':'input', + 'submit':'form', + 'reset':'form', + 'error':'img', + 'load':'img', + 'abort':'img' + }, + + + /* + * Function: isEventSupported + * http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ + */ + isEventSupported: function(eventName) { + var + el = document.createElement(this._eventTagNames[eventName] || 'div'), + isSupported; + eventName = 'on' + eventName; + isSupported = Util.objectHasProperty(el, eventName); + if (!isSupported) { + el.setAttribute(eventName, 'return;'); + isSupported = typeof el[eventName] === 'function'; + } + el = null; + return isSupported; + } + }; + + Util.Browser._detect(); + +} +( + window, + window.Code.Util +)) +; diff --git a/src/util-dom-jQuery.js b/src/code.util/dom.jquery.js similarity index 72% rename from src/util-dom-jQuery.js rename to src/code.util/dom.jquery.js index e1c35541e..1bef0d418 100644 --- a/src/util-dom-jQuery.js +++ b/src/code.util/dom.jquery.js @@ -1,39 +1,84 @@ -// PhotoSwipe - http://www.photoswipe.com/ // Copyright (c) %%year%% by Code Computerlove (http://www.codecomputerlove.com) // Licensed under the MIT license // version: %%version%% -(function (window, Util) { +(function (window, $, Util) { Util.extend(Util, { DOM: { + + + /* + * Function: setData + */ + setData: function(el, key, value){ + + Util.DOM.setAttribute(el, 'data-' + key, value); + + }, + + + + /* + * Function: getData + */ + getData: function(el, key, defaultValue){ + + return Util.DOM.getAttribute(el, 'data-' + key, defaultValue); + }, + + /* - * Function: resetTranslate - * Required for smoother transition on iOS + * Function: removeData */ - resetTranslate: function(el){ + removeData: function(el, key){ + + Util.DOM.removeAttribute(el, 'data-' + key); - if (Util.browser.webkit){ - if (Util.browser.is3dSupported){ - $(el).css({ webkitTransform: 'translate3d(0px, 0px, 0px)'}); - } - else{ - $(el).css({ webkitTransform: 'translate(0px, 0px)'}); - } + }, + + + + /* + * Function: isChildOf + */ + isChildOf: function(childEl, parentEl) + { + if (parentEl === childEl){ + return false; } - else { - $(el).css({ - webkitTransform: 'translate(0px, 0px)', - MozTransform: 'translate(0px, 0px)', - transform: 'translate(0px, 0px)' - }); + while (childEl && childEl !== parentEl) + { + childEl = childEl.parentNode; } - + + return childEl === parentEl; }, - + + + + /* + * Function: find + */ + find: function(selectors, contextEl){ + if (Util.isNothing(contextEl)){ + contextEl = window.document; + } + var + els = $(selectors, contextEl), + retval = [], + i; + + for (i=0; i newHeight){ - newHeight = Util.DOM.windowHeight; - } - Util.DOM.height(this.el, newHeight); - - } - - }); - - - Code.PhotoSwipe.DocumentOverlayClass.CssClasses = { - documentOverlay: 'ps-document-overlay' - }; - -}) -( - window, - Code.PhotoSwipe.Util -); diff --git a/src/element-class.js b/src/element-class.js deleted file mode 100644 index 3725ec1c5..000000000 --- a/src/element-class.js +++ /dev/null @@ -1,238 +0,0 @@ -// PhotoSwipe - http://www.photoswipe.com/ -// Copyright (c) %%year%% by Code Computerlove (http://www.codecomputerlove.com) -// Licensed under the MIT license -// version: %%version%% - -(function (window, Util) { - - /* - * Class: Code.PhotoSwipe.ElementClass - * Most PhotoSwipe classes inherit from this class - * Provides hooks for fading in and out - */ - Code.PhotoSwipe.ElementClass = SimpleClass.extend({ - - el: null, - settings: null, - isHidden: null, - - fadeInHandler: null, - fadeOutHandler: null, - - - /* - * Function: init - */ - init: function(options){ - - this.settings = { - opacity: 1, - fadeInSpeed: 250, - fadeOutSpeed: 500 - }; - - Util.extend(this.settings, options); - - this.fadeInHandler = this.postFadeIn.bind(this); - this.fadeOutHandler = this.postFadeOut.bind(this); - this.isHidden = true; - - }, - - - - /* - * Function: resetPosition - */ - resetPosition: function(){ - }, - - - - /* - * Function: show - */ - show: function(){ - - this.stopFade(); - - // Show - Util.DOM.setStyle(this.el, 'opacity', this.settings.opacity); - Util.DOM.show(this.el); - - this.postShow(); - - }, - - - - /* - * Function: postShow - * Overide this - */ - postShow: function(){ - - this.isHidden = false; - this.addEventHandlers(); - Util.Events.fire(this, Code.PhotoSwipe.ElementClass.EventTypes.onShow); - - }, - - - - /* - * Function: fadeIn - */ - fadeIn: function(){ - - Util.DOM.setStyle(this.el, 'opacity', 0); - - this.fadeInFromCurrentOpacity(); - - }, - - - - /* - * Function: fadeInFromCurrentOpacity - */ - fadeInFromCurrentOpacity: function(){ - - this.stopFade(); - - this.isHidden = false; - - // Fade in - Util.DOM.show(this.el); - Util.Animation.fadeIn( - this.el, - this.settings.opacity, - this.settings.fadeInSpeed, - this.fadeInHandler - ); - - }, - - - - /* - * Function: postFadeIn - */ - postFadeIn: function(e){ - - if (this.isHidden){ - return; - } - - this.addEventHandlers(); - Util.Events.fire(this, Code.PhotoSwipe.ElementClass.EventTypes.onFadeIn); - - }, - - - - /* - * Function: hide - */ - hide: function(){ - - this.stopFade(); - - Util.DOM.hide(this.el); - - this.postHide(); - - }, - - - /* - * Function: postHide - * Overide this - */ - postHide: function(){ - - this.isHidden = true; - this.removeEventHandlers(); - Util.Events.fire(this, Code.PhotoSwipe.ElementClass.EventTypes.onHide); - - }, - - - /* - * Fuction: fadeOut - */ - fadeOut: function(){ - - this.stopFade(); - - this.isHidden = true; - - Util.Animation.fadeOut(this.el, this.settings.fadeOutSpeed, this.fadeOutHandler); - - }, - - - - - /* - * Function: preFadeOut - */ - postFadeOut: function(e){ - - if (!this.isHidden){ - return; - } - - Util.DOM.hide(this.el); - this.removeEventHandlers(); - - Util.Events.fire(this, Code.PhotoSwipe.ElementClass.EventTypes.onFadeOut); - - }, - - - - /* - * Function: stopFade - */ - stopFade: function(){ - - Util.Animation.stopFade(this.el); - - }, - - - /* - * Function: addEventHandlers - */ - addEventHandlers: function(){ - - }, - - - /* - * Function: removeEventHandlers - */ - removeEventHandlers: function(){ - - } - - - }); - - - - Code.PhotoSwipe.ElementClass.EventTypes = { - onShow: 'PhotoSwipeElementClassOnShow', - onHide: 'PhotoSwipeElementClassOnHide', - onClick: 'PhotoSwipeElementClassOnClick', - onFadeIn: 'PhotoSwipeElementClassOnFadeIn', - onFadeOut: 'PhotoSwipeElementClassOnFadeOut' - }; - - -}) -( - window, - Code.PhotoSwipe.Util -); diff --git a/src/examples/01-default.html b/src/examples/01-default.html new file mode 100644 index 000000000..9e132aef8 --- /dev/null +++ b/src/examples/01-default.html @@ -0,0 +1,83 @@ + + + PhotoSwipe + + + + + + + + + + + + + + + + + +
+ +
+

PhotoSwipe

+
+ + + +
+ + + + + + \ No newline at end of file diff --git a/src/examples/02-jquery.html b/src/examples/02-jquery.html new file mode 100644 index 000000000..9633d370c --- /dev/null +++ b/src/examples/02-jquery.html @@ -0,0 +1,84 @@ + + + PhotoSwipe + + + + + + + + + + + + + + + + + + + +
+ +
+

PhotoSwipe

+
+ + + +
+ + + + + + \ No newline at end of file diff --git a/src/examples/03-multiple-image-sets.html b/src/examples/03-multiple-image-sets.html new file mode 100644 index 000000000..fda669ccb --- /dev/null +++ b/src/examples/03-multiple-image-sets.html @@ -0,0 +1,92 @@ + + + PhotoSwipe + + + + + + + + + + + + + + + + + +
+ +
+

PhotoSwipe

+
+ +

Gallery 1

+ + + +

Gallery 2

+ + +

+ + + + + + \ No newline at end of file diff --git a/src/examples/04-jquery-mobile.html b/src/examples/04-jquery-mobile.html new file mode 100644 index 000000000..442ff5f83 --- /dev/null +++ b/src/examples/04-jquery-mobile.html @@ -0,0 +1,146 @@ + + + PhotoSwipe + + + + + + + + + + + + + + + + + + +
+ +
+

PhotoSwipe

+
+ + +
+ +

These examples show PhotoSwipe integrated with jQuery Mobile:

+ + + +

PhotoSwipe has also been designed to run stand-alone and can be easily integrated into your non jQuery / jQuery mobile websites:

+ + + +
+ +
+

© %%year%% Code Computerlove

+
+ +
+ + + + + + + + \ No newline at end of file diff --git a/src/examples/jquery-mobile-ajax.html b/src/examples/05-jquery-mobile-ajax.html similarity index 50% rename from src/examples/jquery-mobile-ajax.html rename to src/examples/05-jquery-mobile-ajax.html index f21372ee2..92b9f3666 100644 --- a/src/examples/jquery-mobile-ajax.html +++ b/src/examples/05-jquery-mobile-ajax.html @@ -1,52 +1,55 @@ - - - - PhotoSwipe + + + PhotoSwipe - + + - + - - - - - - + + - - - + +
@@ -78,6 +81,5 @@

© %%year%% Code Computerlove

- \ No newline at end of file diff --git a/src/examples/06-events.html b/src/examples/06-events.html new file mode 100644 index 000000000..9eb04992c --- /dev/null +++ b/src/examples/06-events.html @@ -0,0 +1,158 @@ + + + PhotoSwipe + + + + + + + + + + + + + + + + + +
+ +
+

PhotoSwipe

+
+ + + +
+ + + + + + \ No newline at end of file diff --git a/src/examples/07-custom-toolbar.html b/src/examples/07-custom-toolbar.html new file mode 100644 index 000000000..4a8112c8a --- /dev/null +++ b/src/examples/07-custom-toolbar.html @@ -0,0 +1,107 @@ + + + PhotoSwipe + + + + + + + + + + + + + + + + + +
+ +
+

PhotoSwipe

+
+ + + +
+ + + + + + \ No newline at end of file diff --git a/src/examples/08-exclusive-mode.html b/src/examples/08-exclusive-mode.html new file mode 100644 index 000000000..941f9d00c --- /dev/null +++ b/src/examples/08-exclusive-mode.html @@ -0,0 +1,87 @@ + + + PhotoSwipe + + + + + + + + + + + + + + + + + +
+ +
+

PhotoSwipe

+
+ + + +
+ + + + + + \ No newline at end of file diff --git a/src/examples/09-exclusive-mode-no-thumbnails.html b/src/examples/09-exclusive-mode-no-thumbnails.html new file mode 100644 index 000000000..67b596eae --- /dev/null +++ b/src/examples/09-exclusive-mode-no-thumbnails.html @@ -0,0 +1,68 @@ + + + PhotoSwipe + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/examples/advanced-setup.html b/src/examples/advanced-setup.html deleted file mode 100644 index bc459506a..000000000 --- a/src/examples/advanced-setup.html +++ /dev/null @@ -1,182 +0,0 @@ - - - PhotoSwipe - - - - - - - - - - - - - - - - - -
- -
-

PhotoSwipe

-
- - - - - -
- - - diff --git a/src/examples/events.html b/src/examples/events.html deleted file mode 100644 index 5cfc65d1b..000000000 --- a/src/examples/events.html +++ /dev/null @@ -1,243 +0,0 @@ - - - PhotoSwipe - - - - - - - - - - - - - - - - - -
- -
-

PhotoSwipe

-
- - - - - -
- - -