Use justified layout for wall (#218)

This commit is contained in:
WithoutPants 2019-11-18 08:43:14 +11:00 committed by Leopere
parent 23657408de
commit 7f03f48310
6 changed files with 72 additions and 4 deletions

View file

@ -19,6 +19,7 @@
"bulma": "0.7.5",
"formik": "1.5.7",
"graphql": "14.3.1",
"justified-layout": "^3.0.0",
"localforage": "1.7.3",
"lodash": "4.17.13",
"node-sass": "4.12.0",

View file

@ -11,10 +11,18 @@ interface IWallItemProps {
scene?: GQL.SlimSceneDataFragment;
sceneMarker?: GQL.SceneMarkerDataFragment;
origin?: string;
position?: IWallItemPosition;
onOverlay: (show: boolean) => void;
clickHandler?: (item: GQL.SlimSceneDataFragment | GQL.SceneMarkerDataFragment) => void;
}
export interface IWallItemPosition {
top: number,
width: number,
height: number,
left: number
}
export const WallItem: FunctionComponent<IWallItemProps> = (props: IWallItemProps) => {
const [videoPath, setVideoPath] = useState<string | undefined>(undefined);
const [previewPath, setPreviewPath] = useState<string>("");
@ -96,12 +104,20 @@ export const WallItem: FunctionComponent<IWallItemProps> = (props: IWallItemProp
const className = ["scene-wall-item-container"];
if (videoHoverHook.isHovering.current) { className.push("double-scale"); }
const style: React.CSSProperties = {};
if (!!props.position) {
let position = props.position;
style.width = position.width;
style.height = position.height;
style.left = position.left;
style.top = position.top;
}
if (!!props.origin) { style.transformOrigin = props.origin; }
return (
<div className="wall grid-item">
<div style={style} className="wall grid-item">
<div
className={className.join(" ")}
style={style}
onTransitionEnd={onTransitionEnd}
onMouseEnter={() => debouncedOnMouseEnter.current()}
onMouseMove={() => debouncedOnMouseEnter.current()}

View file

@ -1,8 +1,9 @@
import _ from "lodash";
import React, { FunctionComponent, useState } from "react";
import React, { FunctionComponent, useState, useEffect } from "react";
import * as GQL from "../../core/generated-graphql";
import "./Wall.scss";
import { WallItem } from "./WallItem";
import { WallItem, IWallItemPosition } from "./WallItem";
import justifiedLayout from "justified-layout";
interface IWallPanelProps {
scenes?: GQL.SlimSceneDataFragment[];
@ -12,6 +13,36 @@ interface IWallPanelProps {
export const WallPanel: FunctionComponent<IWallPanelProps> = (props: IWallPanelProps) => {
const [showOverlay, setShowOverlay] = useState<boolean>(false);
const [wallItemPositions, setWallItemPositions] = useState<IWallItemPosition[]>([]);
useEffect(() => {
if (!props.scenes) {
setWallItemPositions([]);
} else {
// need to get all of the aspect ratios
var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
w = w * 0.8;
let newSceneAspectRatios = props.scenes.map((scene) => {
const defaultAspectRatio = 4 / 3;
if (!scene.file.width || !scene.file.height) {
return defaultAspectRatio;
}
return scene.file.width / scene.file.height;
});
const rowHeight = 290;
const heightTolerance = 0.1;
let layoutGeo = justifiedLayout(newSceneAspectRatios, {
containerWidth: w,
targetRowHeight: rowHeight,
targetRowHeightTolerance: heightTolerance,
boxSpacing: { horizontal: 0, vertical: 0 }
});
setWallItemPositions(layoutGeo.boxes as IWallItemPosition[]);
}
}, [props.scenes]);
function onOverlay(show: boolean) {
setShowOverlay(show);
@ -51,6 +82,7 @@ export const WallPanel: FunctionComponent<IWallPanelProps> = (props: IWallPanelP
onOverlay={onOverlay}
clickHandler={props.clickHandler}
origin={origin}
position={wallItemPositions[index]}
/>
);
});

View file

@ -43,6 +43,7 @@ code {
&.wall {
padding: 0;
margin: 0;
position: relative;
}
& .bp3-button.favorite .bp3-icon {
@ -75,6 +76,7 @@ code {
&.wall {
width: calc(20%);
margin: 0;
position: static;
}
}

View file

@ -0,0 +1,5 @@
declare module "justified-layout" {
// typing module default export as `any` will allow you to access its members without compiler warning
var justifiedLayout: any;
export default justifiedLayout;
}

View file

@ -7286,6 +7286,13 @@ jsx-ast-utils@^2.0.1:
dependencies:
array-includes "^3.0.3"
justified-layout@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/justified-layout/-/justified-layout-3.0.0.tgz#f8643ac51d97cf43dd40ddf38601161968ff8165"
integrity sha512-xki5bVJ84HokIV47mfHdmWB56zFrQKbtrU5KHA5GoatOnRwQWGOvNtBlbW8dU0yIa3pNmCPuacuuMRPvM9p5mg==
dependencies:
merge "1.2.1"
keycode@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.2.0.tgz#3d0af56dc7b8b8e5cba8d0a97f107204eec22b04"
@ -7798,6 +7805,11 @@ merge2@^1.2.3:
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5"
integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA==
merge@1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145"
integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==
methods@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"