I'm working on an image gallery, when the user clicks on a photo in the gallery the photo will do a 3D animation to the center of the screen, something like this:
const style = this.state.expanded ? {
transform: 'translate3d(' + this.state.xOffset + 'px, ' + this.state.yOffset + 'px, 10em) scale(2)',
transition: theme.transitions.create('transform')
} : {
transform: 'translate3d(0px, 0px, 0px)',
transition: theme.transitions.create('transform')
}
That style is applied to every image in the gallery, something like:
//react-virtualized grid of: <div ref={this.divElement} style={style as any}> {...etc}</div>
This works fine except 'zIndex' is not respected when transform is applied. I've tried setting a z offset to the translate3D to no avail.
All I really want is for the expanded image to render last and on top of all the other cards.
Here's the root react virtualized component:
class MasonryComponent extends React.Component<IMasonryProps, IMasonryState>
{
state = {
columns: 3
}
_cellPositioner: Positioner | undefined = undefined
// Default sizes help Masonry decide how many images to batch-measure
cache = new CellMeasurerCache({
defaultHeight,
defaultWidth,
fixedWidth: true
});
columnWidth = () => {
const { columnWidth, width } = this.props;
// const newW = width > columnWidth ? columnWidth : width;
return width > columnWidth ? columnWidth : width;
}
_initCellPositioner = () => {
const columnWidth = this.columnWidth()
if (typeof this._cellPositioner === 'undefined') {
this._cellPositioner = createMasonryCellPositioner({
cellMeasurerCache: this.cache,
columnCount: this.state.columns,
columnWidth,
spacer: gutter,
});
}
}
componentWillReceiveProps(nextProps: IMasonryProps) {
if (JSON.stringify(nextProps.items) !== JSON.stringify(this.props.items)) {
this._masonry.current!.clearCellPositions();
this.cache.clearAll();
this.cellPositioner(this.props.width);
this._masonry.current!.clearCellPositions();
}
}
cellPositioner = (width: number): Positioner => {
const columnWidth = this.columnWidth()
const columns = Math.floor(width / columnWidth);
if (this.state.columns != columns)
this.setState({ columns: columns });
this._cellPositioner!.reset({
columnCount: columns,
columnWidth: columnWidth,
spacer: gutter
})
if (this._masonry.current)
this._masonry.current.recomputeCellPositions();
return this._cellPositioner!
}
_masonry = React.createRef<Masonry>()
cellRenderer = ({ index, key, parent, style }: any) => {
const props = this.props;
if (!props.items[index])
return <div>404</div>
const item = props.items[index];
let customRender = props.customRender;
const size = this.props.imageSizeResolve(item);
const columnWidth = this.columnWidth()
return (
<CellMeasurer cache={this.cache} index={index} key={key} parent={parent}>
{customRender ? customRender(item, style, columnWidth) :
<div style={style}>
<img
src={item.url}
style={{
width: columnWidth,
height: columnWidth / size.width * size.height
}}
/>
</div>}
</CellMeasurer>
);
}
public render() {
const props = this.props;
this._initCellPositioner();
const columnWidth = this.columnWidth()
let paddingLeft = props.width < columnWidth ? 0 : (props.width - (columnWidth + gutter) * this.state.columns) / 2
if (paddingLeft < 0) {
paddingLeft = 0;
}
return (
<Masonry
style={{
paddingLeft
}}
overscanByPixels={1080}
ref={this._masonry}
autoHeight={false}
cellCount={props.items ? props.items.length : 0}
cellMeasurerCache={this.cache}
cellPositioner={this.cellPositioner(props.width)}
cellRenderer={this.cellRenderer}
height={props.height}
width={props.width}
/>
);
}
};
Anyway to accomplish this?