少し前に、何かでブログを徘徊してたらとても良い感じのモーダルウィンドウがあったので調べてみたので。
そしたらフリーで公開されていたので、実装してみました。
モバイルフレンドリーなPhotoSwipeをwordpressで実装する
このPhotoSwipeというライブラリは、スマホのスワイプに対応していて、動きもGOOD。
PCので表示では全画面や、拡大ボタンも付く。
(このブログでは全画面表示は切ってます)
動作は下の画像をクリックでどんぞ。
実装編
さて実装ですが、wordpress用のプラグインもあったのですが、過去の記事だと動かなかった。
エラーが起こってた様子も無かったからそーゆー設定だと思うのですが、どうせならイージーに過去の記事まで対応させたいと思うのが人のサガ。
なので、実装用のコードは自分で書きます。
if ( is_singular() ){ wp_enqueue_style( 'photoswipe-style', get_stylesheet_directory_uri() . '/library/photo-swipe/photoswipe.min.css', array(), '1.0.0' ); wp_enqueue_style( 'psdefault-style', get_stylesheet_directory_uri() . '/library/photo-swipe/default-skin/default-skin.min.css', array(), '1.0.0' ); } if ( is_singular() ){ wp_enqueue_script( 'photoswipe-js', get_stylesheet_directory_uri() . '/library/photo-swipe/photoswipe.min.js', array(), '1.0.0', true ); wp_enqueue_script( 'photoswipeui-js', get_stylesheet_directory_uri() . '/library/photo-swipe/photoswipe-ui-default.min.js', array(), '1.0.0', true ); }
まずはライブラリの読み込み。
上はシングルページのみでの読み込みです。
jsとcssを分けてますが、一緒でも当然大丈夫。
この時点で意味が分からなければ、プラグインで良いと思う。
上ではテーマフォルダにlibrarディレクトリを作って、そこに入れてます。
そんで次は、発火用のデータを記事に差し込みます。
function PhotoSwipe_fanc( $content ) { $pattern = "/(<a[^>]*?href=['\"][^'\"]+?\.(?:bmp|gif|jpg|jpeg|png)(\?\S{0,}){0,1}['\"][^\>]*)>/i"; $replacement = '$1 class="photo-swipe">'; $content = preg_replace($pattern, $replacement, $content); if ( ! preg_match_all( '/<img [^>]+>/', $content, $matches ) ) { return $content; } $selected_images = $attachment_ids = array(); foreach( $matches[0] as $image ) { if ( preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) && ( $attachment_id = absint( $class_id[1] ) ) ) { $selected_images[ $image ] = $attachment_id; $attachment_ids[ $attachment_id ] = true; } } if ( count( $attachment_ids ) > 1 ) { update_meta_cache( 'post', array_keys( $attachment_ids ) ); } foreach ( $selected_images as $image => $attachment_id ) { $content = str_replace( $image, PhotoSwipe_fanc_set( $image, $attachment_id ), $content ); } return $content; } add_filter('the_content', 'PhotoSwipe_fanc'); function PhotoSwipe_fanc_set( $image, $attachment_id ){ $image_src_full = wp_get_attachment_image_src( $attachment_id,'full' ); if($image_src_full){ $attr = 'data-size="'.$image_src_full[1].'x'.$image_src_full[2].'"'; $image = preg_replace( '/<img ([^>]+?)[\/ ]*>/', '<img $1' . $attr . ' />', $image ); } return $image; }
function.phpでthe_contentにフック。
上ではsrcsetを吐き出すコードを真似てdata属性にfullサイズ画像の大きさを渡します。
あと、発火用のclassも。
別にclassはなくても出来るんだけど、あったほうが何かと使えるかな?・・・と思って挿入。
次はjquery。
if( $('a.photo-swipe')[0] ){ $('<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>').appendTo('body'); $('a.photo-swipe img:not("[data-size]")').each(function(){ var eleme = $(this); var img = new Image(); img.src = eleme.parent().attr('href'); img.onload = function() { var imgw = img.width; var imgh = img.height; eleme.attr('data-size',imgw + 'x' +imgh ); } }); var PhotoSwipe = window.PhotoSwipe, PhotoSwipeUI_Default = window.PhotoSwipeUI_Default; $('body').on('click', 'a.photo-swipe:has("[data-size]")', function(e) { if( !PhotoSwipe || !PhotoSwipeUI_Default ) { return; } e.preventDefault(); openPhotoSwipe( this ); }); var parseThumbnailElements = function(gallery, el) { var elements = $(gallery).find('a.photo-swipe:has("[data-size]")').has('img'), galleryItems = [], index; elements.each(function(i) { var $el = $(this), size = $('img',$el).data('size').split('x'), caption; if( $el.next().is('.wp-caption-text') ) { // image with caption caption = $el.next().text(); } else if( $el.parent().next().is('.wp-caption-text') ) { // gallery icon with caption caption = $el.parent().next().text(); } else { caption = $el.find('img').attr('alt'); } galleryItems.push({ src: $el.attr('href'), w: parseInt(size[0], 10), h: parseInt(size[1], 10), title: caption, msrc: $el.find('img').attr('src'), el: $el }); if( el === $el.get(0) ) { index = i; } }); return [galleryItems, parseInt(index, 10)]; }; var openPhotoSwipe = function( element, disableAnimation ) { var pswpElement = $('.pswp').get(0), galleryElement = $(element).parents('.gallery, .hentry, .main, body').first(), gallery, options, items, index; items = parseThumbnailElements(galleryElement, element); index = items[1]; items = items[0]; options = { index: index, fullscreenEl: false, getThumbBoundsFn: function(index) { var image = items[index].el.find('img'), offset = image.offset(); return {x:offset.left, y:offset.top, w:image.width()}; }, }; if(disableAnimation) { options.showAnimationDuration = 0; } gallery = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items, options); gallery.init(); };
これはプラグインで公開されていたコードを使って、少し仕様を変えています。
まずphoto-swipeのclassが無ければ何も起きない。
attachment_idで画像のサイズが読み取れない場合、ブラウザにロードさせてリンク画像の大きさを取得してしまいます。
強制的にロードさせちゃうから、巨大な画像があると重くなるかも知れない。
普通にWP使ってればあまりない事だと思うんだけど...。
attachment_idで画像サイズが取れないケースは、XMLとかで引っ越しして、現在のWP上に画像ファイルが無い とか、データベースに入ってない状態とか。
あと、外部URLの場合はattachment_idが無いからブラウザにロードさせるしか無い。
phpでやる方法もあるけど、jqueryで良いかな? と思ってやってみました。
まとめ
今までは自分で作ったモーダルウィンドウを使ってましたが、PhotoSwipeの完成度が高いので変えてみたワケです。
いずれ自分でスワイプ対応版を作ろうと思っていたのですが、サラリー化で時間の余裕が無くなったので丁度良いタイミングでした。
動きもスムーズだし、ピンチも問題無し。
PCではズームボタンもあるから、僕のやりたかった条件は満たされてしまいました。
たまに徘徊してみると良いライブラリと出会えるもんですね。
作者様には感謝です。
本家サイトはコチラ>> PhotoSwipe
色々チェックして問題が無さそうだったら、メインサイトもこのライブラリを使おうと思います。
ではでは