Simplify lightbox
This commit is contained in:
@@ -4,7 +4,7 @@ import { Map, NavigationControl, Marker, LngLatBounds, LngLat, Popup } from 'map
|
|||||||
import { createApp, ref, provide, inject } from 'vue';
|
import { createApp, ref, provide, inject } from 'vue';
|
||||||
import Simplebar from 'simplebar-vue';
|
import Simplebar from 'simplebar-vue';
|
||||||
|
|
||||||
import lightbox from '@scripts/lightbox';
|
import Lightbox from '@scripts/lightbox';
|
||||||
import { getOuterWidth } from '@scripts/common';
|
import { getOuterWidth } from '@scripts/common';
|
||||||
|
|
||||||
import SpotIcon from '@components/spotIcon';
|
import SpotIcon from '@components/spotIcon';
|
||||||
@@ -44,6 +44,7 @@ export default {
|
|||||||
baseMaps: {},
|
baseMaps: {},
|
||||||
baseMap: null,
|
baseMap: null,
|
||||||
map: null,
|
map: null,
|
||||||
|
lightbox: null,
|
||||||
hikes: {
|
hikes: {
|
||||||
colors:{'main':'#00ff78', 'off-track':'#0000ff', 'hitchhiking':'#FF7814'},
|
colors:{'main':'#00ff78', 'off-track':'#0000ff', 'hitchhiking':'#FF7814'},
|
||||||
width: 4
|
width: 4
|
||||||
@@ -120,9 +121,8 @@ export default {
|
|||||||
*/
|
*/
|
||||||
},
|
},
|
||||||
async init() {
|
async init() {
|
||||||
let bFirstLoad = (typeof this.currProject.codename == 'undefined');
|
|
||||||
this.initProject();
|
this.initProject();
|
||||||
if(bFirstLoad) this.initLightbox();
|
this.initLightbox();
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
this.initFeed(),
|
this.initFeed(),
|
||||||
@@ -133,7 +133,7 @@ export default {
|
|||||||
if(this.hash.items.length == 3) await this.findPost(this.hash.items[1], this.hash.items[2]);
|
if(this.hash.items.length == 3) await this.findPost(this.hash.items[1], this.hash.items[2]);
|
||||||
},
|
},
|
||||||
quit() {
|
quit() {
|
||||||
lightbox.end();
|
this.lightbox?.end();
|
||||||
this.$refs.feedSimpleBar.scrollElement.removeEventListener('scroll', this.onFeedScroll);
|
this.$refs.feedSimpleBar.scrollElement.removeEventListener('scroll', this.onFeedScroll);
|
||||||
this.setFeedUpdateTimer(-1);
|
this.setFeedUpdateTimer(-1);
|
||||||
this.map.remove();
|
this.map.remove();
|
||||||
@@ -147,7 +147,7 @@ export default {
|
|||||||
this.baseMaps = {};
|
this.baseMaps = {};
|
||||||
},
|
},
|
||||||
initLightbox() {
|
initLightbox() {
|
||||||
lightbox.option({
|
this.lightbox = new Lightbox({
|
||||||
alwaysShowNavOnTouchDevices: true,
|
alwaysShowNavOnTouchDevices: true,
|
||||||
albumLabel: 'Media %1 / %2',
|
albumLabel: 'Media %1 / %2',
|
||||||
fadeDuration: 300,
|
fadeDuration: 300,
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export default {
|
|||||||
'spot-icon',
|
'spot-icon',
|
||||||
this.icon,
|
this.icon,
|
||||||
...(this.classes || '').split(/\s+/),
|
...(this.classes || '').split(/\s+/),
|
||||||
this.margin?'margin-'+this.margin:null || this.hasText?'margin-right':null
|
this.margin?'margin-'+this.margin:null
|
||||||
].filter(Boolean).join(' ');
|
].filter(Boolean).join(' ');
|
||||||
},
|
},
|
||||||
resolvedFixedWidth() {
|
resolvedFixedWidth() {
|
||||||
@@ -49,7 +49,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<span :title="title" v-if="title || hasText">
|
<span :title="title" v-if="title || hasText" class="spot-icon-box">
|
||||||
<FontAwesomeIcon :icon="iconDefinition" :class="classNames" :fixed-width="resolvedFixedWidth" :width-auto="resolvedAutoWidth" :size="resolvedSize" :transform="resolvedTransform" />
|
<FontAwesomeIcon :icon="iconDefinition" :class="classNames" :fixed-width="resolvedFixedWidth" :width-auto="resolvedAutoWidth" :size="resolvedSize" :transform="resolvedTransform" />
|
||||||
<span v-if="hasText" :class="textClasses">{{ text }}</span>
|
<span v-if="hasText" :class="textClasses">{{ text }}</span>
|
||||||
</span>
|
</span>
|
||||||
@@ -59,6 +59,16 @@ export default {
|
|||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@use "@styles/var";
|
@use "@styles/var";
|
||||||
|
|
||||||
|
.spot-icon-box {
|
||||||
|
display: flex;
|
||||||
|
gap: var.$elem-spacing;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
span {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.spot-icon {
|
.spot-icon {
|
||||||
&.margin-right {
|
&.margin-right {
|
||||||
margin-right: var.$elem-spacing;
|
margin-right: var.$elem-spacing;
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
import { icon } from '@fortawesome/fontawesome-svg-core';
|
import { icon } from '@fortawesome/fontawesome-svg-core';
|
||||||
import { getIcon } from '@scripts/icons';
|
import { getIcon } from '@scripts/icons';
|
||||||
|
|
||||||
const defaults = {
|
export default class Lightbox {
|
||||||
|
constructor(options = {}) {
|
||||||
|
this.album = [];
|
||||||
|
this.currentImageIndex = 0;
|
||||||
|
this.options = {
|
||||||
albumLabel: 'Image %1 of %2',
|
albumLabel: 'Image %1 of %2',
|
||||||
alwaysShowNavOnTouchDevices: false,
|
alwaysShowNavOnTouchDevices: false,
|
||||||
fadeDuration: 600,
|
fadeDuration: 600,
|
||||||
@@ -16,14 +20,7 @@ const defaults = {
|
|||||||
onMediaChange: () => {},
|
onMediaChange: () => {},
|
||||||
onClosing: () => {}
|
onClosing: () => {}
|
||||||
};
|
};
|
||||||
|
this.option(options);
|
||||||
|
|
||||||
|
|
||||||
class Lightbox {
|
|
||||||
constructor() {
|
|
||||||
this.album = [];
|
|
||||||
this.currentImageIndex = 0;
|
|
||||||
this.options = { ...defaults };
|
|
||||||
this.gMouseDownOffsetX = 0;
|
this.gMouseDownOffsetX = 0;
|
||||||
this.gMouseDownOffsetY = 0;
|
this.gMouseDownOffsetY = 0;
|
||||||
this.resizeTimer = null;
|
this.resizeTimer = null;
|
||||||
@@ -123,8 +120,8 @@ class Lightbox {
|
|||||||
this.video.autoplay = true;
|
this.video.autoplay = true;
|
||||||
this.image.insertAdjacentElement('afterend', this.video);
|
this.image.insertAdjacentElement('afterend', this.video);
|
||||||
|
|
||||||
this.overlay.style.display = 'none';
|
this.setVisible(this.overlay, false);
|
||||||
this.lightbox.style.display = 'none';
|
this.setVisible(this.lightbox, false);
|
||||||
|
|
||||||
this.containerPadding = this.getBoxMetrics(this.container, 'padding');
|
this.containerPadding = this.getBoxMetrics(this.container, 'padding');
|
||||||
this.imageBorderWidth = this.getBoxMetrics(this.image, 'border');
|
this.imageBorderWidth = this.getBoxMetrics(this.image, 'border');
|
||||||
@@ -157,6 +154,7 @@ class Lightbox {
|
|||||||
});
|
});
|
||||||
this.closeButton.addEventListener('click', (event) => {
|
this.closeButton.addEventListener('click', (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
this.end();
|
this.end();
|
||||||
});
|
});
|
||||||
this.closeButton.addEventListener('keyup', (event) => {
|
this.closeButton.addEventListener('keyup', (event) => {
|
||||||
@@ -381,19 +379,19 @@ class Lightbox {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateNav() {
|
updateNav() {
|
||||||
this.nav.style.display = 'block';
|
this.setVisible(this.nav, true);
|
||||||
this.prev.style.display = 'none';
|
this.setVisible(this.prev, false);
|
||||||
this.next.style.display = 'none';
|
this.setVisible(this.next, false);
|
||||||
|
|
||||||
const alwaysShowNav = ('ontouchstart' in window) && this.options.alwaysShowNavOnTouchDevices;
|
const alwaysShowNav = ('ontouchstart' in window) && this.options.alwaysShowNavOnTouchDevices;
|
||||||
if (this.album.length <= 1) return;
|
if (this.album.length <= 1) return;
|
||||||
|
|
||||||
if (this.options.wrapAround) {
|
if (this.options.wrapAround) {
|
||||||
this.prev.style.display = '';
|
this.setVisible(this.prev, true);
|
||||||
this.next.style.display = '';
|
this.setVisible(this.next, true);
|
||||||
} else {
|
} else {
|
||||||
if (this.currentImageIndex > 0) this.prev.style.display = '';
|
if (this.currentImageIndex > 0) this.setVisible(this.prev, true);
|
||||||
if (this.currentImageIndex < this.album.length - 1) this.next.style.display = '';
|
if (this.currentImageIndex < this.album.length - 1) this.setVisible(this.next, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alwaysShowNav) {
|
if (alwaysShowNav) {
|
||||||
@@ -413,12 +411,12 @@ class Lightbox {
|
|||||||
if (this.options.sanitizeTitle) this.caption.textContent = media.title;
|
if (this.options.sanitizeTitle) this.caption.textContent = media.title;
|
||||||
else this.caption.innerHTML = media.title;
|
else this.caption.innerHTML = media.title;
|
||||||
this.fade(this.caption, true, 200);
|
this.fade(this.caption, true, 200);
|
||||||
this.fade(this.closeButton, true, 200);
|
|
||||||
} else {
|
} else {
|
||||||
this.caption.textContent = '';
|
this.caption.textContent = '';
|
||||||
this.caption.style.display = 'none';
|
this.setVisible(this.caption, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.fade(this.closeButton, true, 200);
|
||||||
this.outerContainer.classList.remove('animating');
|
this.outerContainer.classList.remove('animating');
|
||||||
this.fade(this.dataContainer, true, this.options.resizeDuration);
|
this.fade(this.dataContainer, true, this.options.resizeDuration);
|
||||||
}
|
}
|
||||||
@@ -529,24 +527,31 @@ class Lightbox {
|
|||||||
|
|
||||||
hideElements(elements) {
|
hideElements(elements) {
|
||||||
elements.forEach((element) => {
|
elements.forEach((element) => {
|
||||||
if (element) element.style.display = 'none';
|
this.setVisible(element, false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setVisible(element, visible) {
|
||||||
|
if (!element) return;
|
||||||
|
element.style.visibility = visible ? 'visible' : 'hidden';
|
||||||
|
element.style.pointerEvents = visible ? '' : 'none';
|
||||||
|
}
|
||||||
|
|
||||||
fade(element, show, duration, done) {
|
fade(element, show, duration, done) {
|
||||||
if (!element) return;
|
if (!element) return;
|
||||||
|
|
||||||
const safeDuration = duration || 0;
|
const safeDuration = duration || 0;
|
||||||
element.style.transition = `opacity ${safeDuration}ms`;
|
element.style.transition = `opacity ${safeDuration}ms`;
|
||||||
if (show) {
|
if (show) {
|
||||||
element.style.display = element === this.lightbox ? 'flex' : 'block';
|
this.setVisible(element, true);
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
element.style.opacity = element === this.overlay ? '0.8' : '1';
|
element.style.opacity = element === this.overlay ? '0.8' : '1';
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
element.style.opacity = '0';
|
element.style.opacity = '0';
|
||||||
|
element.style.pointerEvents = 'none';
|
||||||
window.setTimeout(() => {
|
window.setTimeout(() => {
|
||||||
element.style.display = 'none';
|
this.setVisible(element, false);
|
||||||
}, safeDuration);
|
}, safeDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -569,8 +574,3 @@ class Lightbox {
|
|||||||
this.options.onClosing();
|
this.options.onClosing();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const lightbox = new Lightbox();
|
|
||||||
|
|
||||||
export const options = defaults;
|
|
||||||
export default lightbox;
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ body.lb-disable-scrolling {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.lightboxOverlay {
|
.lightboxOverlay {
|
||||||
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
@@ -15,7 +16,6 @@ body.lb-disable-scrolling {
|
|||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
background-color: black;
|
background-color: black;
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
display: none;
|
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,31 +30,64 @@ body.lb-disable-scrolling {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
|
/* Data Container (comments, close) */
|
||||||
|
|
||||||
|
.lb-dataContainer {
|
||||||
|
position: relative;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.lb-data {
|
||||||
|
display: flex;
|
||||||
|
margin: var.$elem-spacing;
|
||||||
|
gap: var.$block-spacing;
|
||||||
|
color: color.$default-inv;
|
||||||
|
|
||||||
|
.lb-caption {
|
||||||
|
display: flex;
|
||||||
|
gap: var.$block-spacing;
|
||||||
|
|
||||||
|
.lb-caption-line {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
line-height: 1.33333333333em; //icon height
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.lb-closeContainer .lb-close {
|
||||||
|
@extend .clickable;
|
||||||
|
font-size: 1.3333333333em;
|
||||||
|
line-height: 1em;
|
||||||
|
color: color.$default-inv;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: color.$default-inv-hover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.vertical {
|
&.vertical {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
.lb-dataContainer {
|
.lb-dataContainer {
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.lb-data {
|
.lb-data {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
||||||
.lb-details {
|
.lb-details {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
|
min-width: 0;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
.lb-caption {
|
.lb-caption-line.comment {
|
||||||
.lb-caption-line {
|
flex: 1 1 auto;
|
||||||
padding-right: var.$block-spacing;
|
min-width: 0;
|
||||||
line-height: 1.33333333333em; //icon height
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
&.comment {
|
|
||||||
max-width: 50%;
|
|
||||||
@include common.no-text-overflow();
|
@include common.no-text-overflow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.lb-closeContainer {
|
.lb-closeContainer {
|
||||||
.lb-close {
|
.lb-close {
|
||||||
@@ -73,47 +106,29 @@ body.lb-disable-scrolling {
|
|||||||
.lb-data {
|
.lb-data {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
.lb-caption-line {
|
.lb-caption {
|
||||||
display: block;
|
flex-direction: column;
|
||||||
margin-top: var.$block-spacing;
|
|
||||||
line-height: 1.33333333em;
|
|
||||||
|
|
||||||
&.comment {
|
|
||||||
.spot-icon {
|
|
||||||
vertical-align: center;
|
|
||||||
}
|
|
||||||
.comment-text {
|
|
||||||
display: inline-block;
|
|
||||||
width: calc(100% - 1.25em*1.33333333333 - var.$elem-spacing);
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.lb-closeContainer .lb-close {
|
.lb-closeContainer .lb-close {
|
||||||
margin-top: calc(1em/1.33333333);
|
margin-top: calc(1em/1.33333333);
|
||||||
float: none;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Picture Container */
|
||||||
|
|
||||||
.lb-outerContainer {
|
.lb-outerContainer {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 250px;
|
width: 250px;
|
||||||
height: 250px;
|
height: 250px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border-radius:0;
|
|
||||||
background-color: color.$default-bg-trans;
|
background-color: color.$default-bg-trans;
|
||||||
|
|
||||||
&:after {
|
|
||||||
content: "";
|
|
||||||
display: table;
|
|
||||||
clear: both;
|
|
||||||
}
|
|
||||||
|
|
||||||
.lb-container {
|
.lb-container {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
&.moveable {
|
&.moveable {
|
||||||
cursor: grab;
|
cursor: grab;
|
||||||
@@ -124,7 +139,6 @@ body.lb-disable-scrolling {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.lb-image {
|
.lb-image {
|
||||||
display: block;
|
|
||||||
height: auto;
|
height: auto;
|
||||||
max-width: inherit;
|
max-width: inherit;
|
||||||
max-height: none;
|
max-height: none;
|
||||||
@@ -143,6 +157,9 @@ body.lb-disable-scrolling {
|
|||||||
|
|
||||||
.lb-video {
|
.lb-video {
|
||||||
box-sizing: content-box;
|
box-sizing: content-box;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.lb-video-nav .lb-nav {
|
&.lb-video-nav .lb-nav {
|
||||||
@@ -229,41 +246,4 @@ body.lb-disable-scrolling {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.lb-dataContainer {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
width: 100%;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
.lb-data {
|
|
||||||
text-align: left;
|
|
||||||
padding: var.$elem-spacing;
|
|
||||||
display: flex;
|
|
||||||
color: color.$default-inv;
|
|
||||||
|
|
||||||
.lb-details {
|
|
||||||
float: none;
|
|
||||||
|
|
||||||
.lb-caption-line:first-child {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.lb-closeContainer .lb-close {
|
|
||||||
@extend .clickable;
|
|
||||||
height: auto;
|
|
||||||
font-size: 1.3333333333em;
|
|
||||||
line-height: 1em;
|
|
||||||
text-align: center;
|
|
||||||
width: 1.25em;
|
|
||||||
color: color.$default-inv;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: color.$default-inv-hover;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user