Lightbox with Swiper JS - swiper.js

I'm building a page where I'm using ACF Flexible Content to add a Swiper Slider.
Slider is built so far, but now I want to have a lightbox function in the slider.
For this I have the approach to duplicate the slider once (with one slide per view, instead of three slides per view). So far so good:
Now I want to click on e.g. a zoom icon on the second slider to get to the slide that was clicked on.
For this I have an ActiveIndex function, but I don't know exactly how to give the second slider the index of the first slider...
I have sketched this roughly in a pen:
https://codepen.io/webkonditorei/pen/JjLjRQW?fbclid=IwAR2NZWpzx30gqVWVDPdOkRVrTdMC637dLNPYvakUruFYOjr6auYaJw6L9tY
Or here the code:
<link
rel="stylesheet"
href="https://unpkg.com/swiper#8/swiper-bundle.min.css"
/>
<script src="https://unpkg.com/swiper#8/swiper-bundle.min.js"></script>
<div class="swiper-container swiper1">
<div class="swiper-wrapper">
<div class="swiper-slide"><p onclick="umswipen()">Slide 1</p></div>
<div class="swiper-slide"><p onclick="umswipen()">Slide 2</p></div>
<div class="swiper-slide"><p onclick="umswipen()">Slide 3</p></div>
<div class="swiper-slide"><p onclick="umswipen()">Slide 4</p></div>
<div class="swiper-slide"><p onclick="umswipen()">Slide 5</p></div>
<div class="swiper-slide"><p onclick="umswipen()">Slide 6</p></div>
<div class="swiper-slide"><p onclick="umswipen()">Slide 7</p></div>
<div class="swiper-slide"><p onclick="umswipen()">Slide 8</p></div>
<div class="swiper-slide"><p onclick="umswipen()">Slide 9</p></div>
<div class="swiper-slide"><p onclick="umswipen()">Slide 10</p></div>
</div>
<!-- Add Pagination -->
<div class="swiper-pagination swiper-pagination1"></div>
<div class="swiper-button-prev swiper-button-prev1"></div>
<div class="swiper-button-next swiper-button-next1"></div>
</div>
<!-- Swiper -->
<div class="swiper-container swiper2">
<div class="swiper-wrapper">
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
<div class="swiper-slide">Slide 4</div>
<div class="swiper-slide">Slide 5</div>
<div class="swiper-slide">Slide 6</div>
<div class="swiper-slide">Slide 7</div>
<div class="swiper-slide">Slide 8</div>
<div class="swiper-slide">Slide 9</div>
<div class="swiper-slide">Slide 10</div>
</div>
<!-- Add Pagination -->
<div class="swiper-pagination swiper-pagination2"></div>
</div>
<style>
body {
max-width: 1000px;
overflow: hidden;
margin: 0px auto;
}
.swiper-container {
width: 100%;
}
.swiper-slide {
text-align: center;
padding: 50px;
background: #f4f4f4;
margin-top: 25px;
}
.sliderContainer {
max-width: 500px;
}
.swiper-button-prev, .swiper-button-next {
position: absolute;
}
p {
cursor: pointer;
}
</style>
<script>
<!-- Initialize Swiper -->
var swiper1 = new Swiper('.swiper1', {
slidesPerView: 3,
spaceBetween: 10,
pagination: '.swiper-pagination1',
paginationClickable: true,
navigation: {
nextEl: '.swiper-button-next1',
prevEl: '.swiper-button-prev1',
},
});
var swiper2 = new Swiper('.swiper2', {
slidesPerView: 1,
spaceBetween: 10,
pagination: '.swiper-pagination2',
paginationClickable: true,
navigation: {
nextEl: '.swiper-button-next2',
prevEl: '.swiper-button-prev2',
},
});
<!-- Get SlideIndex -->
function geSlideDataIndex(mainSlider){
var mainSlider = document.querySelector('swiper1');
var activeIndex = mainSlider.activeIndex;
var slidesLen = mainSlider.slides.length;
if(mainSlider.params.loop){
switch(mainSlider.activeIndex){
case 0:
activeIndex = slidesLen-3;
break;
case slidesLen-1:
activeIndex = 0;
break;
default:
--activeIndex;
}
}
return activeIndex;
}
<!-- Scroll Second Slider to current Slide of first Slider on Click -->
function umswipen(activeIndex) {
swiper2.slideTo(activeIndex);
}
</script>
Here the second slider (which should be the lightbox) is of course visible, which it really should not be, but is just about the basic function
Ideas for an approach? 🙂

