Closed acwolff closed 3 years ago
You can do something like:
const lightbox = new PhotoSwipeLightbox({
// ...
});
lightbox.on('itemData', (e) => {
const element = e.itemData.element;
if (element && element.dataset.pswpIsVideo) {
const videoURL = element.href;
e.itemData = {
html: `<video controls><source src="${videoURL}" type="video/mp4"> </video>`
};
}
});
lightbox.init();
<div id="gallery">
<a href="slides/IMG_0877.mp4" data-pswp-is-video="true">
<img src="slides/IMG_0877.jpg" alt="video" />
</a>
</a>
There might be a plugin for video in future.
@dimsemenov - this looks good - however I wonder how one should adjust the wrapper that gets created around the itemData.html
that's provided? The pswp__zoom-wrap
element that's created has inline styles and it'd be nice to adjust the transform3d
value to center the video.
@mallardduck If html
slide is used, pswp__zoom-wrap
should only have styles that stretch it to 100% width/height It isn't for you?
Custom HTML within a slide should be centered and scaled manually via CSS or JS - up to you.
Cool - good to know that makes enough sense.
@dimsemenov thanks for providing example video code.
Your example works at my place as you can see in my test album.
Thanks for your help!
For mobile devices it was rquired to add a poster image, so I adapted the code:
<div id="gallery">
<a href="slides/IMG_0877.mp4" data-pswp-is-video="true" data-pswp-is-poster="slides/IMG_0205.jpg" >
<img src="slides/IMG_0877.jpg" alt="video" />
</a>
</a>
lightbox.on('change', () => {
showZoomBtn(lightbox.pswp.currSlide.isZoomable());
});
lightbox.on('itemData', (e) => {
const element = e.itemData.element;
if (element && element.dataset.pswpIsVideo) {
const videoURL = element.href;
const imgPoster= element.dataset.pswpIsPoster;
e.itemData = {
html: `<video controls poster="${imgPoster}"><source src="${videoURL}" type="video/mp4"> </video>`
};
}
});
lightbox.init();
As you see I hide the zoom button for videos.
I use now the following CSS code for a video:
video {
position: relative;
top: 50%;
transform: translateY(-50%);
height: 100%;
}
You see the reslut in my video test album.
I added too support for YouTube and Vimeo videos and weblocations:
<div id="gallery">
<a href="slides/IMG_0877.mp4" data-pswp-is-video="true" data-pswp-is-poster="slides/IMG_0205.jpg" >
<img src="slides/IMG_0877.jpg" class="video" />
</a>
<a href="https://www.youtube.com/embed/QbULyApj9Sw" data-pswp-is-webloc="true" >
<img src="slides/www.youtube.com-178.jpg" class="video" />
</a>
<a href="https://www.andrewolff.nl/SkinsManual/" data-pswp-is-webloc="true" >
<img src="thumbs/www.andrewolff.nl-780.jpg" />
</a>
</div>
lightbox.on('itemData', (e) => {
const element = e.itemData.element;
if (element && element.dataset.pswpIsVideo) {
const videoURL = element.href;
const imgPoster= element.dataset.pswpIsPoster;
e.itemData = {
html: `<video controls poster="${imgPoster}"><source src="${videoURL}" type="video/mp4"> </video>`
};
}
else if (element && element.dataset.pswpIsWebloc) {
const weblocURL = element.href;
e.itemData = {
html: `<iframe frameborder="0" style=border:"0" src="${weblocURL}" height="100%" width="100%"> </iframe>`
};
}
You see the reslut in my video test album.
@acwolff / @dimsemenov - do either of you have an idea on how to combine this technique for videos with the dynamic generation via API? I have an api based gallery working but only for images not videos.
I have to use XMLHttpRequest
with a synchronous request as I found async requests didn't work. I parse the JSON the API provides then assign the following things for an image:
itemData.msrc = '{{ asset('placeholder.png') }}';
itemData.src = parsed.data.src;
itemData.w = parsed.data.w;
itemData.h = parsed.data.h;
While these techniques for video seemed to work for when the info is embedded into the clicked element. It seems like using the html
attribute in that context doesn't work. I just opted to add an if/else to check for the value of an is_video
property the API exposes.
UPDATE: Sorry - after some further testing I needed to correct my logic around testing the video status. I wasn't properly setting the html attribute for those cases. Once that was things work as expected.
@mallardduck Not sure if I fully understand your question. There is no option to have both video (or any HTML) and zoomable image at the same time on the same slide. At least for now.
To add a video to the slide - all you have to do is define itemData.html
with your video markup. If your data is asynchronous, you may set it to some placeholder HTML and then replace it once the data is loaded.
With the previous version I could implement video with the html code:
This worked OK, to see it click on the first thumbnail of this album.
I try now to port this to PhotoSwipe 5, but not in n array but in html code:
This does not work, see this test
So I have three questions: