PhotoSwipe Repository
Build Status devDependency Status Flattr
JavaScript image gallery for mobile and desktop.
Documentation and getting started guide.
Demo and script home page.
NPM npm install photoswipe.
Bower bower install photoswipe.
Location of files
Compiled PhotoSwipe JS and CSS files, SVG and PNG sprites are in the dist/ folder.
Source files (.JS and .SCSS) are in the src/ folder. Note that PhotoSwipe uses Autoprefixer when compiling SASS files.
Demo website is in the website/ folder.
Documentation markdown files are in website/documentation/.
Plugins / extensions / addons
Ruby gem.
Ember.js addon.
Eager app.
Koken CMS plugin.
Orchard CMS module.
Yellow CMS plugin.
Coded something useful? Email me and I’ll post a link to it here.
Build
To compile PhotoSwipe by yourself, make sure that you have Node.js, Grunt.js, Ruby and Jekyll installed, then:
1) Clone the repository
git clone https://github.com/dimsemenov/PhotoSwipe.git
2) Go inside the PhotoSwipe folder that you fetched and install Node dependencies
cd PhotoSwipe && npm install
3) Run grunt to generate the JS and CSS files in the dist folder and the site in the _site/ folder
grunt
Optionally:
Run grunt watch to automatically rebuild files (JS, CSS, demo website and documentation) when you change files in src/ or in website/.
Run grunt nosite to build just JS and CSS files (output is folder dist/).
Run grunt pswpbuild to build just JS files. Param –pswp-exclude allows to exclude modules, for example grunt pswpbuild –pswp-exclude=history will exclude history module.
Using PhotoSwipe?
If you’ve used PhotoSwipe in some interesting way, or on the site of a popular brand, I’d be very grateful if you shoot me a link to it.
License
Script is licensed under MIT license with one exception: Do not create a public WordPress plugin based on it, as I will develop it. If you need to use it for a public WordPress plugin right now, please ask me by email first. Thanks!
Attribution is not required, but much appreciated, especially if you’re making a product for developers.
About
PhotoSwipe 4.0+ is developed by Dmitry Semenov. But initially script was created in 2011 by Code Computerlove, a digital agency in Manchester, they passed on development in March 2014. You can view source and documentation of old PhotoSwipe (<4.0) in history of this repo.
EG:
javascript and css:
<link href=”dist/photoswipe.css” rel=”stylesheet” />
<link href=”dist/default-skin/default-skin.css” rel=”stylesheet” />
<script src=”dist/photoswipe.min.js”></script>
<script src=”dist/photoswipe-ui-default.min.js”></script>
html:
<div id=”demo-test-gallery” class=”demo-gallery”>
<a class=”demo-gallery__img–main” href=”https://farm4.staticflickr.com/3894/15008518202_c265dfa55f_h.jpg” data-size=”1600×1600″ data-med=”https://farm4.staticflickr.com/3894/15008518202_b016d7d289_b.jpg” data-med-size=”1024×1024″ data-author=”Folkert Gorter”>
<img src=”https://farm4.staticflickr.com/3894/15008518202_b016d7d289_m.jpg” alt=”” />
</a>
<a href=”https://farm6.staticflickr.com/5591/15008867125_b61960af01_h.jpg” data-size=”1600×1068″ data-med=”https://farm6.staticflickr.com/5591/15008867125_68a8ed88cc_b.jpg” data-med-size=”1024×683″ data-author=”Samuel Rohl”>
<img src=”https://farm6.staticflickr.com/5591/15008867125_68a8ed88cc_m.jpg” alt=”” />
</a>
<a href=”https://farm4.staticflickr.com/3902/14985871946_24f47d4b53_h.jpg” data-size=”1600×1067″ data-med=”https://farm4.staticflickr.com/3902/14985871946_86abb8c56f_b.jpg” data-med-size=”1024×683″ data-author=”Ales Krivec”>
<img src=”https://farm4.staticflickr.com/3902/14985871946_86abb8c56f_m.jpg” alt=”” />
</a>
<a href=”https://farm6.staticflickr.com/5584/14985868676_b51baa4071_h.jpg” data-size=”1600×1067″ data-med=”https://farm6.staticflickr.com/5584/14985868676_4b802b932a_b.jpg” data-med-size=”1024×683″ data-author=”Michael Hull”>
<img src=”https://farm6.staticflickr.com/5584/14985868676_4b802b932a_m.jpg” alt=”” />
</a>
<a href=”https://farm4.staticflickr.com/3920/15008465772_d50c8f0531_h.jpg” data-size=”1600×1067″ data-med=”https://farm4.staticflickr.com/3920/15008465772_383e697089_b.jpg” data-med-size=”1024×683″ data-author=”Thomas Lefebvre”>
<img src=”https://farm4.staticflickr.com/3920/15008465772_383e697089_m.jpg” alt=”” />
</a>
</div>
<div id=”gallery” class=”pswp” tabindex=”-1″>
<div class=”pswp__bg”></div>
<div class=”pswp__scroll-wrap”>
<div class=”pswp__container”></div>
<div class=”pswp__ui pswp__ui–hidden”>
<div class=”pswp__top-bar”></div>
<!–
<div class=”pswp__loading-indicator”>
<div class=”pswp__loading-indicator__line”></div>
</div>
–>
<div class=”pswp__share-modal pswp__share-modal–hidden pswp__single-tap”>
<div class=”pswp__share-tooltip”><!– <a href=”#” class=”pswp__share–facebook”></a>
<a href=”#” class=”pswp__share–twitter”></a>
<a href=”#” class=”pswp__share–pinterest”></a>
<a href=”#” download class=”pswp__share–download”></a> –></div>
</div>
<button class=”pswp__button pswp__button–arrow–left” title=”Previous (arrow left)”></button>
<button class=”pswp__button pswp__button–arrow–right” title=”Next (arrow right)”></button>
<div class=”pswp__caption”></div>
</div>
</div>
</div>
javascript:
<script type=”text/javascript”>// <![CDATA[
(function() {
var initPhotoSwipeFromDOM = function(gallerySelector) {
var parseThumbnailElements = function(el) {
var thumbElements = el.childNodes,
numNodes = thumbElements.length,
items = [],
el,
childElements,
thumbnailEl,
size,
item;
for(var i = 0; i < numNodes; i++) { el = thumbElements[i]; // include only element nodes if(el.nodeType !== 1) { continue; } childElements = el.children; size = el.getAttribute(‘data-size’).split(‘x’); // create slide object item = { src: el.getAttribute(‘href’), w: parseInt(size[0], 10), h: parseInt(size[1], 10), author: el.getAttribute(‘data-author’) }; item.el = el; // save link to element for getThumbBoundsFn if(childElements.length > 0) {
item.msrc = childElements[0].getAttribute(‘src’); // thumbnail url
if(childElements.length > 1) {
item.title = childElements[1].innerHTML; // caption (contents of figure)
}
}
var mediumSrc = el.getAttribute(‘data-med’);
if(mediumSrc) {
size = el.getAttribute(‘data-med-size’).split(‘x’);
// “medium-sized” image
item.m = {
src: mediumSrc,
w: parseInt(size[0], 10),
h: parseInt(size[1], 10)
};
}
// original image
item.o = {
src: item.src,
w: item.w,
h: item.h
};
items.push(item);
}
return items;
};
// find nearest parent element
var closest = function closest(el, fn) {
return el && ( fn(el) ? el : closest(el.parentNode, fn) );
};
var onThumbnailsClick = function(e) {
e = e || window.event;
e.preventDefault ? e.preventDefault() : e.returnValue = false;
var eTarget = e.target || e.srcElement;
var clickedListItem = closest(eTarget, function(el) {
return el.tagName === ‘A’;
});
if(!clickedListItem) {
return;
}
var clickedGallery = clickedListItem.parentNode;
var childNodes = clickedListItem.parentNode.childNodes,
numChildNodes = childNodes.length,
nodeIndex = 0,
index;
for (var i = 0; i < numChildNodes; i++) { if(childNodes[i].nodeType !== 1) { continue; } if(childNodes[i] === clickedListItem) { index = nodeIndex; break; } nodeIndex++; } if(index >= 0) {
openPhotoSwipe( index, clickedGallery );
}
return false;
};
var photoswipeParseHash = function() {
var hash = window.location.hash.substring(1),
params = {};
if(hash.length < 5) { // pid=1
return params;
}
var vars = hash.split(‘&’);
for (var i = 0; i < vars.length; i++) {
if(!vars[i]) {
continue;
}
var pair = vars[i].split(‘=’);
if(pair.length < 2) { continue; } params[pair[0]] = pair[1]; } if(params.gid) { params.gid = parseInt(params.gid, 10); } return params; }; var openPhotoSwipe = function(index, galleryElement, disableAnimation, fromURL) { var pswpElement = document.querySelectorAll(‘.pswp’)[0], gallery, options, items; items = parseThumbnailElements(galleryElement); // define options (if needed) options = { galleryUID: galleryElement.getAttribute(‘data-pswp-uid’), getThumbBoundsFn: function(index) { // See Options->getThumbBoundsFn section of docs for more info
var thumbnail = items[index].el.children[0],
pageYScroll = window.pageYOffset || document.documentElement.scrollTop,
rect = thumbnail.getBoundingClientRect();
return {x:rect.left, y:rect.top + pageYScroll, w:rect.width};
},
addCaptionHTMLFn: function(item, captionEl, isFake) {
if(!item.title) {
captionEl.children[0].innerText = ”;
return false;
}
captionEl.children[0].innerHTML = item.title + ‘
<small>Photo: ‘ + item.author + ‘</small>’;
return true;
}
};
if(fromURL) {
if(options.galleryPIDs) {
// parse real index when custom PIDs are used
// http://photoswipe.com/documentation/faq.html#custom-pid-in-url
for(var j = 0; j < items.length; j++) {
if(items[j].pid == index) {
options.index = j;
break;
}
}
} else {
options.index = parseInt(index, 10) – 1;
}
} else {
options.index = parseInt(index, 10);
}
// exit if index not found
if( isNaN(options.index) ) {
return;
}
var radios = document.getElementsByName(‘gallery-style’);
for (var i = 0, length = radios.length; i < length; i++) { if (radios[i].checked) { if(radios[i].id == ‘radio-all-controls’) { } else if(radios[i].id == ‘radio-minimal-black’) { options.mainClass = ‘pswp–minimal–dark’; options.barsSize = {top:0,bottom:0}; options.captionEl = false; options.fullscreenEl = false; options.shareEl = false; options.bgOpacity = 0.85; options.tapToClose = true; options.tapToToggleControls = false; } break; } } if(disableAnimation) { options.showAnimationDuration = 0; } // Pass data to PhotoSwipe and initialize it gallery = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items, options); // see: http://photoswipe.com/documentation/responsive-images.html var realViewportWidth, useLargeImages = false, firstResize = true, imageSrcWillChange; gallery.listen(‘beforeResize’, function() { var dpiRatio = window.devicePixelRatio ? window.devicePixelRatio : 1; dpiRatio = Math.min(dpiRatio, 2.5); realViewportWidth = gallery.viewportSize.x * dpiRatio; if(realViewportWidth >= 1200 || (!gallery.likelyTouchDevice && realViewportWidth > 800) || screen.width > 1200 ) {
if(!useLargeImages) {
useLargeImages = true;
imageSrcWillChange = true;
}
} else {
if(useLargeImages) {
useLargeImages = false;
imageSrcWillChange = true;
}
}
if(imageSrcWillChange && !firstResize) {
gallery.invalidateCurrItems();
}
if(firstResize) {
firstResize = false;
}
imageSrcWillChange = false;
});
gallery.listen(‘gettingData’, function(index, item) {
if( useLargeImages ) {
item.src = item.o.src;
item.w = item.o.w;
item.h = item.o.h;
} else {
item.src = item.m.src;
item.w = item.m.w;
item.h = item.m.h;
}
});
gallery.init();
};
// select all gallery elements
var galleryElements = document.querySelectorAll( gallerySelector );
for(var i = 0, l = galleryElements.length; i < l; i++) {
galleryElements[i].setAttribute(‘data-pswp-uid’, i+1);
galleryElements[i].onclick = onThumbnailsClick;
}
// Parse URL and open gallery if it contains #&pid=3&gid=1
var hashData = photoswipeParseHash();
if(hashData.pid && hashData.gid) {
openPhotoSwipe( hashData.pid, galleryElements[ hashData.gid – 1 ], true, true );
}
};
initPhotoSwipeFromDOM(‘.demo-gallery’);
})();
// ]]></script>
近期评论