Magnific Popup - gallery images not displaying - magnific-popup

I'm trying to use Magnific Popup in collaboration with elevateZoom, I have it working to a point where I have bound a click handler to the zoom container, which in this case is the .product-image-gallery div.
If I pass a single image src, e.g. $j('.product-image-gallery .gallery-image').attr('src'); as the src: argument then I get a popup with an image, but as soon as I pass a more general selector such as the .gallery-image on its own, i get a 'The image could not be loaded' message.
The aim is to have the popup let me cycle through all the avaliable product images.
HTML:
<div class="product-image-gallery">
<img id="image-main" class="gallery-image visible" src="example1.jpg" alt="Title" title="Title" />
<img id="image-0" class="gallery-image" src="example1.jpg" data-zoom-image="example1.jpg" />
<img id="image-1" class="gallery-image" src="example2.jpg" data-zoom-image="example2.jpg" />
<img id="image-2" class="gallery-image" src="example3.jpg" data-zoom-image="example3.jpg" />
</div>
JS ($j because jQuery is in noConflict mode):
$j.magnificPopup.open({
items: {
src: '.gallery-image',
type: 'image',
gallery: {
enabled: true
}
}
});

I ended up building an object then passing that to magnific-popup, my solution:
$j('.product-image-gallery').bind('click', function(){
galleryObj = [];
$j('.product-image-gallery .gallery-image').not('#image-main').each(function() {
var src = $j(this).data('zoom-image'),
type = 'image'; // it's always an image :)
image = {};
image ["src"] = src;
image ["type"] = type;
galleryObj.push(image);
});
// open the popup
$j.magnificPopup.open({
items: galleryObj,
gallery: {
enabled: true
},
});
});

Related

GLightbox and HTML5 videos - how can I set a poster image?

I am using GLightbox in a project I am working on. I have a hyperlink that has a URL to a self-hosted MP4 video. The video is opened in a GLightbox. I have poster images already setup for my videos, but I can't figure out where to set the poster image in the Glightbox setup. Here is my html link that launches the video in the lightbox.
<a href="<?= $video_url; ?>" class="standard-lightbox">
Here is the javascript configuration I have in my site.js file:
let standardLightboxSlideHTML = `<div class="gslide">
<div class="gslide-inner-content">
<div class="ginner-container">
<div class="gslide-media">
</div>
<div class="gslide-description">
<div class="gdesc-inner">
<h4 class="gslide-title"></h4>
<div class="gslide-desc"></div>
</div>
</div>
</div>
</div>
</div>`;
var standardLightbox = GLightbox({
selector: '.standard-lightbox',
width: '1280px',
height: '720px',
skin: 'modern',
closeOnOutsideClick: true,
slideHTML: standardLightboxSlideHTML,
type:'video',
autoplayVideos: false,
plyr: {
config: {
ratio: '16:9', // or '4:3'
muted: false,
hideControls: false,
autoplay: false,
autopause: true,
volume: 0.5,
controls: ['play-large', 'play','progress','volume','mute','fullscreen']
}
}
});
I have tried adding a data-poster value to the hyperlink. That didn't work. That is where I would like to set it and then I want to GLightbox to use it. Any ideas how to make that work?
I want to tag this post as "glightbox", but I don't have enough rep.
I was able to resolve my problem this way.
In wordpress I setup two new fields, one for the url to the video and another for the poster image.
I changed my code to output the url and poster urls in the hyperlink that is clicked.
In my Glightbox setup, I just grab those values and add it dynamically with javascript to the video tag. I also add a counter to the hyperlink so I can append the count value to create an ID selector for the video.
standardLightbox.on('slide_after_load', (data) => {
const { slideIndex, slideNode, slideConfig, player, trigger } = data;
var btnClicked = document.getElementById(trigger.id);
var posterimage = btnClicked.getAttribute('data-html5videoposter');
var videoid = btnClicked.getAttribute('data-videoid');
// use the index
var getVideoTag = document.getElementById(videoid);
getVideoTag.setAttribute('poster', posterimage);
});

How to change slider? Is there possibility to do it in that way?

