<template> <teleport to="body"> <div class="album"> <div class="album-header"> <h3 class="album-title">{{ title }}</h3> <Icon icon="cross2" class="close" @click.native="$emit('close')" /> </div> <div class="album-body"> <div v-if="entity || tag" class="campaign-container" > <Campaign :entity="entity" :tag="tag" :min-ratio="3" /> </div> <div class="album-items" :class="{ portrait }" > <div v-for="item in albumItems" :key="item.id" class="item-container" > <a :href="getPath(item, null, { local })" class="item-link" target="_blank" > <img :src="getPath(item, 'thumbnail', { local })" :style="{ 'background-image': getBgPath(item, 'lazy', { local }) }" :width="item.thumbnailWidth" :height="item.thumbnailHeight" :title="item.title" loading="lazy" class="item image" > <Logo :photo="item" /> <router-link v-if="comments && item.title && item.entity" :to="`/${item.entity.type}/${item.entity.slug}`" class="item-comment" >{{ item.title }} for {{ item.entity.name }}</router-link> <span v-else-if="comments && item.title" class="item-comment" >{{ item.title }}</span> </a> </div> </div> </div> </div> </teleport> </template> <script> import Logo from './logo.vue'; import Campaign from '../campaigns/campaign.vue'; function albumItems() { return this.items .filter(Boolean) .map(item => ({ ...item, title: item.comment || (item.credit && `© ${item.credit}`) || (item.entity && `© ${item.entity.name}`), })); } export default { components: { Logo, Campaign, }, props: { items: { type: Array, default: () => [], }, title: { type: String, default: null, }, local: { type: Boolean, default: false, }, portrait: { type: Boolean, default: false, }, comments: { type: Boolean, default: true, }, entity: { type: Object, default: null, }, tag: { type: Object, default: null, }, }, computed: { albumItems, }, emits: ['close'], }; </script> <style lang="scss" scoped> @import 'breakpoints'; .album { width: 100%; height: 100%; display: flex; flex-direction: column; position: fixed; top: 0; left: 0; background: var(--darken-extreme); z-index: 10; } .album-header { display: flex; justify-content: space-between; flex-shrink: 0; } .album-title { display: block; flex-grow: 1; align-items: center; padding: 1rem; margin: 0; color: var(--text-light); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: center; text-transform: capitalize; } .close { width: 1.5rem; height: 1.5rem; padding: 1rem; fill: var(--lighten); &:hover { cursor: pointer; fill: var(--text-light); } } .album-body { display: flex; flex-grow: 1; flex-direction: column; justify-content: center; overflow-y: auto; } .campaign-container { flex-shrink: 0; text-align: center; } .album-items { height: 0; display: grid; flex-grow: 1; flex-shrink: 0; align-items: center; justify-content: center; grid-template-columns: repeat(auto-fit, minmax(25rem, 1fr)); grid-gap: 0 1rem; padding: 1rem; margin: auto 0; &.portrait { grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); } } .item-container { display: flex; align-items: center; justify-content: center; } .item-link { position: relative; margin: 0 0 .5rem 0; overflow: hidden; &:hover { .item-comment { transform: translateY(0); } ::v-deep(.album-logo) { opacity: 0; } } } .item { max-width: 100%; max-height: 100%; height: auto; background-size: cover; background-position: center; } .item-comment { width: 100%; position: absolute; bottom: 0; left: 0; box-sizing: border-box; padding: .5rem; color: var(--text-light); background: var(--darken); font-size: .9rem; text-shadow: 0 0 3px var(--darken); text-decoration: none; white-space: normal; line-height: 1.25; transform: translateY(100%); transition: transform .25s ease; } @media(max-width: $breakpoint-giga) { .album-items { grid-template-columns: repeat(auto-fill, minmax(22.5rem, 1fr)); .portrait { grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr)); } } } @media(max-width: $breakpoint-mega) { .album-items.portrait { grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr)); } } @media(max-width: $breakpoint-kilo) { .album-items { grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr)); grid-gap: 0 .5rem; padding: .5rem; } .item-link { margin: 0 0 .25rem 0; } } @media(max-width: $breakpoint) { .album-items { grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); } } @media(max-width: $breakpoint-micro) { .album-items { grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); } } @media(max-width: $breakpoint-pico) { .album-items { grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr)); } } </style>