<figure class="a-image a-image--cover">
<a class="a-image__link" href="#" tabindex="-1">
<img src="/img/wheat_ratio.jpg" alt="Some many things on this image" title="This is a linked image" class="a-image__image a-image__image--fp a-image__image--fp-">
</a>
<figcaption>
<span class="a-image__caption">This is the image caption</span>
<small class="a-image__copy a-image__copy--caption">© Photographer xy</small>
</figcaption>
</figure>
<figure class="a-image{{#unless no_crop }} a-image--cover{{/unless}}">
{{#if link-url}}<a class="a-image__link" href="{{link-url}}" tabindex="-1">{{/if}}
<img src="{{image-src}}" alt="{{alt}}" title="{{title}}" class="a-image__image{{#unless no_crop }} a-image__image--fp a-image__image--fp-{{focal_point}}{{/unless}}">
{{#if link-url}}</a>{{/if}}
{{# unless no_caption }}
<figcaption>
{{#if caption}}<span class="a-image__caption">{{caption}}</span>{{/if}}
{{#if copy}}
<small class="a-image__copy{{#if caption}} a-image__copy--caption{{/if}}">© {{copy}}</small>{{/if}}
</figcaption>
{{/unless}}
</figure>
.a-image {
max-width: 100%;
position: relative;
line-height: 0;
&__image {
transition: transform $transition-mid $transition-ease-image;
}
&__image--no-crop {
max-width: 100%;
}
&--cover {
width: 100%;
height: 100%;
}
&--cover &__image {
width: 100%;
height: 100%;
}
&--cover &__lazy-wrapper {
width: 100%;
height: 100%;
overflow: hidden;
}
&--cover.object-fit-ie {
background-size: cover;
}
&__image--lazy {
filter: blur(2vw);
transform: scale(1.1);
}
&__image--loaded {
animation-name: reveal;
animation-duration: $transition-mid;
animation-timing-function: $transition-ease-image;
}
&--cover &__image--fp {
object-fit: cover;
&-top {
&-left {
object-position: 0 0;
}
&-center {
object-position: 50% 0;
}
&-right {
object-position: 100% 0;
}
}
&-middle {
&-left {
object-position: 0 50%;
}
&-center {
object-position: 50% 50%;
}
&-right {
object-position: 100% 50%;
}
}
&-bottom {
&-left {
object-position: 0 100%;
}
&-center {
object-position: 50% 100%;
}
&-right {
object-position: 100% 100%;
}
}
&.object-fit-ie {
display: none;
}
}
// for the IE polyfill
&--cover.object-fit-ie.a-image__image-fp {
&-top {
&-left {
background-position: 0 0;
}
&-center {
background-position: 50% 0;
}
&-right {
background-position: 100% 0;
}
}
&-middle {
&-left {
background-position: 0 50%;
}
&-center {
background-position: 50% 50%;
}
&-right {
background-position: 100% 50%;
}
}
&-bottom {
&-left {
background-position: 0 100%;
}
&-center {
background-position: 50% 100%;
}
&-right {
background-position: 100% 100%;
}
}
}
&__link {
@include clean-link;
display: block;
max-width: 100%;
overflow: hidden;
@include hover {
.a-image__image {
transform: scale(1.01);
}
}
}
&--cover &__link {
width: 100%;
height: 100%;
}
&__copy {
position: absolute;
@include fluid-props(bottom right, $size-tiny, $size-large, 5px, 10px);
@include fluid-props(font-size, $size-tiny, $size-large, 5px, 7px);
transform: translateX(calc(100% - 1em)) rotate(-90deg);
transform-origin: top left;
color: $color-white;
text-transform: uppercase;
mix-blend-mode: difference;
&--caption {
transform: none;
color: $color-text-light;
mix-blend-mode: normal;
}
&--small {
bottom: 6px;
right: 3px;
font-size: 6px;
}
a {
box-shadow: none;
color: inherit;
text-decoration: none;
@include hover {
background: none;
box-shadow: none;
}
}
}
&__caption {
line-height: 1.4em;
font-size: 0.875rem;
color: $color-text-light;
padding: 0.5em 1em 1em;
background: $color-grey-1;
width: 100%;
display: block;
}
}
@keyframes reveal {
0% {filter: blur(2vw); transform: scale(1.1);}
100% {filter: blur(0); transform: scale(1);}
};
.no-js .a-image--cover .a-image__lazy-wrapper {
display: none;
}
import BaseView from 'base-view';
const COVER_IMAGE_SELECTOR = '.a-image__image--fp';
const LAZY_LOADED = 'a-image__image--loaded';
const COMPATIBILITY_STATE = 'object-fit-ie';
const LAZY_LOAD_WAIT_MS = 200;
/**
* Since IE and Edge don't support object-fit, use background: cover css for
* them
*
* @see https://medium.com/@primozcigler/neat-trick-for-css-object-fit-fallback-on-edge-and-other-browsers-afbc53bbb2c3
*/
export default class AImageCover extends BaseView {
initialize() {
this.initUrl = this.getUrl();
}
bind() {
super.bind();
this.on( 'afterReplaceImage', () => {
this.setSizes();
this.objectFit();
} );
}
objectFit() {
if ('objectFit' in document.documentElement.style !== false) {
this.destroy();
return;
}
const img = this.getScopedElement(COVER_IMAGE_SELECTOR);
if (!img) {
this.destroy();
return;
}
this.polyfill(img);
}
polyfill(img) {
const url = this.getUrl();
// wait for lazy loading to be complete
if (img.classList.contains(LAZY_LOADED)) {
if (this.initUrl === url) {
window.setTimeout(() => this.polyfill(img), LAZY_LOAD_WAIT_MS);
return;
}
}
let fp = img.className.match(/\ba-image__image--fp-[^\s]+\b/g);
if (fp) {
this.addClass('a-image__image--fp');
this.addClass(fp[0]);
}
this.addClass(COMPATIBILITY_STATE);
this.element.style.backgroundImage = "url('"+url+"')";
this.addClass(img, COMPATIBILITY_STATE);
}
getUrl() {
const img = this.getScopedElement( COVER_IMAGE_SELECTOR );
if (img) {
return img.src;
}
return '';
}
setSizes() {
const img = this.getScopedElement( COVER_IMAGE_SELECTOR );
const cDims = this.element.getBoundingClientRect();
const cRatio = cDims.width / cDims.height;
const iRatio = img.naturalWidth / img.naturalHeight;
const zoom = iRatio > cRatio ? iRatio / cRatio : cRatio / iRatio;
img.sizes = cDims.width * zoom + 'px';
}
}
import BaseView from 'base-view';
import inView from '../../../js/service/inview';
const BASE_CONTAINER_SELECTOR = '.a-image';
const LAZY_STATE = 'a-image__image--lazy';
const LAZY_LOADED = 'a-image__image--loaded';
const DEBOUNCE_DELAY_MS = 300;
export default class AImageLazy extends BaseView {
initialize() {
this.loading = false;
}
bind() {
super.bind();
inView(this.element, DEBOUNCE_DELAY_MS).then(() => this.maybeLoadImage());
}
maybeLoadImage() {
if (!this.loading){
this.loading = true;
let img = this.loadFullImage();
if (img.complete) {
this.replaceImage( img );
} else {
img.onload = () => this.replaceImage( img );
}
}
}
loadFullImage() {
let img = this.element.cloneNode( true );
img.srcset = img.dataset.srcset || '';
img.sizes = img.dataset.sizes || '';
img.removeAttribute( 'data-srcset' );
img.removeAttribute( 'data-sized' );
// otherwise safari on iOS doesn't load images when
// scrolling, even if they are in the viewport
img.loading = 'eager';
return img;
}
replaceImage( img ) {
if (this.element.parentNode) {
this.element.parentNode.replaceChild( img, this.element );
}
img.classList.add( LAZY_LOADED );
img.classList.remove( LAZY_STATE );
this.triggerAfterReplaceEvent( img.closest( BASE_CONTAINER_SELECTOR ) );
this.destroy();
}
triggerAfterReplaceEvent(elem) {
// use the old fashioned way, cause we need it in IE
let event = document.createEvent('Event');
event.initEvent('afterReplaceImage', true, true);
elem.dispatchEvent(event);
}
}
{
"link-url": "#",
"image-src": "/img/wheat_ratio.jpg",
"alt": "Some many things on this image",
"title": "This is a linked image",
"copy": "Photographer xy",
"caption": "This is the image caption"
}
No notes defined.