Skip to content

Commit

Permalink
Implement basic Mosaic layout (#21767)
Browse files Browse the repository at this point in the history
  • Loading branch information
guarani authored Nov 25, 2021
1 parent 7aa36ef commit 653cbbe
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ import { useResizeObserver } from '@wordpress/compose';
/**
* Internal dependencies
*/
import { ALLOWED_MEDIA_TYPES } from './constants';
import { ALLOWED_MEDIA_TYPES, LAYOUT_STYLES } from './constants';
import { icon } from '.';
import styles from './styles.scss';
import TiledGallerySettings, { DEFAULT_COLUMNS, MAX_COLUMNS } from './settings';
import { getActiveStyleName } from '../../shared/block-styles';

const TILE_SPACING = 8;

Expand Down Expand Up @@ -100,13 +101,15 @@ const TiledGalleryEdit = props => {
}, [ columns, images, setAttributes ] );

const populateInnerBlocksWithImages = ( imgs, replace = false ) => {
const layoutStyle = getActiveStyleName( LAYOUT_STYLES, className );

const newBlocks = imgs.map( image => {
return createBlock( 'core/image', {
id: image.id,
url: image.url,
caption: image.caption,
alt: image.alt,
className: styles[ 'is-style-squared' ],
className: styles[ `is-style-${ layoutStyle }` ],
} );
} );

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
import { Component, createRef } from '@wordpress/element';
import { Component, createRef, Platform } from '@wordpress/element';
import ResizeObserver from 'resize-observer-polyfill';

/**
Expand All @@ -10,7 +10,7 @@ import ResizeObserver from 'resize-observer-polyfill';
import Column from '../column';
import Gallery from '../gallery';
import Row from '../row';
import { getGalleryRows, handleRowResize } from './resize';
import { getGalleryRows, handleRowResize, getColumnWidths } from './resize';
import { imagesToRatios, ratiosToColumns, ratiosToMosaicRows } from './ratios';

export default class Mosaic extends Component {
Expand Down Expand Up @@ -84,14 +84,19 @@ export default class Mosaic extends Component {
}

render() {
const { align, columns, images, layoutStyle, renderedImages, columnWidths } = this.props;
const { align, columns, images, layoutStyle, renderedImages } = this.props;

const ratios = imagesToRatios( images );
const rows =
'columns' === layoutStyle
? ratiosToColumns( ratios, columns )
: ratiosToMosaicRows( ratios, { isWide: [ 'full', 'wide' ].includes( align ) } );

const columnWidths = Platform.select( {
web: this.props.columnWidths,
native: getColumnWidths( rows, renderedImages, 1000 ),
} );

let cursor = 0;
return (
<Gallery galleryRef={ this.gallery }>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* WordPress dependencies
*/
import { Platform } from '@wordpress/element';

/**
* Internal dependencies
*/
Expand Down Expand Up @@ -32,18 +37,39 @@ function getRowRatio( row ) {
return result;
}

export function getColumnWidths( rows, images, width ) {
let cursor = 0;
const content = rows.map( row => {
return row.map( colSize => {
const columnImages = images.slice( cursor, cursor + colSize );
cursor += colSize;
return columnImages;
} );
} );

const result = content.map( row => handleRowResize( row, width ) );
return result;
}

export function getGalleryRows( gallery ) {
return Array.from( gallery.querySelectorAll( '.tiled-gallery__row' ) );
}

function getRowCols( row ) {
return Array.from( row.querySelectorAll( '.tiled-gallery__col' ) );
return Platform.select( {
web: () => Array.from( row.querySelectorAll( '.tiled-gallery__col' ) ),
native: () => row,
} )();
}

function getColImgs( col ) {
return Array.from(
col.querySelectorAll( '.tiled-gallery__item > img, .tiled-gallery__item > a > img' )
);
return Platform.select( {
web: () =>
Array.from(
col.querySelectorAll( '.tiled-gallery__item > img, .tiled-gallery__item > a > img' )
),
native: () => col.map( img => img.props ),
} )();
}

function getColumnRatio( col ) {
Expand All @@ -59,36 +85,53 @@ function getColumnRatio( col ) {
}

function getImageRatio( img ) {
const w = parseInt( img.dataset.width, 10 );
const h = parseInt( img.dataset.height, 10 );
const w = Platform.select( {
web: () => parseInt( img.dataset.width, 10 ),
native: () => img.width,
} )();
const h = Platform.select( {
web: () => parseInt( img.dataset.height, 10 ),
native: () => img.height,
} )();
const result = w && ! Number.isNaN( w ) && h && ! Number.isNaN( h ) ? w / h : 1;
return result;
}

function applyRowRatio( row, [ ratio, weightedRatio ], width ) {
const rawHeight =
( 1 / ratio ) * ( width - GUTTER_WIDTH * ( row.childElementCount - 1 ) - weightedRatio );
const colCount = Platform.select( {
web: () => row.childElementCount,
native: () => row.length,
} )();
const rawHeight = ( 1 / ratio ) * ( width - GUTTER_WIDTH * ( colCount - 1 ) - weightedRatio );

return applyColRatio( row, {
rawHeight,
rowWidth: width - GUTTER_WIDTH * ( row.childElementCount - 1 ),
rowWidth: width - GUTTER_WIDTH * ( colCount - 1 ),
} );
}

function applyColRatio( row, { rawHeight, rowWidth } ) {
const cols = getRowCols( row );

const colWidths = cols.map(
col => ( rawHeight - GUTTER_WIDTH * ( col.childElementCount - 1 ) ) * getColumnRatio( col )[ 0 ]
);
const colWidths = cols.map( col => {
const imgCount = Platform.select( {
web: () => col.childElementCount,
native: () => col.length,
} )();
return ( rawHeight - GUTTER_WIDTH * ( imgCount - 1 ) ) * getColumnRatio( col )[ 0 ];
} );

const adjustedWidths = adjustFit( colWidths, rowWidth );

cols.forEach( ( col, i ) => {
const rawWidth = colWidths[ i ];
const width = adjustedWidths[ i ];
const imgCount = Platform.select( {
web: () => col.childElementCount,
native: () => col.length,
} )();
applyImgRatio( col, {
colHeight: rawHeight - GUTTER_WIDTH * ( col.childElementCount - 1 ),
colHeight: rawHeight - GUTTER_WIDTH * ( imgCount - 1 ),
width,
rawWidth,
} );
Expand All @@ -105,9 +148,13 @@ function applyImgRatio( col, { colHeight, width, rawWidth } ) {
const imgHeights = getColImgs( col ).map( img => rawWidth / getImageRatio( img ) );
const adjustedHeights = adjustFit( imgHeights, colHeight );

// Set size of col children, not the <img /> element
Array.from( col.children ).forEach( ( item, i ) => {
const height = adjustedHeights[ i ];
item.setAttribute( 'style', `height:${ height }px;width:${ width }px;` );
Platform.select( {
web: () => {
// Set size of col children, not the <img /> element
Array.from( col.children ).forEach( ( item, i ) => {
const height = adjustedHeights[ i ];
item.setAttribute( 'style', `height:${ height }px;width:${ width }px;` );
} );
},
} );
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
*/
import Layout from './layout';
import { defaultColumnsNumber } from './edit';
import { getActiveStyleName } from '../../shared/block-styles';
import { LAYOUT_STYLES } from './constants';

export default function TiledGallerySave( { attributes, innerBlocks } ) {
if ( ! attributes.images.length && ! innerBlocks.length ) {
Expand Down Expand Up @@ -31,14 +33,16 @@ export default function TiledGallerySave( { attributes, innerBlocks } ) {
ids,
} = attributes;

const layoutStyle = getActiveStyleName( LAYOUT_STYLES, className );

return (
<Layout
align={ align }
className={ className }
columns={ columns }
images={ images }
isSave
layoutStyle={ 'square' }
layoutStyle={ layoutStyle }
linkTo={ linkTo }
roundedCorners={ roundedCorners }
columnWidths={ columnWidths }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
aspect-ratio: 1;
}

.is-style-rectangular {
aspect-ratio: 1;
}

.cellRowStyles {
flex-shrink: 1;
}
Expand Down

0 comments on commit 653cbbe

Please sign in to comment.