A blazingly fast implementation of the justified layout gallery view popularized by Flickr, written in Rust and exported to WebAssembly. Capable of processing hundreds of thousands of boxes in under a millisecond, or 10 million boxes in under 50ms.
npm i @immich/justified-layout-wasm
Note that you should exclude this package from dependency optimization as it may interfere with the initialization of the Wasm module. For Vite, this means using the optimizeDeps.exclude
field in vite.config.js
:
...
optimizeDeps: {
exclude: ['@immich/justified-layout-wasm'],
},
...
Usage as a native Rust library for non-Wasm targets is not yet supported.
npm run build
import { init, JustifiedLayout } from '@immich/justified-layout-wasm';
// this needs to be called before `JustifiedLayout` can be used with non-empty inputs
await init();
const boxes = [{ width: 160, height: 90 }, { width: 200, height: 100 }, { width: 90, height: 160 }];
const aspectRatios = new Float32Array(boxes.map(({ width, height }) => width / height));
const layout = new JustifiedLayout(aspectRatios, {
rowHeight: 250, // the target height for each row
rowWidth: 600, // the target width for each row
spacing: 4, // spacing between boxes
heightTolerance: 0.1, // allows increasing the height of a row by a certain percentage (10% here) when it doesn't fill the target row width at the target height
});
// maximum width across all rows, used to determine the width of the component containing these rows
const containerWidth = layout.containerWidth;
// total height needed to display all rows, used to determine the height of the component containing these rows
const containerHeight = layout.containerHeight;
for (let i = 0; i < boxes.length; i++) {
// you can use these values to position each box accordingly
const { top, left, width, height } = layout.getPosition(i);
}
PR's are welcome! Also feel free to reach out to the team on Discord.
However, it should be noted that the design intent of this package is to be minimal and high performance. As such, there is limited scope for additional features.