how can I do 5 photos instead of 3, how to change their size, how to do that they will be change automatically becouse now I have to press play to start?
html:
<script>
$(function () {
// Unstyled Example
$.monte('#example1');
// Styled Buttons Example
// (see the CSS in the above style block)
$.monte('#example2', {auto:false});
// Callback Example
// Format and append the HTML:
$('#example3 > img').each(function(){
$(this)
.wrap('<div style="position:relative"/>')
.parent()
.append('<div><p>' + $(this).attr('alt') + '</p></div>')
.append('<img src="frame.png" alt="" class="frame"/>');
});
// Hide the text on all but the center slide:
$('#example3 div div').css({opacity: 0}).eq(0).css({opacity: 0.8});
// Using the callbacks to reveal and hide the text:
$.monte('#example3', {
auto:false,
callbackIn: function () {
$(this[0]).find('div').animate({opacity: 0.8}, 450);
},
callbackAway: function () {
$(this[0]).find('div').animate({opacity: 0}, 450);
}
});
});
</script>
Here is link to the source where I found it [https://github.com/paizai/monte][1]

Aframe Add Preloader to image loading in sky

I have a scene where I am changing the src for sky using buttons I created "outside the scene". Currently everything works fine but I would like to show a preloader while waiting for the next image to load.
Here you can see my scene: http://scriptstrainer.com/vr_training/
Below I have provided some of my code:
<a-scene>
<a-sky src="images/0-1.jpg" id="img-src">
</a-scene>
<div>
<img src="images/t1.png">
</div>
<div>
<img src="images/t2.png">
</div>
<div>
<img src="images/t3.png">
</div>
<script>
var sky = document.querySelector('#img-src');
var button1 = document.querySelector('#button1');
var button2 = document.querySelector('#button2');
var button3 = document.querySelector('#button3');
button1.addEventListener('click', function() {
sky.setAttribute('src', 'images/0-1.jpg');
});
button2.addEventListener('click', function() {
sky.setAttribute('src', 'images/2.JPG');
});
button3.addEventListener('click', function() {
sky.setAttribute('src', 'images/3.JPG');
});
</script>
Thanks for your assistance...
https://aframe.io/docs/0.4.0/components/material.html#events_materialtextureloaded
There's an event materialtextureloaded you can use to detect when the texture has loaded onto the mesh. In between the time you request to set the texture and the time the texture is set, you can display a loading graphic.
button1.addEventListener('click', function() {
sky.setAttribute('src', 'images/0-1.jpg');
// Display something in the meantime.
sky.addEventListener('materialtextureloaded', function () {
// Small timeout just in case?
setTimeout(function () { // Remove the placeholder. }, 100);
});
});
The loading graphic can be like a spinning object in the scene, a fade-in black mask around the camera (as used in https://github.com/aframevr/360-image-gallery-boilerplate). It depends on what you want it to be.
I had the same scenario where I wanted to add a preloader and only when the image is displayed, to remove the preloader.
I tried using events 'load' and 'loaded' but didn't work as I found out images are not displayed once they finish loading.
Eventually I got help from the AFrame GitHub page and that's how I did it:
<a-assets>
<img id='img-src' src='image.jpg'/>
</a-assets>
<a-sky src='#img-src' id='sky-id'></a-sky>
<script type='text/javascript'>
var skyEl = document.querySelector('#sky-id');
function loaded()
{
var preloader = document.querySelector('#preloader');
preloader.style.display = "none";
}
skyEl.addEventListener('materialtextureloaded', loaded);
</script>

Add/Remove individual widgets from gridster

I'm trying to add and or remove a a widget based on a button click function. It works but once the function is called once it does something odd where the code is called on any mouse click instead of just the button click on the html page. So if I click the remove button on the html page it will remove that widget but then if I click any other widget (not on a button) it still removes that widget. I only want the function called on the html button click, not any mouse click. It's like the button is initializing something on the page to make any mouse click call the remove function. Can anyone explain why this is happening and how I can fix it? My code below:
function deleteWidget() {
var gridster = $('.gridster ul').gridster().data('gridster');
$(document).on( "click", ".gridster ul li", function() {
$(this).addClass("activ");
gridster.remove_widget($('.activ'));
});
}
function addWidget() {
var gridster = $(".gridster ul").gridster().data('gridster');
$(document).on("click", ".gridster ul li", function() {
gridster.add_widget('<li class="gs_w">The HTML of the widget...</li>', 2, 1);
});
}
<li data-row="1" data-col="4" data-sizex="1" data-sizey="1" class="gs_w"><button onclick="addWidget()" style="float: right;">+</button><h3>4</h3><span class="gs-resize-handle gs-resize-handle-both"></span></li>
<li data-row="1" data-col="6" data-sizex="1" data-sizey="1" class="gs_w"><button onclick="deleteWidget()"style="float: right;">-</button><h3>6</h3></li>
Thank you for any help!
When you click on your delete button, your code is creating a bind that makes any click on any widget, run the code to remove it.
$(document).on( "click", ".gridster ul li", function() {
$(this).addClass("activ");
gridster.remove_widget($('.activ'));
});
You can try change your html to:
<li data-row="1" data-col="4" data-sizex="1" data-sizey="1" class="gs_w"><button class="delete-button" style="float: right;">+</button><h3>4</h3><span class="gs-resize-handle gs-resize-handle-both"></span></li>
<li data-row="1" data-col="6" data-sizex="1" data-sizey="1" class="gs_w"><button class="add-button" style="float: right;">-</button><h3>6</h3></li>
and, in your javascript code, after initializing your gridster add:
$(document).on( "click", ".gridster .delete-button", function() {
var gridster = $(".gridster ul").gridster().data('gridster');
gridster.remove_widget($(this).parent());
});
$(document).on("click", ".gridster .add-button", function() {
var gridster = $(".gridster ul").gridster().data('gridster');
gridster.add_widget('<li class="gs_w">The HTML of the widget...</li>', 2, 1);
});
Hope it helps.
Below is the jQuery and HTML required for adding a widget to a gridster grid.
jQuery:
$(document).on( "click", "#addWidgetButton", function(e) {
e.preventDefault();
gridster.add_widget.apply(gridster, ['<li>new</li>', 1, 2]);
});
HTML:
<button id="addWidgetButton" style="float: right;">+</button>

Magnific Popup - Counter in Videogallery

I made a video gallery with magnific popup.
But unlike the imagegallery, the videogallery doesn't show a counter e.g. 1/3 at the bottom right of the video. Why not? In the imagegallery it works well.
Code of the Videogallery:
$('.gallery_video').each(function() { // the containers for all your galleries
$(this).magnificPopup({
delegate: 'a', // the selector for gallery item
disableOn: 700,
type: 'iframe',
mainClass: 'mfp-fade',
removalDelay: 160,
preloader: true,
fixedContentPos: false,
gallery: {
enabled:true
},
callbacks: {
lazyLoad: function(item) {
console.log(item); // Magnific Popup data object that should be loaded
}
}
});
});
Code of imagegallery:
$('.image-popup-no-margins').magnificPopup({
type: 'image',
closeOnContentClick: true,
closeBtnInside: true,
fixedContentPos: true,
mainClass: 'mfp-no-margins mfp-with-zoom', // class to remove default margin from left and right side
image: {
verticalFit: true
},
zoom: {
enabled: true,
duration: 300 // don't foget to change the duration also in CSS
},
callbacks: {
lazyLoad: function(item) {
console.log(item); // Magnific Popup data object that should be loaded
}
}
});
Both scripts don't specify a counter so why isn't it showing up on both?
thank you
It has been a time ago when this was asked but a full anwser:
You have to add or specify the iframe markup.
You also want to add some small css updates for positioning the counter.
var $attachmentContainers = $('.js-attachments-in-gallery');
$attachmentContainers.magnificPopup({
delegate: 'a',
type: 'image',
gallery:{
enabled:true,
},
iframe: {
markup:
'<div class="mfp-iframe-scaler">'+
'<div class="mfp-close"></div>'+
'<iframe class="mfp-iframe" frameborder="0" allowfullscreen></iframe>'+
'<div class="mfp-bottom-bar">'+
'<div class="mfp-counter"></div>'+
'</div>'+
'</div>'
}
});
.mfp-iframe-scaler .mfp-bottom-bar {
margin-top: 4px; }
Figured it out - for the iframe type you have to specify that you want a counter:
$(this).magnificPopup({
.....
iframe: {
markup: '<button title="Close (Esc)" type="button" class="mfp-close">×</button>'+
'<div class="mfp-counter"></div>'
}