我想将视频添加到我的PhotoSwipe图库。
我在这里阅读文档: http://photoswipe.com/documentation/custom-html-in-slides.html
不幸的是,我不知道这意味着什么: "如果你真的需要在PhotoSwipe中拥有视频,你可以将其添加为模态 当用户点击当前幻灯片时,您可以动态创建 DOM中的模态并在.pswp__scroll-wrap元素之后追加它。"
是否有人通过PhotoSwipe成功制作视频?
修改:我已尝试过此操作(最后一张幻灯片是视频):http://pixelkrams.de/2015/artspin适用于桌面设备但在移动设备上中断(视频无法启动且尺寸错误) 。 相关代码:http://pixelkrams.de/js/main.js
PhotoSwipe初始化的片段:
// Pass data to PhotoSwipe and initialize it
gallery = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, dataLarge, options);
gallery.init();
gallery.listen('afterChange', function() {
detectVideo(gallery);
});
gallery.listen('beforeChange', function() {
removeVideo();
});
gallery.listen('resize', function() {
if ($('.videoHolder').length > 0) updateVideoPosition(gallery);
});
gallery.listen('close', function() {
removeVideo();
});
detectVideo(gallery);
以及视频的相关功能:
function removeVideo() {
if ($('.videoHolder').length > 0) {
if ($('#video').length > 0) {
$('video')[0].pause();
$('video')[0].src = "";
$('.videoHolder').remove();
$('.pswp__img').css('visibility','visible');
} else {
$('.videoHolder').remove();
}
}
}
function detectVideo(gallery) {
var src = gallery.currItem.src;
if (src.indexOf('video')>= 0) {
addVideo(gallery.currItem);
updateVideoPosition(gallery);
}
}
function addVideo(item, vp) {
var videofile = item.src.split(".");
var v = $('<div />', {
class:'videoHolder',
css : ({'position': 'absolute','width':item.w, 'height':item.h})
});
v.one('click touchstart', (function() {
var playerCode = '<video id="video" width="'+item.w+'" height="'+item.h+'" autoplay controls>' +
'<source src="'+videofile[0]+'.mp4" type="video/mp4"></source>' +
'<source src="'+videofile[0]+'.webm" type="video/webm"></source>' +
'</video>';
$(this).html(playerCode);
$('.pswp__img').css('visibility','hidden');
}));
v.appendTo('.pswp__scroll-wrap');
}
function updateVideoPosition(o) {
var item = o.currItem;
var vp = o.viewportSize;
var top = (vp.y - item.h)/2;
var left = (vp.x - item.w)/2;
$('.videoHolder').css({position:'absolute',top:top, left:left});
}
答案 0 :(得分:2)
针对移动尺寸问题,我使用了一个额外的功能,可根据gallery.viewportSize和视频宽高比计算视频尺寸。
function setVideoSize(item, vp) {
var w = item.w,
h = item.h,
vw = vp.x,
r,
vh;
if (vw < w) {
r = w/h;
vh = vw/r;
w = vw;
h = vh;
}
return {
w: w,
h: h
};
}
然后将detectVideo()中的addVideo调用更改为
addVideo(gallery.currItem, gallery.viewportSize);
在现有的addVideo(item,vp)函数中使用它
var vsize = setVideoSize(item, vp);
var v = $('<div />', {
class:'.videoHolder',
css : ({'position': 'absolute','width':vsize.w, 'height':vsize.h})
还有updateVideoPosition(o)
var item = o.currItem;
var vp = o.viewportSize;
var vsize = setVideoSize(item, vp);
var top = (vp.y - vsize.h)/2;
var left = (vp.x - vsize.w)/2;
$('.videoHolder').css({position:'absolute',top:top, left:left});
答案 1 :(得分:1)
通过jAlbum PhotoSwipe皮肤,请参阅http://jalbum.net/nl/skins/skin/PhotoSwipe,可以将视频添加到PhotoSwipe图库。要查看它,请打开示例相册:http://andrewolff.jalbum.net/Reestdal_PS/
我使用前2个图像的下一个代码和皮肤代码中的下一个视频:
// build items array
var items = [
{
src: 'slides/151228-112819_Kerststal.jpg',
w: 1625,
h: 1080,
title: 'Vooraan: Maria\'s dorp.'
},
{
src: 'slides/20150703-ch_IMG_2160.jpg',
w: 810,
h: 1080,
title: 'My Cabin!<br>Hey boss, I must\'ve taken a wrong turn, cause I\'m stuck up here!'
},
{
html: '<video controls autoplay style="padding-top: 40px;"><source src="slides/IMG_4979.mp4" type="video/mp4"></video>'
},
答案 2 :(得分:1)
以下是我使用Photoswipe和Youtube&amp; Vimeo视频的解决方案。
这是我在Stackoverflow和网络上看到的java脚本库和解决方案的混合。
<强>花式强>
<link href="photoswipe.css" rel="stylesheet">
<link href="default-skin/default-skin.css" rel="stylesheet">
<style>
.gallery-viewer-play-video-btn-container {
position: relative;
cursor: pointer;
}
.gallery-viewer-play-video-btn-container button {
pointer-events: none;
position: absolute;
outline: 0;
border: none;
background-color: transparent;
padding: 0;
color: inherit;
text-align: inherit;
font-size: 100%;
font-family: inherit;
cursor: pointer;
line-height: inherit;
left: 50%;
top: 50%;
width: 68px;
height: 48px;
margin-left: -34px;
margin-top: -24px;
-moz-transition: opacity .25s cubic-bezier(0.0,0.0,0.2,1);
-webkit-transition: opacity .25s cubic-bezier(0.0,0.0,0.2,1);
transition: opacity .25s cubic-bezier(0.0,0.0,0.2,1);
}
.gallery-viewer-play-video-btn-container .ytp-large-play-button-bg {
-moz-transition: fill .1s cubic-bezier(0.4,0.0,1,1),fill-opacity .1s cubic-bezier(0.4,0.0,1,1);
-webkit-transition: fill .1s cubic-bezier(0.4,0.0,1,1),fill-opacity .1s cubic-bezier(0.4,0.0,1,1);
transition: fill .1s cubic-bezier(0.4,0.0,1,1),fill-opacity .1s cubic-bezier(0.4,0.0,1,1);
fill: #cc181e;
fill-opacity: 1;
}
.YouTubePopUp-Wrap .loading {
display: block;
position: absolute;
top: 50%;
left: 50%;
margin-top: -13px;
margin-left: -36px;
color: #fff;
}
</style>
标记(标准版)
<div class="pswp pswp-chat" tabindex="-1" role="dialog" aria-hidden="true">
<!-- Background of PhotoSwipe.
It's a separate element as animating opacity is faster than rgba(). -->
<div class="pswp__bg"></div>
<!-- Slides wrapper with overflow:hidden. -->
<div class="pswp__scroll-wrap">
<!-- Container that holds slides.
PhotoSwipe keeps only 3 of them in the DOM to save memory.
Don't modify these 3 pswp__item elements, data is added later on. -->
<div class="pswp__container">
<div class="pswp__item"></div>
<div class="pswp__item"></div>
<div class="pswp__item"></div>
</div>
<!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
<div class="pswp__ui pswp__ui--hidden">
<div class="pswp__top-bar">
<!-- Controls are self-explanatory. Order can be changed. -->
<div class="pswp__counter"></div>
<button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
<button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
<button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>
<!-- Preloader demo http://codepen.io/dimsemenov/pen/yyBWoR -->
<!-- element will get class pswp__preloader--active when preloader is running -->
<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>
<强>项
<div class="list">
<div class="element">
<a data-index="0" class="media" href="file58dc530580a94.jpg" target="_blank">
<img src="thumb/file58dc530580a94.jpg" itemprop="thumbnail"/>
</a>
</div>
<div class="element">
<a data-index="1" class="media" href="file58dc530580a94.jpg" target="_blank">
<img src="thumb/file58dc530580a94.jpg" itemprop="thumbnail"/>
</a>
</div>
<div class="element">
<a data-index="2" class="media" href="file58dc530580a94.jpg" target="_blank">
<img src="thumb/file58dc530580a94.jpg" itemprop="thumbnail"/>
</a>
</div>
<div class="element">
<a data-index="3" class="media" href="file58dc530580a94.jpg" target="_blank">
<img src="thumb/file58dc530580a94.jpg" itemprop="thumbnail"/>
</a>
</div>
</div>
<强>脚本强>
<script src="photoswipe.js"></script>
<script src="photoswipe-ui-default.js"></script>
<script src="jquery.min.js"></script>
<script src="jquery-ui.min.js"></script>
<script src="YouTubePopUp.jquery.js"></script>
<script src="custom.js"></script>
YouTubePopUp.jquery.js (这是Qassim Hassan的jQuery插件)。你也需要download它。我在其中进行了一些自定义更改,因此下载后只需将js-code替换为我的。
/*
Name: YouTubePopUp
Description: jQuery plugin to display YouTube or Vimeo video in PopUp, responsive and retina, easy to use.
Version: 1.0.1
Plugin URL: http://wp-time.com/youtube-popup-jquery-plugin/
Written By: Qassim Hassan
Twitter: @QQQHZ
Websites: wp-time.com | qass.im | wp-plugins.in
Dual licensed under the MIT and GPL licenses:
http://www.opensource.org/licenses/mit-license.php
http://www.gnu.org/licenses/gpl.html
Copyright (c) 2016 - Qassim Hassan
Mod by MaximusBaton
*/
(function ( $ ) {
$.fn.YouTubePopUp = function(options) {
var YouTubePopUpOptions = $.extend({
autoplay : 1,
controls : 1,
cc_load_policy : 0,
iv_load_policy : 3,
rel : 0,
showinfo : 0
}, options );
$(this).on('click', function (e) {
var youtubeLink = $(this).attr("href");
if( youtubeLink.match(/(youtube.com)/) ){
var split_c = "v=";
var split_n = 1;
}
if( youtubeLink.match(/(youtu.be)/) || youtubeLink.match(/(vimeo.com\/)+[0-9]/) ){
var split_c = "/";
var split_n = 3;
}
if( youtubeLink.match(/(vimeo.com\/)+[a-zA-Z]/) ){
var split_c = "/";
var split_n = 5;
}
var getYouTubeVideoID = youtubeLink.split(split_c)[split_n];
var cleanVideoID = getYouTubeVideoID.replace(/(&)+(.*)/, "");
if( youtubeLink.match(/(youtu.be)/) || youtubeLink.match(/(youtube.com)/) ){
var videoEmbedLink = "https://www.youtube.com/embed/"+cleanVideoID+"?autoplay="+YouTubePopUpOptions.autoplay+"&controls="+ YouTubePopUpOptions.controls +"&cc_load_policy="+ YouTubePopUpOptions.cc_load_policy +"&iv_load_policy="+ YouTubePopUpOptions.iv_load_policy +"&rel="+ YouTubePopUpOptions.rel +"&showinfo="+ YouTubePopUpOptions.showinfo +"";
}
if( youtubeLink.match(/(vimeo.com\/)+[0-9]/) || youtubeLink.match(/(vimeo.com\/)+[a-zA-Z]/) ){
var videoEmbedLink = "https://player.vimeo.com/video/"+cleanVideoID+"?autoplay="+YouTubePopUpOptions.autoplay+"";
}
$("body").append('<div class="YouTubePopUp-Wrap YouTubePopUp-animation"><div class="YouTubePopUp-Content"><span class="loading">Loading...</span><span class="YouTubePopUp-Close"></span><iframe src="'+videoEmbedLink+'" allowfullscreen></iframe></div></div>');
$('.YouTubePopUp-Content iframe')[0].onload = function() {
$('.YouTubePopUp-Wrap .loading').hide();
$('.YouTubePopUp-Wrap iframe').show();
};
if( $('.YouTubePopUp-Wrap').hasClass('YouTubePopUp-animation') ){
setTimeout(function() {
$('.YouTubePopUp-Wrap').removeClass("YouTubePopUp-animation");
}, 600);
}
$(".YouTubePopUp-Wrap, .YouTubePopUp-Close").click(function(){
$.event.trigger({type : 'youtubeVideoBeforeClose', link : youtubeLink});
$(".YouTubePopUp-Wrap").addClass("YouTubePopUp-Hide").delay(515).queue(function() { $(this).remove(); });
});
$.event.trigger({type : 'youtubeVideoStarted', link : youtubeLink});
e.preventDefault();
});
$(document).keyup(function(e) {
if ( e.keyCode == 27 ){
$('.YouTubePopUp-Wrap, .YouTubePopUp-Close').click();
}
});
};
}( jQuery ));
custom.js (主要的js:)
$(document).ready(function () {
var mediaList = [];
var interval,
intervalTries = 0,
maxIntervalTries = 40;
mediaList.push({
'src' : 'file58dc530580a94.jpg',
'w' : 1726,
'h' : 2506
});
mediaList.push({
'src' : 'file58dae7f57ea15.jpg',
'w' : 4032,
'h' : 3024
});
mediaList.push({
'src' : 'file58daa7b097cc2.jpg',
'w' : 3799,
'h' : 2849
});
mediaList.push({
'src' : 'file58dc530580a94.jpg',
'w' : 1000,
'h' : 667,
'videoSrc' : '//www.youtube.com/watch?v=a_Ypr_uV-mw'
});
var pswpElement = $('.pswp.pswp-chat')[0];
$(document).on("click", ".media", function(e){
e.preventDefault();
var index = $(this).data("index"),
options = {
index : index,
bgOpacity : 0.7,
overlayIcon : true,
showHideOpacity : true
},
gallery = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, mediaList, options);
gallery.init();
gallery.listen('close', function() {
removeVideo(gallery);
});
gallery.listen('beforeChange', function() {
removeVideo(gallery);
});
gallery.listen('afterChange', function() {
detectVideo(gallery.currItem);
});
gallery.listen('resize', function() {
resizeItem(gallery.currItem);
});
gallery.listen('imageLoadComplete', function(index, item) {
resizeItem(gallery.currItem);
});
detectVideo(gallery.currItem);
$(document).off('pswpTap').on('pswpTap', function(e){
var container = $(gallery.currItem.container),
img = container.find('img.youtubeClass');
if (img.length) {
if (typeof(img.data('youtubeVideoStarted')) == 'undefined') {
img.data('youtubeVideoStarted', false);
}
if (img.data('youtubeVideoStarted') === false) {
img.data('youtubeVideoStarted', true);
if (typeof(img.data('youtubeInitialed')) == 'undefined') {
img.data('youtubeInitialed', false);
}
if (img.data('youtubeInitialed') === false) {
img.data('youtubeInitialed', true);
img.YouTubePopUp();
}
if (e.detail.pointerType != 'mouse') {
img.click();
}
}
}
});
$(document).off('youtubeVideoStarted').on('youtubeVideoStarted', function(e){
var container = $(gallery.container),
img = container.find('img.youtubeClass[href="'+ e.link +'"]');
if (img.length) {
container = img.closest('.pswp__item');
if (container.length) {
var buttonContainer = container.find('.gallery-viewer-play-video-btn-container');
img.fadeOut(200);
if (buttonContainer.length) {
buttonContainer.fadeOut(200);
}
}
}
});
$(document).off('youtubeVideoBeforeClose').on('youtubeVideoBeforeClose', function(e){
var container = $(gallery.container),
img = container.find('img.youtubeClass[href="'+ e.link +'"]');
if (img.length) {
container = img.closest('.pswp__item');
if (container.length) {
var buttonContainer = container.find('.gallery-viewer-play-video-btn-container');
img.fadeIn(300);
img.data('youtubeVideoStarted', false);
if (buttonContainer.length) {
buttonContainer.fadeIn(300);
}
}
}
});
});
function resizeItem(item) {
var container = $(item.container),
children = container.children();
if (children.length > 1) {
var newWidth = $(children[ children.length - 1 ]).css('width'),
newHeight = $(children[ children.length - 1 ]).css('height');
children.css({
'width' : newWidth,
'height' : newHeight
});
}
}
function removeVideo(gallery) {
clearVideoInterval();
var container = $(gallery.container),
buttonContainers = container.find('.gallery-viewer-play-video-btn-container');
$.each(buttonContainers, function(){
var $thisButtonContainer = $(this),
container = $thisButtonContainer.closest('.pswp__item');
if (container.length) {
var img = container.find('img:not(.youtubeClass)');
$thisButtonContainer.remove();
if (img.length) {
img.show();
}
}
});
}
function detectVideo(item) {
clearVideoInterval();
if (typeof(item.videoSrc) != 'undefined') {
interval = setInterval(function(){ addVideoIframe(item); }, 100);
}
}
function clearVideoInterval() {
clearInterval(interval);
intervalTries = 0;
}
function addVideoIframe(item) {
if (intervalTries >= maxIntervalTries) {
clearVideoInterval();
return;
}
intervalTries++;
var container = $(item.container),
img = container.find('img:not(.youtubeClass)');
if (img.length) {
resizeItem(item);
var imgSrcCode = '_'+ img.attr('src'),
buttonContainer = container.find('.gallery-viewer-play-video-btn-container');
if (buttonContainer.length == 0) {
buttonContainer = $('<div class="gallery-viewer-play-video-btn-container"><button><svg height="100%" version="1.1" viewBox="0 0 68 48" width="100%"><path class="ytp-large-play-button-bg" d="m .66,37.62 c 0,0 .66,4.70 2.70,6.77 2.58,2.71 5.98,2.63 7.49,2.91 5.43,.52 23.10,.68 23.12,.68 .00,-1.3e-5 14.29,-0.02 23.81,-0.71 1.32,-0.15 4.22,-0.17 6.81,-2.89 2.03,-2.07 2.70,-6.77 2.70,-6.77 0,0 .67,-5.52 .67,-11.04 l 0,-5.17 c 0,-5.52 -0.67,-11.04 -0.67,-11.04 0,0 -0.66,-4.70 -2.70,-6.77 C 62.03,.86 59.13,.84 57.80,.69 48.28,0 34.00,0 34.00,0 33.97,0 19.69,0 10.18,.69 8.85,.84 5.95,.86 3.36,3.58 1.32,5.65 .66,10.35 .66,10.35 c 0,0 -0.55,4.50 -0.66,9.45 l 0,8.36 c .10,4.94 .66,9.45 .66,9.45 z" fill="#1f1f1e" fill-opacity="0.81"></path><path d="m 26.96,13.67 18.37,9.62 -18.37,9.55 -0.00,-19.17 z" fill="#fff"></path><path d="M 45.02,23.46 45.32,23.28 26.96,13.67 43.32,24.34 45.02,23.46 z" fill="#ccc"></path></svg></button></div>');
var clonedImg = img.clone();
clonedImg.attr('href', item.videoSrc)
.addClass('youtubeClass')
.removeClass('pswp__img')
.css({
'width' : '100%',
'height' : '100%'
});
buttonContainer.prepend( clonedImg );
}
buttonContainer.css({
'width' : img.outerWidth() +'px',
'height' : img.outerHeight() +'px'
})
.appendTo(container);
img.hide();
clearVideoInterval();
}
}
});
玩得开心!