少し前に、何かでブログを徘徊してたらとても良い感じのモーダルウィンドウがあったので調べてみたので。
そしたらフリーで公開されていたので、実装してみました。
モバイルフレンドリーな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
色々チェックして問題が無さそうだったら、メインサイトもこのライブラリを使おうと思います。
ではでは




