import { ratio } from './ratio' ; import { round } from './round' ; import { findShortestPath } from './dijkstra' ; const getCommonHeight = ( row , containerWidth , margin ) => { const rowWidth = containerWidth - row . length * ( margin * 2 ) ; const totalAspectRatio = row . reduce ( ( acc , photo ) => acc + ratio ( photo ) , 0 ) ; return rowWidth / totalAspectRatio ; } ; const cost = ( photos , i , j , width , targetHeight , margin ) => { const row = photos . slice ( i , j ) ; const commonHeight = getCommonHeight ( row , width , margin ) ; return Math . pow ( Math . abs ( commonHeight - targetHeight ) , 2 ) ; } ; const makeGetNeighbors = ( targetHeight , containerWidth , photos , limitNodeSearch , margin ) => ( start ) => { const results = { } ; start = + start ; results [ + start ] = 0 ; for ( let i = start + 1 ; i < photos . length + 1 ; ++ i ) { if ( i - start > limitNodeSearch ) break ; results [ i . toString ( ) ] = cost ( photos , start , i , containerWidth , targetHeight , margin ) ; } return results ; } ; export const computeRowLayout = ( { containerWidth , limitNodeSearch , targetRowHeight , margin , photos , } ) => { const getNeighbors = makeGetNeighbors ( targetRowHeight , containerWidth , photos , limitNodeSearch , margin ) ; let path = findShortestPath ( getNeighbors , '0' , photos . length ) ; path = path . map ( ( node ) => + node ) ; for ( let i = 1 ; i < path . length ; ++ i ) { const row = photos . slice ( path [ i - 1 ] , path [ i ] ) ; const height = getCommonHeight ( row , containerWidth , margin ) ; for ( let j = path [ i - 1 ] ; j < path [ i ] ; ++ j ) { photos [ j ] . width = round ( height * ratio ( photos [ j ] ) , 1 ) ; photos [ j ] . height = height ; } } return photos ; } ;