V2 is here!
Pretty Vue.js lightbox inspired by fancybox
with zoom, swipe, captions and videos supported.
Important: loop only works when effect is swipe
Getting started
Installation
via npm
npm install --save vue-cool-lightbox
via CDN
<!-- the lightbox uses body-scroll-lock as a dependency -->
<script src="https://cdn.jsdelivr.net/npm/body-scroll-lock/lib/bodyScrollLock.min.jsx"></script>
<script src="https://unpkg.com/vue-cool-lightbox"></script>
<link rel="stylesheet" media="all" href="https://unpkg.com/vue-cool-lightbox/dist/vue-cool-lightbox.min.css" />
Basic Usage
via npm
// use the component
import CoolLightBox from 'vue-cool-lightbox'
import 'vue-cool-lightbox/dist/vue-cool-lightbox.min.css'
export default {
components: {
CoolLightBox,
},
}
// or register it globally
import Vue from 'Vue'
import CoolLightBox from 'vue-cool-lightbox'
import 'vue-cool-lightbox/dist/vue-cool-lightbox.min.css'
Vue.use(CoolLightBox)
via CDN
<script>
// register globally
Vue.component('vue-cool-lightbox', window.CoolLightBox.default)
</script>
Examples
Basic
You can swipe the slides, when you swipe to up or to down the lightbox is going to close.
<template>
<div id="app">
<CoolLightBox
:items="items"
:index="index"
@close="index = null">
</CoolLightBox>
<div class="images-wrapper">
<div
class="image"
v-for="(image, imageIndex) in items"
:key="imageIndex"
@click="index = imageIndex"
:style="{ backgroundImage: 'url(' + image + ')' }"
></div>
</div>
</div>
</template>
<script>
export default {
data: function () {
return {
items: [
'https://cosmos-images2.imgix.net/file/spina/photo/20565/191010_nature.jpg?ixlib=rails-2.1.4&auto=format&ch=Width%2CDPR&fit=max&w=835',
'https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/nature-quotes-1557340276.jpg?crop=0.666xw:1.00xh;0.168xw,0&resize=640:*',
],
index: null
};
},
};
</script>
Fade effect
<template>
<div id="app">
<CoolLightBox
:items="items"
:index="index"
:effect="'fade'"
@close="index = null">
</CoolLightBox>
<div class="images-wrapper">
<div
class="image"
v-for="(image, imageIndex) in items"
:key="imageIndex"
@click="index = imageIndex"
:style="{ backgroundImage: 'url(' + image + ')' }"
></div>
</div>
</div>
</template>
<script>
export default {
data: function () {
return {
items: [
'https://cosmos-images2.imgix.net/file/spina/photo/20565/191010_nature.jpg?ixlib=rails-2.1.4&auto=format&ch=Width%2CDPR&fit=max&w=835',
'https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/nature-quotes-1557340276.jpg?crop=0.666xw:1.00xh;0.168xw,0&resize=640:*',
],
index: null
};
},
};
</script>
With captions
<template>
<div id="app">
<CoolLightBox
:items="items"
:index="index"
@close="index = null">
</CoolLightBox>
<div class="images-wrapper">
<div
class="image"
v-for="(image, imageIndex) in items"
:key="imageIndex"
@click="index = imageIndex"
:style="{ backgroundImage: 'url(' + image.src + ')' }"
></div>
</div>
</div>
</template>
<script>
export default {
data: function () {
return {
items: [
{
title: 'In nature, nothing is perfect and everything is perfect',
description: "Photo by Lucas",
src: 'https://cosmos-images2.imgix.net/file/spina/photo/20565/191010_nature.jpg?ixlib=rails-2.1.4&auto=format&ch=Width%2CDPR&fit=max&w=835',
},
{
title: 'a beautiful mountain view',
description: "Photo by Facundo",
src: 'https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/nature-quotes-1557340276.jpg?crop=0.666xw:1.00xh;0.168xw,0&resize=640:*',
},
],
index: null
};
},
};
</script>
Zoom example
Important: The zoom is only activated when the image is bigger than the height or width of the screen. On mobile sizes is disabled at the moment.
<template>
<div id="app">
<CoolLightBox
:items="items"
:index="index"
@close="index = null">
</CoolLightBox>
<div class="images-wrapper">
<div
class="image"
v-for="(image, imageIndex) in items"
:key="imageIndex"
@click="index = imageIndex"
:style="{ backgroundImage: 'url(' + image.src + ')' }"
></div>
</div>
</div>
</template>
<script>
export default {
data: function () {
return {
items: [
{
title: 'In nature, nothing is perfect and everything is perfect',
description: "Photo by Lucas",
src: 'https://images.unsplash.com/photo-1420593248178-d88870618ca0?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80',
},
{
title: 'A beautiful mountain view',
description: "Photo by Facundo",
src: 'https://upload.wikimedia.org/wikipedia/commons/4/42/Shaqi_jrvej.jpg',
},
],
index: null
};
},
};
</script>
Zoom bar
<template>
<div id="app">
<CoolLightBox
:items="items"
:index="index"
:useZoomBar="true"
@close="index = null">
</CoolLightBox>
<div class="images-wrapper">
<div
class="image"
v-for="(image, imageIndex) in items"
:key="imageIndex"
@click="index = imageIndex"
:style="{ backgroundImage: 'url(' + image + ')' }"
></div>
</div>
</div>
</template>
<script>
export default {
data: function () {
return {
items: [
'https://cosmos-images2.imgix.net/file/spina/photo/20565/191010_nature.jpg?ixlib=rails-2.1.4&auto=format&ch=Width%2CDPR&fit=max&w=835',
'https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/nature-quotes-1557340276.jpg?crop=0.666xw:1.00xh;0.168xw,0&resize=640:*',
],
index: null
};
},
};
</script>
Fullscreen
<template>
<div id="app">
<CoolLightBox
:items="items"
:index="index"
:fullScreen="true"
@close="index = null">
</CoolLightBox>
<div class="images-wrapper">
<div
class="image"
v-for="(image, imageIndex) in items"
:key="imageIndex"
@click="index = imageIndex"
:style="{ backgroundImage: 'url(' + image + ')' }"
></div>
</div>
</div>
</template>
<script>
export default {
data: function () {
return {
items: [
'https://cosmos-images2.imgix.net/file/spina/photo/20565/191010_nature.jpg?ixlib=rails-2.1.4&auto=format&ch=Width%2CDPR&fit=max&w=835',
'https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/nature-quotes-1557340276.jpg?crop=0.666xw:1.00xh;0.168xw,0&resize=640:*',
],
index: null
};
},
};
</script>
Videos
<template>
<div id="app">
<CoolLightBox
:items="items"
:index="index"
@close="index = null">
</CoolLightBox>
<div class="images-wrapper">
<div
class="image"
v-for="(image, imageIndex) in items"
:key="imageIndex"
@click="index = imageIndex"
:style="{ backgroundImage: 'url(' + image.thumb + ')' }"
></div>
</div>
</div>
</template>
<script>
export default {
data: function () {
return {
items: [
{
title: 'In nature, nothing is perfect and everything is perfect',
description: "Photo by Lucas",
thumb: 'https://cosmos-images2.imgix.net/file/spina/photo/20565/191010_nature.jpg?ixlib=rails-2.1.4&auto=format&ch=Width%2CDPR&fit=max&w=835',
src: 'https://www.youtube.com/watch?v=d0tU18Ybcvk',
},
{
title: 'A beautiful mountain view',
description: "Photo by Facundo",
src: 'https://vimeo.com/43338103',
thumb: 'https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/nature-quotes-1557340276.jpg?crop=0.666xw:1.00xh;0.168xw,0&resize=640:*',
},
{
title: 'In nature, nothing is perfect and everything is perfect',
description: "Photo by Lucas",
thumb: 'https://scx1.b-cdn.net/csz/news/800/2019/1-nature.jpg',
src: '/video.mp4',
},
],
index: null
};
},
};
</script>
API
Items attributes
Name | Description |
---|---|
src | Url of the image/video |
alt | alt attribute of the image |
title | Slide title |
description | Slide description |
thumb | Thumb url used in thumbs block |
mediaType | Defines media type |
autoplay | Setting it to true it will work with youtube, vimeo or any web video format. |
Props
Name | Type | Default | Description |
---|---|---|---|
index | Number | Index of items to open | |
items | Array | Array of images/videos | |
loop | Boolean | true | Enables looping through items |
effect | String | swipe | Effect on slide, could be swipe or fade |
fullScreen | Boolean | false | Allow users to fullscreen mode |
slideshow | Boolean | true | Enables lighbox slideshow |
slideshowColorBar | String | #fa4242 | Color of the slideshow progress bar |
slideshowDuration | Number | 3000 | Duration of slides when slideshow is running (in ms) |
srcName | String | src | Name of the prop to use as image/video url |
srcThumb | String | thumb | Name of the prop to use as image/video thumb |
overlayColor | String | rgba(30, 30, 30, .9) | Overlay color |
zIndex | Number | 9999 | .cool-lightbox z-index |
thumbsPosition | String | right | Defines thumbs position, could be right or bottom |
youtubeCookies | Boolean | true | if is setted to false it will use https://www.youtube-nocookie.com/embed/YOUTUBE_ID for youtube videos |
useZoomBar | Boolean | false | enables a zoom bar similar with the zoom as in Slack |
enableWheelEvent | Boolean | false | enables change slides on mouse wheel events |
closeOnClickOutsideMobile | Boolean | false | enables close lightbox when the user clicks outside the image/video/iframe on mobile devices |
srcMediaType | String | 'mediaType' | media type src for each item |
dir | String | 'ltr' | if you set it to 'rtl' it will work fine with sites where the body or any wrapper has direction: rtl |
enableScrollLock | Boolean | true | By default when the lightbox is open the body is locked |
translations | Object |
| Translation to allow simple locale settings |
Events
Name | Attributes | Listen to | Description |
---|---|---|---|
OnChange | (indexItem) | @on-change | Emitted when the lightbox changes the item index |
OnOpen | (indexItem) | @on-open | Emitted when the lightbox is opened |
Close | (indexItem) | @close | Emitted when the lightbox is closed |
Slots
Name | Description |
---|---|
icon-previous | Previous icon |
icon-next | Next icon |
close | Close icon |
loading | Loading animation |
Acknowledgements
Thanks to all these people who helped me to do some great features :)
- Dmitriy Borshchevskiy who did a big part of enableWheelEvent prop
- Matt who made the first pull request and did an excellent job doing the mediaType prop
- elalekey who gave me greats ideas to add to the lightbox
- Icons made by Freepik from www.flaticon.com
Online examples
It makes me really happy to see online sites that are using the component:
- partner.fairtradecertified.org. Thanks Matt Pope.