add GalleryMap component in Gallery
This commit is contained in:
@@ -7,11 +7,11 @@
|
|||||||
:body-class="{ paddings: !noCross }"
|
:body-class="{ paddings: !noCross }"
|
||||||
backdrop backdrop-variant="light"
|
backdrop backdrop-variant="light"
|
||||||
>
|
>
|
||||||
<template #default="{ hide }">
|
<template #default="{ hide, visible }">
|
||||||
<div v-if="!noCross" class="btn-close-wrapper">
|
<div v-if="!noCross" class="btn-close-wrapper">
|
||||||
<button-close @click="hide()" />
|
<button-close @click="hide()" />
|
||||||
</div>
|
</div>
|
||||||
<slot name="default" v-bind="{ hide }" />
|
<slot name="default" v-bind="{ hide, visible }" />
|
||||||
</template>
|
</template>
|
||||||
</b-sidebar>
|
</b-sidebar>
|
||||||
</template>
|
</template>
|
||||||
@@ -38,11 +38,11 @@ export default {
|
|||||||
background-color: red;
|
background-color: red;
|
||||||
width: auto;
|
width: auto;
|
||||||
|
|
||||||
@include media-breakpoint-down($size-bp-down) {
|
@media (orientation: portrait) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include media-breakpoint-up($size-bp) {
|
@media (orientation: landscape) {
|
||||||
max-width: 50%;
|
max-width: 50%;
|
||||||
|
|
||||||
&:not(.b-sidebar-right) {
|
&:not(.b-sidebar-right) {
|
||||||
|
|||||||
+20
-4
@@ -1,11 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="gallery">
|
<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') }}
|
{{ $t('map') }}
|
||||||
</b-button>
|
</b-button>
|
||||||
|
|
||||||
<side-view id="gallery-map">
|
<side-view id="gallery-map-side">
|
||||||
MAP
|
<template #default="{ hide, visible }">
|
||||||
|
<gallery-map
|
||||||
|
v-if="creations"
|
||||||
|
:nodes="creations" :node="creation"
|
||||||
|
:visible="visible"
|
||||||
|
@open-creation="openCreation($event, hide)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
</side-view>
|
</side-view>
|
||||||
|
|
||||||
<gallery-view
|
<gallery-view
|
||||||
@@ -47,7 +54,7 @@ import { mapGetters } from 'vuex'
|
|||||||
import { getRelation } from '@/store/utils'
|
import { getRelation } from '@/store/utils'
|
||||||
import { SideView } from '@/components/layouts'
|
import { SideView } from '@/components/layouts'
|
||||||
import { NodeViewTitle } from '@/components/nodes'
|
import { NodeViewTitle } from '@/components/nodes'
|
||||||
import { GalleryView } from '@/pages/gallery'
|
import { GalleryView, GalleryMap } from '@/pages/gallery'
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -56,6 +63,7 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
SideView,
|
SideView,
|
||||||
GalleryView,
|
GalleryView,
|
||||||
|
GalleryMap,
|
||||||
NodeViewTitle
|
NodeViewTitle
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -138,6 +146,14 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::v-deep #gallery-map-side {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.btn-close {
|
||||||
|
float: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#gallery-index {
|
#gallery-index {
|
||||||
ul {
|
ul {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -159,8 +159,11 @@ export default {
|
|||||||
&-caption {
|
&-caption {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 1.15rem;
|
|
||||||
font-family: $font-family-text;
|
font-family: $font-family-text;
|
||||||
|
|
||||||
|
@include media-breakpoint-up($size-bp) {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.gallery-view-btn-wrapper {
|
.gallery-view-btn-wrapper {
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
export { default as GalleryView } from './GalleryView'
|
export { default as GalleryView } from './GalleryView'
|
||||||
|
export { default as GalleryMap } from './GalleryMap'
|
||||||
|
|||||||
Reference in New Issue
Block a user