2015/05/20
スマホに適したlightbox系javascriptプラグイン「PhotoSwipe」
今回はjavascriptのプラグイン「PhotoSwipe」を紹介します。
こちらはjQueryに依存しません。
久しぶりにjavascriptのプラグインなので、htmlを自分で書かないといけなかったり、
いつもより設定がややこしかったです。
こちらの特徴は、スマホでの写真の操作がSNSや通常の写真アプリのように出来るという点です。
具体的には、
・2本指の操作で写真のピンチ、ズームができる
・横にスワイプで前後の写真に遷移する
・縦にスワイプするとギャラリーを閉じる
・PCでは、ズームボタン、SNSシェア、フルスクリーンの機能がある
が他のプラグインとの違いかと思います。
キャプションをつけることも出来ます。
デモを作成していますので、ご覧ください。
スマホで見るのをオススメします!
PhotoSwipeの使い方
まずはファイルをダウンロードします。
dimsemenov/PhotoSwipe · GitHub
ちなみに、プラグインのサイトは以下になります。
PhotoSwipe: Responsive JavaScript Image Gallery
ダウンロードしたファイルを解凍すると、「dist」というフォルダがあり、基本的にはその中のファイルを使用します。
次に、htmlで関係ファイルを読み込みます。
1 2 3 4 5 | <link type="text/css" href="css/photoswipe.css" rel="stylesheet" media="all" /> <link type="text/css" href="css/default-skin/default-skin.css" rel="stylesheet" media="all" /> <script type="text/javascript" src="js/photoswipe.min.js"></script> <script type="text/javascript" src="js/photoswipe-ui-default.js"></script> |
そして、
javascriptを記述します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | var initPhotoSwipeFromDOM = function(gallerySelector) { var parseThumbnailElements = function(el) { var thumbElements = el.childNodes, numNodes = thumbElements.length, items = [], figureEl, linkEl, size, item; for(var i = 0; i < numNodes; i++) { figureEl = thumbElements[i]; // <figure> element // include only element nodes if(figureEl.nodeType !== 1) { continue; } linkEl = figureEl.children[0]; // <a> element size = linkEl.getAttribute('data-size').split('x'); // create slide object item = { src: linkEl.getAttribute('href'), w: parseInt(size[0], 10), h: parseInt(size[1], 10) }; if(figureEl.children.length > 1) { // <figcaption> content item.title = figureEl.children[1].innerHTML; } if(linkEl.children.length > 0) { // <img> thumbnail element, retrieving thumbnail url item.msrc = linkEl.children[0].getAttribute('src'); } item.el = figureEl; // save link to element for getThumbBoundsFn items.push(item); } return items; }; // find nearest parent element var closest = function closest(el, fn) { return el && ( fn(el) ? el : closest(el.parentNode, fn) ); }; // triggers when user clicks on thumbnail var onThumbnailsClick = function(e) { e = e || window.event; e.preventDefault ? e.preventDefault() : e.returnValue = false; var eTarget = e.target || e.srcElement; // find root element of slide var clickedListItem = closest(eTarget, function(el) { return (el.tagName && el.tagName.toUpperCase() === 'FIGURE'); }); if(!clickedListItem) { return; } // find index of clicked item by looping through all child nodes // alternatively, you may define index via data- attribute var clickedGallery = clickedListItem.parentNode, 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) { // open PhotoSwipe if valid index found openPhotoSwipe( index, clickedGallery ); } return false; }; // parse picture index and gallery index from URL (#&pid=1&gid=2) var photoswipeParseHash = function() { var hash = window.location.hash.substring(1), params = {}; if(hash.length < 5) { 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); } if(!params.hasOwnProperty('pid')) { return params; } params.pid = parseInt(params.pid, 10); return params; }; var openPhotoSwipe = function(index, galleryElement, disableAnimation) { var pswpElement = document.querySelectorAll('.pswp')[0], gallery, options, items; items = parseThumbnailElements(galleryElement); // define options (if needed) options = { index: index, // define gallery index (for URL) galleryUID: galleryElement.getAttribute('data-pswp-uid'), getThumbBoundsFn: function(index) { // See Options -> getThumbBoundsFn section of documentation for more info var thumbnail = items[index].el.getElementsByTagName('img')[0], // find thumbnail pageYScroll = window.pageYOffset || document.documentElement.scrollTop, rect = thumbnail.getBoundingClientRect(); return {x:rect.left, y:rect.top + pageYScroll, w:rect.width}; } }; if(disableAnimation) { options.showAnimationDuration = 0; } // Pass data to PhotoSwipe and initialize it gallery = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items, options); gallery.init(); }; // loop through all gallery elements and bind events 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 > 0 && hashData.gid > 0) { openPhotoSwipe( hashData.pid - 1 , galleryElements[ hashData.gid - 1 ], true ); } }; // execute above function window.onload = function(){ initPhotoSwipeFromDOM(".my-gallery"); } |
こちらは、別ファイルでも、の直前でもいいと思います。
さらに、
プラグイン用のフレームというか、外側の部分のHTMLを記述します。
の直前、自分のhtmlの邪魔にならないような位置に記述してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | <div class="pswp" tabindex="-1" role="dialog" aria-hidden="true"> <div class="pswp__bg"></div> <div class="pswp__scroll-wrap"> <div class="pswp__container"> <div class="pswp__item"></div> <div class="pswp__item"></div> <div class="pswp__item"></div> </div> <div class="pswp__ui pswp__ui--hidden"> <div class="pswp__top-bar"> <div class="pswp__counter"></div> <button class="pswp__button pswp__button--close" title="Close (Esc)"></button> <button class="pswp__button pswp__button--share" title="Share"></button> <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button> <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button> <div class="pswp__preloader"> <div class="pswp__preloader__icn"> <div class="pswp__preloader__cut"> <div class="pswp__preloader__donut"></div> </div> </div> </div> </div> <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap"> <div class="pswp__share-tooltip"></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 class="pswp__caption__center"></div> </div> </div> </div> </div> |
そして、やっと、
ギャラリー部分のhtmlです。
ルールとしては、divのclassは、上述したjavascriptの「.my-gallery」部分と同じ必要があります。
そして、画像部分は、figureタグで囲み、aにdata-sizeを記述します。
1 2 3 4 5 6 7 8 9 | <div class="my-gallery"> <figure><a href="sample01.jpg" data-size="1000x665"><img src="sample01.jpg" alt="" /></a><figcaption>キャプション</figcaption></figure> <figure><a href="sample02.jpg" data-size="1000x678"><img src="sample02.jpg" alt="" /></a></figure> <figure><a href="sample03.jpg" data-size="750x1000"><img src="sample03.jpg" alt="" /></a></figure> <figure><a href="sample06.jpg" data-size="667x1000"><img src="sample06.jpg" alt="" /></a></figure> <figure><a href="sample04.jpg" data-size="1000x667"><img src="sample04.jpg" alt="" /></a></figure> <figure><a href="sample05.jpg" data-size="1000x667"><img src="sample05.jpg" alt="" /></a></figure> <figure><a href="sample07.jpg" data-size="1000x645"><img src="sample07.jpg" alt="" /></a></figure> </div> |
これで完成です!
オプションも用意されています!
ちなみに、ブラウザ・スマホ対応は、
PCだと、Chrome, Firefox, Safari, Opera, IE8以上
Android 2.3.7+ (2.1はテストしていない): デフォルトのbrowser, Chrome, Firefox (最新), Dolphin (最新)
iOS 5+
Windows Phone 7+: デフォルトのbrowser (タッチジェスチャーは8から)
BlackBerry OS 10+: デフォルトのbrowser (古いバージョンはテストしていない)
になります。
Author Profile
スターフィールド編集部
SHARE