From 1a0893d5005fb1f18a782a9d8c8ac809b2092746 Mon Sep 17 00:00:00 2001 From: Yiotis Kaltsikis Date: Mon, 15 Jul 2019 14:14:28 +0200 Subject: [PATCH] Fix layout calculations issues because of gutters --- demo/index.html | 6 +++ .../makeHorizontalLayoutPositions.ts | 13 +++--- .../makeSameHeightLayoutPositions.ts | 46 +++++++++++-------- .../makeSameSizeLayoutPosition.ts | 2 +- .../makeVerticalLayoutPositions.ts | 15 ++++-- 5 files changed, 50 insertions(+), 32 deletions(-) diff --git a/demo/index.html b/demo/index.html index 5378d98..4ac87c9 100644 --- a/demo/index.html +++ b/demo/index.html @@ -541,26 +541,32 @@

Vertical layout

}); new window.Filterizr('.color-container-1', { controlsSelector: '.color-controls-1', + gutterPixels: 10, }); new window.Filterizr('.color-container-2', { controlsSelector: '.color-controls-2', layout: 'sameWidth', + gutterPixels: 10, }); new window.Filterizr('.color-container-3', { controlsSelector: '.color-controls-3', layout: 'sameHeight', + gutterPixels: 10, }); new window.Filterizr('.color-container-4', { controlsSelector: '.color-controls-4', layout: 'packed', + gutterPixels: 10, }); new window.Filterizr('.color-container-5', { controlsSelector: '.color-controls-5', layout: 'horizontal', + gutterPixels: 10, }); new window.Filterizr('.color-container-6', { controlsSelector: '.color-controls-6', layout: 'vertical', + gutterPixels: 10, }); diff --git a/src/makeLayoutPositions/makeHorizontalLayoutPositions.ts b/src/makeLayoutPositions/makeHorizontalLayoutPositions.ts index 4800b36..dd85e5c 100644 --- a/src/makeLayoutPositions/makeHorizontalLayoutPositions.ts +++ b/src/makeLayoutPositions/makeHorizontalLayoutPositions.ts @@ -4,9 +4,9 @@ function calculateWidthSumWithGutters( itemsDimensions: Dimensions[], gutterPixels: number ): number { - return ( - itemsDimensions.reduce((acc, { width }): number => acc + width, 0) + - gutterPixels + return itemsDimensions.reduce( + (acc, { width }): number => acc + width + gutterPixels, + 0 ); } @@ -17,10 +17,9 @@ export default ( itemsDimensions: Dimensions[], gutterPixels: number ): ContainerLayout => ({ - containerHeight: Math.max.apply( - Math, - itemsDimensions.map(({ height }): number => height) - ), + containerHeight: + Math.max(...itemsDimensions.map(({ height }): number => height)) + + gutterPixels * 2, itemsPositions: itemsDimensions.map( ({}, index: number): Position => ({ left: calculateWidthSumWithGutters( diff --git a/src/makeLayoutPositions/makeSameHeightLayoutPositions.ts b/src/makeLayoutPositions/makeSameHeightLayoutPositions.ts index 3c4f346..a354f49 100644 --- a/src/makeLayoutPositions/makeSameHeightLayoutPositions.ts +++ b/src/makeLayoutPositions/makeSameHeightLayoutPositions.ts @@ -1,4 +1,9 @@ -import { ContainerLayout, Position, Dimensions } from '../types/interfaces'; +import { + ContainerLayout, + Position, + Dimensions, + Dictionary, +} from '../types/interfaces'; /** * Same height layout for items that have the same height, but can have varying width @@ -9,36 +14,39 @@ export default ( gutterPixels: number ): ContainerLayout => { const endWidths = itemsDimensions.map(({ width }, index): number => { - const previousItemsWidthSum = itemsDimensions + const prevWidth = itemsDimensions .slice(0, index) - .reduce((sum, { width }): number => sum + width + gutterPixels, 0); - return width + previousItemsWidthSum + gutterPixels; + .reduce((acc, { width }): number => acc + width + gutterPixels * 2, 0); + return prevWidth + width + gutterPixels; }); + const rowStartIndexes: Dictionary = endWidths.reduce( + (acc: Dictionary, width, index): object => { + const accLength = Object.keys(acc).length; + const rowMustBreak = width > containerWidth * accLength; + return { + ...acc, + ...(rowMustBreak && { [accLength]: index }), + }; + }, + { 0: 0 } + ); + const itemsPositions = itemsDimensions.map( ({ height }, index): Position => { const row = Math.floor(endWidths[index] / containerWidth); - const sameRowPreviousItemsWidthSum = itemsDimensions - .slice(0, index) - .filter((_, previousItemIndex): boolean => { - const previousItemRow = Math.floor( - endWidths[previousItemIndex] / containerWidth - ); - return previousItemRow === row; - }) - .reduce((sum, { width }): number => sum + width + gutterPixels, 0); - return { - left: sameRowPreviousItemsWidthSum, + left: itemsDimensions + .slice(rowStartIndexes[row], index) + .reduce((acc, { width }): number => acc + width + gutterPixels, 0), top: (height + gutterPixels) * row, }; } ); - const lastEndWidth = endWidths[endWidths.length - 1]; - const totalRows = Math.floor(lastEndWidth / containerWidth) + 1; - const itemHeight = itemsDimensions[0].height + gutterPixels; - const containerHeight = totalRows * itemHeight + gutterPixels; + const totalRows = Object.keys(rowStartIndexes).length; + const totalItemHeight = itemsDimensions[0].height + gutterPixels; + const containerHeight = totalRows * totalItemHeight + gutterPixels; return { containerHeight, diff --git a/src/makeLayoutPositions/makeSameSizeLayoutPosition.ts b/src/makeLayoutPositions/makeSameSizeLayoutPosition.ts index 73c307c..3bce64c 100644 --- a/src/makeLayoutPositions/makeSameSizeLayoutPosition.ts +++ b/src/makeLayoutPositions/makeSameSizeLayoutPosition.ts @@ -23,7 +23,7 @@ export default ( } ); - const totalRows = Math.floor(itemsDimensions.length / columns) + 1; + const totalRows = Math.ceil(itemsDimensions.length / columns); const firstItemHeight = itemsDimensions[0].height + gutterPixels; const containerHeight = totalRows * firstItemHeight + gutterPixels; diff --git a/src/makeLayoutPositions/makeVerticalLayoutPositions.ts b/src/makeLayoutPositions/makeVerticalLayoutPositions.ts index 4035ad9..4ff2808 100644 --- a/src/makeLayoutPositions/makeVerticalLayoutPositions.ts +++ b/src/makeLayoutPositions/makeVerticalLayoutPositions.ts @@ -4,9 +4,13 @@ function calculateHeightSumWithGutters( itemsDimensions: Dimensions[], gutterPixels: number ): number { - return ( - itemsDimensions.reduce((acc, { height }): number => acc + height, 0) + - gutterPixels + if (!itemsDimensions.length) { + return 0; + } + + return itemsDimensions.reduce( + (acc, { height }): number => acc + height + gutterPixels, + 0 ); } @@ -17,9 +21,10 @@ export default ( itemsDimensions: Dimensions[], gutterPixels: number ): ContainerLayout => ({ - containerHeight: calculateHeightSumWithGutters(itemsDimensions, gutterPixels), + containerHeight: + calculateHeightSumWithGutters(itemsDimensions, gutterPixels) + gutterPixels, itemsPositions: itemsDimensions.map( - ({}, index): Position => ({ + (_, index): Position => ({ left: 0, top: calculateHeightSumWithGutters( itemsDimensions.slice(0, index),