소스 검색

add GalleryView component

axolotle 2 년 전
부모
커밋
a5c4cd0f51
4개의 변경된 파일210개의 추가작업 그리고 2개의 파일을 삭제
  1. 12 0
      src/helpers/common.js
  2. 6 2
      src/messages/fr.json
  3. 191 0
      src/pages/gallery/GalleryView.vue
  4. 1 0
      src/pages/gallery/index.js

+ 12 - 0
src/helpers/common.js

@@ -8,3 +8,15 @@ export function toCommaList (arr, key = 'name') {
   if (!arr) return
   return arr.map(item => item[key]).join(', ')
 }
+
+
+export function shuffle (a) {
+  let j, x, i
+  for (i = a.length - 1; i > 0; i--) {
+    j = Math.floor(Math.random() * (i + 1))
+    x = a[i]
+    a[i] = a[j]
+    a[j] = x
+  }
+  return a
+}

+ 6 - 2
src/messages/fr.json

@@ -46,8 +46,12 @@
   "text": {
     "read": "Voir le texte",
     "read-origin": "Voir le texte de départ",
-    "read-artwork": "Voir l'œuvre"
+    "read-artwork": "Voir l'œuvre",
+    "open-origin": "Texte de référence",
+    "open-artwork": "Texte de l'œuvre"
   },
   "history": "Historique de consultation",
-  "from": "à partir de :"
+  "from": "à partir de :",
+  "map": "Carte",
+  "index": "Index"
 }

+ 191 - 0
src/pages/gallery/GalleryView.vue

@@ -0,0 +1,191 @@
+<template>
+  <div class="gallery-view wh-100">
+    <div v-if="!loading" class="gallery-view-wrapper wh-100">
+      <figure class="gallery-view-figure">
+        <div class="h-100" />
+
+        <div class="node-view-img-wrapper">
+          <img :src="image.url" :alt="image.alt">
+
+          <button-expand @click="$emit('view-creation')" v-b-modal="'modal-creation' + node.id" class="center" />
+
+          <div class="btns-artwork">
+            <b-button variant="depart" class="btn-shadow btn-artwork mr-2" @click="$emit('view-origin')">
+              {{ $t('text.open-origin') }}
+            </b-button>
+
+            <b-button variant="creation" class="btn-shadow btn-artwork" @click="$emit('view-text')">
+              {{ $t('text.open-artwork') }}
+            </b-button>
+          </div>
+        </div>
+
+        <figcaption class="gallery-view-caption">
+          <p class="mb-0 mt-4">
+            <strong>{{ toCommaList(node.authors) }}</strong>,
+            <em v-html="' ' + trim(node.title)" />,
+            {{ node.date.start }}
+          </p>
+        </figcaption>
+      </figure>
+
+      <div
+        v-for="(sibling, i) in node.siblings" :key="sibling.id"
+        class="gallery-view-btn-wrapper"
+        :class="buttonClasses[i]"
+      >
+        <button-image :image="sibling.images[0]" @click="$emit('open-creation', sibling.id)">
+          <node-view-title
+            :node="sibling"
+            tag="span" link
+            class="sr-only"
+          />
+        </button-image>
+      </div>
+    </div>
+
+    <b-overlay
+      :show="loading"
+      spinner-variant="creation"
+      no-wrap
+    />
+  </div>
+</template>
+
+<script>
+import { NodeViewTitle } from '@/components/nodes'
+import { trim, toCommaList, shuffle } from '@/helpers/common'
+
+export default {
+  name: 'GalleryView',
+
+  components: {
+    NodeViewTitle
+  },
+
+  props: {
+    node: { type: Object, default: undefined }
+  },
+
+  data () {
+    return {
+      image: undefined,
+      buttonClasses: [
+        ['top', 'left'],
+        ['top', 'right'],
+        ['bottom', 'right'],
+        ['bottom', 'left']
+      ]
+    }
+  },
+
+  computed: {
+    loading () {
+      return this.node === undefined || this.node.dataLevel < 1
+    }
+  },
+
+  methods: {
+    trim,
+    toCommaList
+  },
+
+  created () {
+    this.buttonClasses = shuffle(this.buttonClasses)
+    if (this.node.images && this.node.images.length) {
+      const { url, alt, id } = this.node.images[0]
+      this.image = { alt, id, url: url.replace('api', 'api/sites/default/files') }
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.gallery-view {
+  margin: auto;
+
+  &-wrapper {
+    display: flex;
+  }
+
+  &-figure {
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+    align-items: center;
+    height: 100%;
+    margin: auto;
+
+    width: calc(100% - 4rem);
+
+    @media (orientation: landscape) {
+      width: calc(100% - 270px);
+
+      @include media-breakpoint-up($size-bp) {
+        width: calc(100% - 450px);
+      }
+    }
+
+    .node-view-img-wrapper {
+      flex-basis: 100%;
+      flex-grow: 2;
+      height: calc(100% - 270px - 4rem);
+
+      @media (orientation: landscape) {
+        height: calc(100% - 270px);
+        @include media-breakpoint-up($size-bp) {
+          height: calc(100% - 450px);
+        }
+      }
+    }
+
+    img {
+      object-fit: cover;
+      object-position: center;
+      width: 100%;
+      height: 100%;
+    }
+
+    .btns-artwork {
+      position: absolute;
+
+      @include media-breakpoint-down($size-bp-down) {
+        top: -50px;
+        width: 100%;
+        display: flex;
+        justify-content: space-between;
+      }
+
+      @include media-breakpoint-up($size-bp) {
+        right: $node-view-spacer-sm-x;
+        bottom: $node-view-spacer-sm-y;
+      }
+    }
+  }
+
+  &-caption {
+    height: 100%;
+    text-align: center;
+    font-size: 1.15rem;
+    font-family: $font-family-text;
+  }
+
+  .gallery-view-btn-wrapper {
+    position: absolute;
+    overflow: hidden;
+
+    &.left {
+      left: 0;
+    }
+    &.right {
+      right: 0;
+    }
+    &.top {
+      top: 0;
+    }
+    &.bottom {
+      bottom: 0;
+    }
+  }
+}
+</style>

+ 1 - 0
src/pages/gallery/index.js

@@ -0,0 +1 @@
+export { default as GalleryView } from './GalleryView'