add GalleryMap component in Gallery

This commit is contained in:
axolotle
2021-07-09 11:19:40 +02:00
parent 5343caa4a6
commit af1dc1320c
5 changed files with 170 additions and 9 deletions
+4 -4
View File
@@ -7,11 +7,11 @@
:body-class="{ paddings: !noCross }"
backdrop backdrop-variant="light"
>
<template #default="{ hide }">
<template #default="{ hide, visible }">
<div v-if="!noCross" class="btn-close-wrapper">
<button-close @click="hide()" />
</div>
<slot name="default" v-bind="{ hide }" />
<slot name="default" v-bind="{ hide, visible }" />
</template>
</b-sidebar>
</template>
@@ -38,11 +38,11 @@ export default {
background-color: red;
width: auto;
@include media-breakpoint-down($size-bp-down) {
@media (orientation: portrait) {
width: 100%;
}
@include media-breakpoint-up($size-bp) {
@media (orientation: landscape) {
max-width: 50%;
&:not(.b-sidebar-right) {
+20 -4
View File
@@ -1,11 +1,18 @@
<template>
<div class="gallery">
<b-button v-b-toggle.gallery-map variant="creation" class="btn-side left">
<b-button v-b-toggle.gallery-map-side variant="creation" class="btn-side left">
{{ $t('map') }}
</b-button>
<side-view id="gallery-map">
MAP
<side-view id="gallery-map-side">
<template #default="{ hide, visible }">
<gallery-map
v-if="creations"
:nodes="creations" :node="creation"
:visible="visible"
@open-creation="openCreation($event, hide)"
/>
</template>
</side-view>
<gallery-view
@@ -47,7 +54,7 @@ import { mapGetters } from 'vuex'
import { getRelation } from '@/store/utils'
import { SideView } from '@/components/layouts'
import { NodeViewTitle } from '@/components/nodes'
import { GalleryView } from '@/pages/gallery'
import { GalleryView, GalleryMap } from '@/pages/gallery'
export default {
@@ -56,6 +63,7 @@ export default {
components: {
SideView,
GalleryView,
GalleryMap,
NodeViewTitle
},
@@ -138,6 +146,14 @@ export default {
}
}
::v-deep #gallery-map-side {
width: 100%;
.btn-close {
float: unset;
}
}
#gallery-index {
ul {
padding: 0;
+141
View File
@@ -0,0 +1,141 @@
<template>
<div class="gallery-map wh-100">
<div class="gallery-map-wrapper" :style="`--max: ${max}px;`">
<div class="rows" v-if="dots && max">
<div
v-for="(row, y) in dots" :key="y"
class="row"
:class="{ sub: y % 2 === 0 }"
>
<div
v-for="(dot, x) in row" :key="`${y}-${x}`"
class="dot" :class="{ current: dot === node }"
>
<img
v-if="dot"
:src="dot.image.url"
:alt="dot.image.alt"
@click="$emit('open-creation', dot.id)"
>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { shuffle } from '@/helpers/common'
export default {
name: 'GalleryMap',
props: {
nodes: { type: Array, required: true },
node: { type: Object, required: true },
visible: { type: Boolean, required: true }
},
data () {
return {
dots: undefined,
size: [0, 0],
max: undefined
}
},
watch: {
visible (visible) {
if (visible) {
this.defineSize()
}
}
},
methods: {
setDots () {
const nodesLen = this.nodes.length
const sqrt = Math.ceil(Math.sqrt(nodesLen))
const rows = Math.floor(Math.sqrt(Math.pow(sqrt, 2) / 2))
const len = rows + 1
let max = rows * len * 2
let extra = 0
while (max - nodesLen < 0) {
extra += 1
max += extra % 2 === 0 ? rows : len
}
const nodes = shuffle([...this.nodes, ...Array(max - nodesLen).fill(undefined)])
const dots = []
for (var y = 0; y < len + rows + extra; y++) {
const x = y % 2 === 0 ? rows : len
dots.push(nodes.splice(0, x))
}
this.size = [len, len + rows + extra]
this.dots = dots
},
defineSize () {
const [x, y] = this.size
const { offsetWidth, offsetHeight } = document.querySelector('.gallery-map-wrapper')
const h = offsetHeight / (y * 2 - 1)
const w = offsetWidth / (x * 2 - 1)
this.max = Math.min(Math.min(h, w), 100)
}
},
created () {
this.setDots()
}
}
</script>
<style lang="scss" scoped>
.gallery-map {
&-wrapper {
width: 100%;
position: relative;
height: 100%;
}
.rows {
position: absolute;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
height: 100%;
width: 100%;
}
.row {
display: flex;
justify-content: space-between;
width: 100%;
&.sub {
justify-content: space-around;
}
}
.dot {
display: flex;
width: var(--max);
height: var(--max);
img {
max-width: 100%;
max-height: 100%;
margin: auto;
cursor: pointer;
}
&.current {
border: 5px solid theme-color('creation');
background-color: theme-color('creation');
}
}
}
</style>
+4 -1
View File
@@ -159,8 +159,11 @@ export default {
&-caption {
height: 100%;
text-align: center;
font-size: 1.15rem;
font-family: $font-family-text;
@include media-breakpoint-up($size-bp) {
font-size: 1.5rem;
}
}
.gallery-view-btn-wrapper {
+1
View File
@@ -1 +1,2 @@
export { default as GalleryView } from './GalleryView'
export { default as GalleryMap } from './GalleryMap'