I think you are looking for some think lake: LightGallery.
This package can help you.

Related

I'm trying to convert from pure html code to Vuejs but it's not working

This is the logic algorithm I'm converting and it's not working.
Popup.vue
<script>
import '../../assets/style.css'
export default {
data(){
return{
ceos: [{name_ceo:"Mr. A",
position_ceo:"CEO-GOSTREAM",
content:"Lorem."},
{name_ceo:"Mr. B",
position_ceo:"CTO-GOSTREAM",
content:"Lorem2."},
{name_ceo:"Mr. C",
position_ceo:"CGO-GOSTREAM",
content:"Lorem3."},
]
}
},
methods:{
modalCeo(i){
var modal = this.$refs.modal;
modal[0].style.display="flex";
ceos.forEach(element => {
name_ceo1.innerHTML=ceos[i].name_ceo;
position.innerHTML=ceos[i].position_ceo;
content.innerHTML=ceos[i].content;
});
},
closemodal(){
var modal = this.$refs.modal;
modal[0].style.display="none";
}
}
}
</script>
<style>
</style>
My theme:
<template>
<div class="ceo">
<div ref="modal" class="ceo-popup">
<div class="modal-content-ceo">
<div class="btn-close-popup">
<img src="../../assets/close.svg" id="btn-close-modal" type="button" #click="closemodal()">
</div>
<div class="content-main" v-for="(detail, index) in ceos" :key="index">
<h3 id="name"></h3>
<h5 id="position"></h5>
<h6 id="intro-ceo"></h6>
</div>
<img class="buiding-popup" src="../../assets/Group 226.png" alt="">
</div>
</div>
<div class="title">
<h5>Đội ngũ GoStream</h5>
<h2>Co-Founders</h2>
</div>
<div class="avatar-buiding">
<img class="buiding" src="../../assets/building-0122.png" alt="">
<div class="avatar ">
<img src="../../assets/Profile1.png" #click="modalCeo(0)">
<img src="../../assets//Profile2.png" alt="" #click="modalCeo(1)">
<img src="../../assets/Profile3.png" alt="" #click="modalCeo(2)">
</div>
</div>
</div>
</template>
I want when I click it, a pop up will appear showing the values ​​I have given.
Can you guys give me a solution to this problem?
<div class="avatar" v-for="(item, index) in images" :key="index" >
<img :src="item.url" #click="modalCeo(index)">
</div>
Script:
images:[
{url: '../../assets/Profile1.png'},
{url: '../../assets/Profile2.png'},
{url: '../../assets/Profile3.png'},
]
Update on the code I worked on but it still can't render the image.
You can simply achieve it by using Vue Modal component.
Demo :
new Vue({
el: '#app',
data: {
showModal: false,
selectedCeo: [],
ceos: [
{name_ceo:"Mr. A",
position_ceo:"CEO-GOSTREAM",
content:"Lorem."},
{name_ceo:"Mr. B",
position_ceo:"CTO-GOSTREAM",
content:"Lorem2."},
{name_ceo:"Mr. C",
position_ceo:"CGO-GOSTREAM",
content:"Lorem3."}
]
},
methods: {
modalCeo(index) {
this.showModal = true;
this.selectedCeo = this.ceos[index];
}
}
});
.modal-vue .overlay {
position: fixed;
z-index: 9998;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, .5);
}
.modal-vue .modal {
position: relative;
width: 300px;
z-index: 9999;
margin: 0 auto;
padding: 20px 30px;
background-color: #fff;
}
.modal-vue .close{
position: absolute;
top: 10px;
right: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<!-- app -->
<div id="app" class="modal-vue">
<!-- button show -->
<button v-for="(item, index) in ceos" :key="index" #click="modalCeo(index)">{{ item.name_ceo }}</button>
<!-- overlay -->
<div class="overlay" v-if="showModal" #click="showModal = false"></div>
<!-- modal -->
<div class="modal" v-if="showModal">
<button class="close" #click="showModal = false">x</button>
<p>Name : {{ selectedCeo.name_ceo }}</p>
<p>Position : {{ selectedCeo.position_ceo }}</p>
<p>Content : {{ selectedCeo.content }}</p>
</div>
</div>
Note : I updated code snippet as per your comment. Instead of the profile pictures I used buttons just for the demo.

Easy way to apply masonry to vue grid items?

Is there an easy way to apply masonry to grid items in Vue? I've been searching through tutorials and questions here, but I haven't been able to successfully apply Masonry to my app. I'm looking for a way to use Masonry to automatically place and size the images:
<template>
<div class="row" v-if="othersImages">
<div class="col" v-if="errors">
<div class="alert alert-danger"><p>{{ errors }}</p></div>
</div>
<div id="others-images" class="grid">
<div class="grid-item" v-for="image in othersImages" :key="image.id">
<h5>{{ image.name }}</h5>
<picture v-bind="'image' + image.id">
<img v-bind:src="image.image.path" v-bind:alt="image.description"/>
</picture>
</div>
<div class="clearfix"></div>
</div>
</div>
</template>
<script>
export default {
name: 'othersImages',
created() {
this.fetchImages();
},
data() {
return {
apiRequest: new this.$request(),
othersImages: [],
errors: '',
};
},
methods: {
fetchImages() {
const endpoint = 'images';
this.apiRequest.get(endpoint)
.then((response) => {
this.othersImages = response;
this.errors = '';
})
.catch((errors) => {
this.errors = errors;
});
},
},
};
</script>
I believe, the easiest way to handle that is applying one plugin based on npm package: https://www.npmjs.com/package/vue-masonry. That's the simple library with good supporting and small size.
<template>
<div data-masonry='{"percentPosition": true }' class="row">
<div class="full col-lg-4 half"></div>
<div class="half col-lg-4"></div>
<div class="full col-lg-4"></div>
<div class="full col-lg-4"></div>
<div class="half col-lg-4"></div>
<div class="full col-lg-4"></div>
<div class="full col-lg-4"></div>
<div class="half col-lg-4"></div>
<div class="full col-lg-4"></div>
<div class="full col-lg-4"></div>
</div>
</template>
<script>
export default {}
</script>
<style>
.row {
width: 80vw;
height: 600px;
background-color: green;
margin: auto;
}
.full {
height: 150px;
background-color: grey;
border: 1px solid black;
}
.half {
height: 75px;
background-color: grey;
border: 1px solid black;
}
</style>
You should add bootstrap and masonry cdn's to your projects, then simply adding
data-masonry='{"percentPosition": true }'
line to your row, masonry works automatically.
Check out this link for more info.

Show Swiper slider out of container

The slider slides out of the container.
I do not want to use overflow: hidden for the container.
Here my code:
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide">Slide a</div>
<div class="swiper-slide">Slide b</div>
<div class="swiper-slide">Slide c</div>
<div class="swiper-slide">Slide d</div>
<div class="swiper-slide">Slide e</div>
<div class="swiper-slide">Slide f</div>
<div class="swiper-slide">Slide g</div>
<div class="swiper-slide">Slide h</div>
<div class="swiper-slide">Slide i</div>
<div class="swiper-slide">Slide j</div>
</div>
<div class="swiper-button-next"></div>
<div class="swiper-button-prev"></div>
</div>
var swiper = new Swiper('.swiper-container', {
slidesPerView: 5,
spaceBetween: 9,
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
});
Look this:
image
You can try this solution:
const swiper = new Swiper(".swiper-container", {
// Optional parameters
loop: false,
slidesPerView: "auto",
spaceBetween: 30,
breakpoints: {
// when window width is >= 320px
300: {
slidesPerView: 1.5
},
// when window width is >= 480px
600: {
slidesPerView: 2.5
},
// when window width is >= 640px
900: {
slidesPerView: 3.5
},
1200: {
slidesPerView: 4.5
}
}
});
.swiper-overflow-container {
overflow-x: hidden;
}
.container {
overflow: visible;
outline: 2px solid red;
}
.swiper-container {
overflow: visible;
}
.item {
outline: 1px solid cyan;
}
.image {
width: 100%;
padding-bottom: 100%;
background: #808080;
}
<link href="https://unpkg.com/swiper/swiper-bundle.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://unpkg.com/swiper/swiper-bundle.min.js"></script>
<div class="swiper-overflow-container">
<div class="container py-5">
<div class="swiper-container">
<!-- Additional required wrapper -->
<div class="swiper-wrapper">
<!-- Slides -->
<div class="swiper-slide">
<div class="item">
<div class="image"></div>
<p>First</p>
</div>
</div>
<div class="swiper-slide">
<div class="item">
<div class="image"></div>
<p>Second</p>
</div>
</div>
<div class="swiper-slide">
<div class="item">
<div class="image"></div>
<p>Thrid</p>
</div>
</div>
<div class="swiper-slide">
<div class="item">
<div class="image"></div>
<p>Four</p>
</div>
</div>
<div class="swiper-slide">
<div class="item">
<div class="image"></div>
<p>Five</p>
</div>
</div>
<div class="swiper-slide">
<div class="item">
<div class="image"></div>
<p>Six</p>
</div>
</div>
</div>
</div>
</div>
</div>
HTML:
<div class="swiper-overflow-container">
<div class="container">
<!-- swiper html here -->
</div>
</div>
CSS:
.swiper-overflow-container {
overflow-x: hidden; /* prevent horizontal scroll */
}
.swiper-overflow-container .container {
overflow: visible; /* if your container has overflow by default */
}
.swiper-overflow-container .swiper-container {
overflow: visible; /* remove swiper container overflow */
}
Limitations: not working properly with loop: true

SwiperJS Thumbs bug

Created a swipe with thumbs. When I click on thumbs, it scrolls to the right with incomprehensible logic. I cannot understand what this may be connected with, I am trying to solve this problem for the second day, nothing comes out. Is it possible to somehow disable this option so that you can remove this scroll when clicked?
const productThumbs = new Swiper(".swiper-thumbs", {
spaceBetween: 30,
loop: true,
slidesPerView: 6,
loopedSlides: 7,
});
const productCarousel = new Swiper(".swiper-content", {
effect: 'fade',
fadeEffect: {
crossFade: true
},
touchRatio: 0,
thumbs: {
swiper: productThumbs,
}
});
.swiper-slide{
background: gray;
}
.swiper-thumbs .swiper-slide{
height: 300px;
}
.swiper-content{
margin-top: 30px;
}
.swiper-thumbs .swiper-slide{
display: flex;
flex-direction: column;
}
.swiper-content .swiper-slide{
height: 250px;
background: black;
color: white;
font-size: 72px;
}
<link href="https://unpkg.com/swiper/swiper-bundle.min.css" rel="stylesheet"/>
<script src="https://unpkg.com/swiper/swiper-bundle.min.js"></script>
<div class="swiper-container swiper-thumbs">
<div class="swiper-wrapper">
<div class="swiper-slide">
<span class="slider-title">01</span>
<img src='https://i.ibb.co/Tq5Hvp8/1.png'>
<span class="slider-desc">Windows Server</span>
</div>
<div class="swiper-slide">
<span class="slider-title">02</span>
<img src='https://i.ibb.co/Tq5Hvp8/1.png'>
<span class="slider-desc">Windows Server</span>
</div>
<div class="swiper-slide">
<span class="slider-title">03</span>
<img src='https://i.ibb.co/Tq5Hvp8/1.png'>
<span class="slider-desc">Windows Server</span>
</div>
<div class="swiper-slide">
<span class="slider-title">04</span>
<img src='https://i.ibb.co/Tq5Hvp8/1.png'>
<span class="slider-desc">Windows Server</span>
</div>
<div class="swiper-slide">
<span class="slider-title">05</span>
<img src='https://i.ibb.co/Tq5Hvp8/1.png'>
<span class="slider-desc">Windows Server</span>
</div>
<div class="swiper-slide">
<span class="slider-title">06</span>
<img src='https://i.ibb.co/Tq5Hvp8/1.png'>
<span class="slider-desc">Windows Server</span>
</div>
</div>
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
<div class="swiper-container swiper-content">
<!-- Additional required wrapper -->
<div class="swiper-wrapper">
<!-- Slides -->
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
<div class="swiper-slide">Slide 4</div>
<div class="swiper-slide">Slide 5</div>
<div class="swiper-slide">Slide 6</div>
</div>
</div>
I tried to do this, but I just simply do not understand why this is happening
In the "thumbs" slider, you need to change the value "loop" to "false" or remove the key "loop" from "thumbs" slider.

Reordering bootstrap 3.3.7 columns & eliminating height white space between columns

I try to achieve the mobile and desktop view of the following attached image in the lower half. The problem I have right now is, that the violet col begins only after the yellow col is finished.
Here is my html structure:
<div class="container-fluid">
<div class="col-sm-12 col-md-6 col-md-push-6">RED</div>
<div class="col-sm-12 col-md-6 col-md-pull-6">YELLOW</div>
<div class="col-sm-12 col-md-6 col-md-push-6">VIOLET</div>
</div>
.yellow {
background-color: yellow;
}
.red {
background-color: red;
}
.purple {
background-color: purple;
}
<html>
<head>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
</head>
<div class="container-fluid">
<div class="col-sm-12 col-md-6 col-md-push-6 red">RED<br><br></div>
<div class="col-sm-12 col-md-6 col-md-pull-6 yellow">YELLOW<br><br><br><br><br><br></div>
<div class="col-sm-12 col-md-6 col-md-push-6 purple">VIOLET</div>
</div>
</html>
I have found a simple solution using Grid CSS & Media Queries.
First, I cleaned your HTML markup like so:
HTML:
<div class="container-fluid">
<div class="col-sm-12 col-md-8 col-lg-8 yellow">YELLOW</div>
<div class="col-sm-12 col-md-4 col-lg-4 red">RED</div>
<div class="col-sm-12 col-md-4 col-lg-4 purple">VIOLET</div>
</div>
You can see that I moved the yellow <div> to the first position. We'll set change the position with the grid system only on a certain viewport, mobile on this case, like so:
CSS:
.yellow {
background-color: yellow;
height: 400px; /* for demo only */
}
.red {
background-color: red;
height: 200px; /* for demo only */
}
.purple {
background-color: purple;
height: 200px; /* for demo only */
}
/* Reordering the yellow <div> on mobile version */
#media only screen and (max-width: 1000px) {
.container-fluid {
display: grid;
}
.yellow {
order: 2;
}
.red {
order: 1;
}
.purple {
order: 3;
}
}
Check this code working sample.
Edit:
If you add margin to the <div> columns, you'll need to reduce col-lg & col-md utility classes's number so it won't break the columns grid.