<figure class="figure" aria-labelledby="figure-7bfd">
<div class="figure__media">
<div class="image-wrap"><img class="image" alt="Das ist ein Platzhalter-Bild" src="/images/dummy/figure-480x320.jpg" />
<button class="copyright js-tooltip image__copyright" title="Quellenangabe" aria-label="Bildquelle anzeigen">
<svg class="icon icon--copyright" id="icon-3a3b" viewBox="0 0 200 200" role="presentation">
<use xlink:href="#icon-copyright"></use>
</svg>
</button>
</div>
</div>
<figcaption class="figure__caption" id="figure-7bfd">
Ich bin eine Bildunterschrift <small class="figure__copyright">(Quellenangabe)</small>
</figcaption>
</figure>
-
//- Prepare attr object
attr = attr || {};
attr.class = classList(attr.class);
if (modifier) attr.class.push(`figure--${modifier}`);
if (video) attr.class.push('figure--video');
figId = id || `figure-${randomString()}`;
attr['aria-labelledby'] = figId;
//- Render figure
figure.figure&attributes(attr)
//- Image
if image
- if (resize || video) label = video ? 'Abspielen' : 'Vergrößern';
- var mediaTag = link ? 'a' : 'div';
- var mediaAttrs = { href: link, title: label, 'aria-label': label };
- if (resize) mediaAttrs.class = ['js-image-resize'];
- if (resizeWidth) mediaAttrs['data-width'] = resizeWidth;
- if (resizeHeight) mediaAttrs['data-height'] = resizeHeight;
- if (video) mediaAttrs.class = ['js-replace-video'];
#{mediaTag}.figure__media&attributes(mediaAttrs)
| #{'\n'}
!= include('@image', {image: image, alt: alt, lazyload, width, height, copyright:copyright})
//- Caption
if caption
figcaption.figure__caption(id=figId)
| #{'\n'}
| #{caption}
if captionCopyrightText
| #[small.figure__copyright #{captionCopyrightText}]
if length
| #[span.figure__length #[!= include('@icon', {title: 'Länge des Videos', icon: 'time', before: true, color: 'grey'})]#{length}]
{
"caption": "Ich bin eine Bildunterschrift",
"captionCopyrightText": "(Quellenangabe)",
"copyright": "Quellenangabe",
"image": "/images/dummy/figure-480x320.jpg",
"alt": "Das ist ein Platzhalter-Bild",
"lazyload": null
}
import initVideos from './videos';
import initGallery from './gallery';
initVideos(document.querySelectorAll('.js-replace-video'));
initGallery(document.querySelectorAll('.js-image-resize'));
.figure {
font-size: 15px;
margin-bottom: 0;
}
.figure__media {
display: block;
line-height: 1;
position: relative;
}
.figure__media--16x9 {
height: 0;
padding-bottom: 56.25%;
}
.figure__iframe {
border: 0;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
.figure__media-overlay {
align-items: flex-end;
bottom: 0;
display: flex;
justify-content: flex-end;
left: 0;
padding: 1rem;
position: absolute;
right: 0;
top: 0;
transition: $default-transition-duration background-color;
@include mq($from: m) {
padding: 1.5rem;
}
@include mq($from: l) {
padding: 2rem;
}
.figure__media:hover &,
.figure__media:focus & {
background-color: rgba($color-steelgrey-xdark, 0.3);
}
.figure--video & {
align-items: center;
justify-content: center;
}
}
.figure__media-icon {
align-items: center;
background-color: #fff;
border-radius: 50%;
box-shadow: 0 0 12px rgba(0, 0, 0, 0.05);
color: #000;
display: flex;
font-size: 2rem;
height: 4.5rem;
justify-content: center;
line-height: 1;
opacity: 0.6;
transition: $default-transition-duration opacity;
width: 4.5rem;
.figure__media:hover &,
.figure__media:focus & {
opacity: 1;
}
}
.figure__caption {
display: block;
font-weight: bold;
padding-top: 1rem;
.figure--video & {
color: $color-blue-light;
}
@include mq($from: m) {
padding-bottom: 1rem;
.detail-page__aside & {
border-bottom: 5px solid $color-steelgrey-light;
}
}
@include mq($from: l) {
padding-bottom: 1.5rem;
padding-top: 1.5rem;
}
}
.figure__copyright {
display: inline-block;
font-size: 1em;
font-weight: 200;
}
.figure__length {
color: $color-anthracite;
display: block;
font-weight: 200;
margin-top: 0.5rem;
}
.js-image-resize {
.image__copyright {
left: 0;
right: auto;
}
}
import h from 'hyperscript';
import PhotoSwipe from 'photoswipe';
import PhotoSwipeUiDefault from 'photoswipe/dist/photoswipe-ui-default';
import jumpStore from '../../../javascripts/shared/anchor-scroll-jump-store';
import icon from '../../../javascripts/utils/icon';
// Template for PhotoSwipe
const $photoswipeTemplate = h('.pswp', {
attrs: {
tabindex: '-1',
role: 'dialog',
'aria-hidden': 'true',
},
}, h('.pswp__bg'), h('.pswp__scroll-wrap',
h('.pswp__container',
h('.pswp__item'),
h('.pswp__item'),
h('.pswp__item'),
),
h('.pswp__ui.pswp__ui--hidden',
h('.pswp__top-bar',
h('.pswp__counter'),
h('button.pswp__button.pswp__button--close', { title: 'Schließen (Esc)' }),
h('button.pswp__button.pswp__button--fs', { title: 'Vollbild ein/aus' }),
h('button.pswp__button.pswp__button--zoom', { title: 'Zoomen' }),
h('.pswp__preloader',
h('.pswp__preloader__icn',
h('.pswp__preloader__cut',
h('.pswp__preloader__donut'),
),
),
),
),
h('button.pswp__button.pswp__button--arrow--left', { title: 'Vorheriges Bild (Pfeil links)' }),
h('button.pswp__button.pswp__button--arrow--right', { title: 'Nächstes Bild (Pfeil rechts)' }),
h('.pswp__caption',
h('.pswp__caption__center'),
),
),
));
// Create array of gallery items
const createGalleryItems = $thumbs => $thumbs.map(
($thumb) => {
// Get title from parent figure
const $figure = $thumb.closest('.figure');
const $caption = $figure ? $figure.querySelector('.figure__caption') : null;
const title = $caption ? $caption.textContent : null;
return {
src: $thumb.getAttribute('href'),
w: $thumb.getAttribute('data-width'),
h: $thumb.getAttribute('data-height'),
title,
};
}
);
// Attach photoswipe to items
const attachPhotoswipe = ($thumbs, galleryItems) => $thumbs.forEach(
($thumb, index) => {
// Add icon overlay
$thumb.appendChild(
h('.figure__media-overlay',
h('span.figure__media-icon', icon({ icon: 'search' })),
),
);
$thumb.addEventListener('click', (event) => {
event.preventDefault();
// Insert template
const $template = $photoswipeTemplate.cloneNode(true);
document.body.appendChild($template);
// Init PhotoSwipe
const slideshow = new PhotoSwipe(
$template,
PhotoSwipeUiDefault,
galleryItems,
{
index,
closeOnScroll: false,
closeOnVerticalDrag: false,
mouseUsed: true,
},
);
// Disable anchor scroll hash change jump when gallery opens
slideshow.listen('initialZoomIn', () => jumpStore.setSkipNext(true));
// After gallery is closed, destroy DOM
slideshow.listen('destroy', () => $template.remove());
// Start gallery
slideshow.init();
});
}
);
const initGallery = ($thumbs) => {
if (!$thumbs || !$thumbs.length) {
return;
}
attachPhotoswipe($thumbs, createGalleryItems($thumbs));
};
export default initGallery;
import h from 'hyperscript';
import getYouTubeID from 'get-youtube-id';
import icon from '../../../javascripts/utils/icon';
const initVideos = $thumbs => $thumbs.forEach(
($thumb) => {
$thumb.appendChild(
h('.figure__media-overlay',
h('span.figure__media-icon', icon({ icon: 'play' }))
),
);
$thumb.addEventListener('click', (event) => {
event.preventDefault();
const $target = event.currentTarget;
const $videoContainer = $target.parentNode;
const youtubeId = getYouTubeID($target.getAttribute('href'));
// Construct Youtube iframe player, add rel=0 to disable related video's
const $iframe = h('.figure__media.figure__media--16x9', h('iframe.figure__iframe', {
src: `https://www.youtube.com/embed/${youtubeId}?rel=0&autoplay=1`,
allowFullscreen: true,
msAllowFullscreen: true,
webkitAllowFullscreen: true,
mozAllowFullscreen: true,
}));
// Add iframe to DOM
$videoContainer.insertBefore($iframe, $target);
// Remove preview image
$target.remove();
// Focus iframe
$iframe.focus();
});
}
);
export default initVideos;
There are no notes for this item.