我想把视频添加到我的PhotoSwipe画廊。
我在这里阅读了文档:http://photoswipe.com/documentation/custom-html-in-slides.html
不幸的是,我不明白这意味着什么:“如果您真的需要在PhotoSwipe中使用视频,您可以将它添加为用户在当前幻灯片上点击时出现的模式,您可以在DOM中动态创建模型,并在..pswp_scroll元素之后追加它。”
是否有人成功地用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});
}发布于 2016-06-03 10:48:26
对于移动大小问题,我使用了一个额外的函数来计算基于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()中的detectVideo调用更改为
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});发布于 2017-05-17 17:07:38
这里是我的解决方案,在Youtube和Vimeo视频中使用Photoswipe。
它是java脚本库和解决方案的混合体,我在Stackoverflow和web上都看到了这些。
风格
<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 (这是卡西姆·哈桑的jQuery插件)。您也需要下载它。我在其中做了一些自定义的更改,所以下载后只需用我的js-代码替换。
/*
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();
}
}
});玩得开心!
发布于 2016-03-01 21:24:12
通过jAlbum PhotoSwipe皮肤,请参阅http://jalbum.net/nl/skins/skin/PhotoSwipe,可以向PhotoSwipe图库添加视频。要查看它,请打开示例相册: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>'
},https://stackoverflow.com/questions/32770979
复制相似问题