192 lines
6.1 KiB
JavaScript
192 lines
6.1 KiB
JavaScript
( function () {
|
|
function TiledGalleryCollection() {
|
|
this.galleries = [];
|
|
this.findAndSetupNewGalleries();
|
|
}
|
|
|
|
TiledGalleryCollection.prototype.findAndSetupNewGalleries = function () {
|
|
var self = this;
|
|
var unresizedGalleries = document.querySelectorAll( '.tiled-gallery.tiled-gallery-unresized' );
|
|
|
|
Array.prototype.forEach.call( unresizedGalleries, function ( el ) {
|
|
self.galleries.push( new TiledGallery( el ) );
|
|
} );
|
|
};
|
|
|
|
TiledGalleryCollection.prototype.resizeAll = function () {
|
|
Array.prototype.forEach.call( this.galleries, function ( gallery ) {
|
|
gallery.resize();
|
|
} );
|
|
};
|
|
|
|
function TiledGallery( galleryElem ) {
|
|
this.gallery = galleryElem;
|
|
|
|
this.addCaptionEvents();
|
|
|
|
// Resize when initialized to fit the gallery to window dimensions
|
|
this.resize();
|
|
|
|
// Displays the gallery and prevents it from being initialized again
|
|
this.gallery.classList.remove( 'tiled-gallery-unresized' );
|
|
}
|
|
|
|
/**
|
|
* Selector for all resizeable elements inside a Tiled Gallery
|
|
*/
|
|
|
|
TiledGallery.prototype.resizeableElementsSelector =
|
|
'.gallery-row, .gallery-group, .tiled-gallery-item img';
|
|
|
|
/**
|
|
* Story
|
|
*/
|
|
|
|
TiledGallery.prototype.addCaptionEvents = function () {
|
|
// Hide captions
|
|
var galleryCaptions = this.gallery.querySelectorAll( '.tiled-gallery-caption' );
|
|
Array.prototype.forEach.call( galleryCaptions, function ( el ) {
|
|
el.style.display = 'none';
|
|
} );
|
|
|
|
var mouseHoverHandler = function ( e ) {
|
|
var itemEl = e.target.closest( '.tiled-gallery-item' );
|
|
var displayValue = 'mouseover' === e.type ? 'block' : 'none';
|
|
|
|
if ( itemEl ) {
|
|
var itemCaption = itemEl.querySelector( '.tiled-gallery-caption' );
|
|
if ( itemCaption ) {
|
|
itemCaption.style.display = displayValue;
|
|
}
|
|
}
|
|
};
|
|
|
|
// Add hover effects to bring the caption up and down for each item
|
|
this.gallery.addEventListener( 'mouseover', mouseHoverHandler );
|
|
this.gallery.addEventListener( 'mouseout', mouseHoverHandler );
|
|
};
|
|
|
|
TiledGallery.prototype.getExtraDimension = function ( el, attribute, mode ) {
|
|
if ( mode === 'horizontal' ) {
|
|
var left = attribute === 'border' ? 'borderLeftWidth' : attribute + 'Left';
|
|
var right = attribute === 'border' ? 'borderRightWidth' : attribute + 'Right';
|
|
return ( parseInt( el.style[ left ], 10 ) || 0 ) + ( parseInt( el.style[ right ], 10 ) || 0 );
|
|
} else if ( mode === 'vertical' ) {
|
|
var top = attribute === 'border' ? 'borderTopWidth' : attribute + 'Top';
|
|
var bottom = attribute === 'border' ? 'borderBottomWidth' : attribute + 'Bottom';
|
|
return ( parseInt( el.style[ top ], 10 ) || 0 ) + ( parseInt( el.style[ bottom ], 10 ) || 0 );
|
|
}
|
|
return 0;
|
|
};
|
|
|
|
TiledGallery.prototype.resize = function () {
|
|
// Resize everything in the gallery based on the ratio of the current content width
|
|
// to the original content width;
|
|
var originalWidth = parseInt( this.gallery.dataset.originalWidth, 10 );
|
|
var currentWidth = parseFloat(
|
|
getComputedStyle( this.gallery.parentNode, null ).width.replace( 'px', '' )
|
|
);
|
|
var resizeRatio = Math.min( 1, currentWidth / originalWidth );
|
|
|
|
var self = this;
|
|
var resizableElements = this.gallery.querySelectorAll( this.resizeableElementsSelector );
|
|
Array.prototype.forEach.call( resizableElements, function ( el ) {
|
|
var marginWidth = self.getExtraDimension( el, 'margin', 'horizontal' );
|
|
var marginHeight = self.getExtraDimension( el, 'margin', 'vertical' );
|
|
|
|
var paddingWidth = self.getExtraDimension( el, 'padding', 'horizontal' );
|
|
var paddingHeight = self.getExtraDimension( el, 'padding', 'vertical' );
|
|
|
|
var borderWidth = self.getExtraDimension( el, 'border', 'horizontal' );
|
|
var borderHeight = self.getExtraDimension( el, 'border', 'vertical' );
|
|
|
|
// Take all outer dimensions into account when resizing so that images
|
|
// scale with constant empty space between them
|
|
var outerWidth =
|
|
parseInt( el.dataset.originalWidth, 10 ) + paddingWidth + borderWidth + marginWidth;
|
|
var outerHeight =
|
|
parseInt( el.dataset.originalHeight, 10 ) + paddingHeight + borderHeight + marginHeight;
|
|
|
|
// Subtract margins so that images don't overflow on small browser windows
|
|
el.style.width = Math.floor( resizeRatio * outerWidth ) - marginWidth + 'px';
|
|
el.style.height = Math.floor( resizeRatio * outerHeight ) - marginHeight + 'px';
|
|
} );
|
|
};
|
|
|
|
/**
|
|
* Resizing logic
|
|
*/
|
|
|
|
var requestAnimationFrame =
|
|
window.requestAnimationFrame ||
|
|
window.mozRequestAnimationFrame ||
|
|
window.webkitRequestAnimationFrame ||
|
|
window.msRequestAnimationFrame;
|
|
|
|
function attachResizeInAnimationFrames( tiledGalleries ) {
|
|
var resizing = false;
|
|
var resizeTimeout = null;
|
|
|
|
function handleFrame() {
|
|
tiledGalleries.resizeAll();
|
|
if ( resizing ) {
|
|
requestAnimationFrame( handleFrame );
|
|
}
|
|
}
|
|
|
|
window.addEventListener( 'resize', function () {
|
|
clearTimeout( resizeTimeout );
|
|
|
|
if ( ! resizing ) {
|
|
requestAnimationFrame( handleFrame );
|
|
}
|
|
resizing = true;
|
|
resizeTimeout = setTimeout( function () {
|
|
resizing = false;
|
|
}, 15 );
|
|
} );
|
|
}
|
|
|
|
function attachPlainResize( tiledGalleries ) {
|
|
window.addEventListener( 'resize', function () {
|
|
tiledGalleries.resizeAll();
|
|
} );
|
|
}
|
|
|
|
/**
|
|
* Ready, set...
|
|
*/
|
|
function ready( fn ) {
|
|
if ( document.readyState !== 'loading' ) {
|
|
fn();
|
|
} else {
|
|
document.addEventListener( 'DOMContentLoaded', fn );
|
|
}
|
|
}
|
|
ready( function () {
|
|
var tiledGalleries = new TiledGalleryCollection();
|
|
|
|
document.body.addEventListener( 'is.post-load', function () {
|
|
tiledGalleries.findAndSetupNewGalleries();
|
|
} );
|
|
|
|
// Chrome is a unique snow flake and will start lagging on occasion
|
|
// It helps if we only resize on animation frames
|
|
//
|
|
// For other browsers it seems like there is no lag even if we resize every
|
|
// time there is an event
|
|
if ( window.chrome && requestAnimationFrame ) {
|
|
attachResizeInAnimationFrames( tiledGalleries );
|
|
} else {
|
|
attachPlainResize( tiledGalleries );
|
|
}
|
|
|
|
if ( 'undefined' !== typeof wp && wp.customize && wp.customize.selectiveRefresh ) {
|
|
wp.customize.selectiveRefresh.bind( 'partial-content-rendered', function ( placement ) {
|
|
if ( wp.isJetpackWidgetPlaced( placement, 'gallery' ) ) {
|
|
tiledGalleries.findAndSetupNewGalleries();
|
|
}
|
|
} );
|
|
}
|
|
} );
|
|
} )();
|