Merge pull request #11 from captbaritone/zoom

Zoom
This commit is contained in:
Jordan Eldredge 2022-01-08 19:46:27 -08:00 committed by GitHub
commit 3f9aa0c2cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 159 additions and 20 deletions

View file

@ -197,4 +197,21 @@ body.webamp-loaded #webamp {
.tinder-card {
position: absolute;
width: 100%;
}
}
#zoom button {
color: rgba(255, 2550, 2550, 0.9);
}
#zoom button:active, #zoom button:disabled {
color: grey;
}
@media (hover: hover) {
#zoom {
opacity: 0.7;
transition: opacity 200ms ease-in-out;
}
#zoom:hover {
opacity: 1;
}
}

View file

@ -20,7 +20,7 @@ import { useDropzone } from "react-dropzone";
import ReviewPage from "./ReviewPage";
const getTableDimensions = (windowWidth, scale) => {
const columnCount = Math.floor(windowWidth / (SCREENSHOT_WIDTH * scale));
const columnCount = Math.round(windowWidth / (SCREENSHOT_WIDTH * scale));
const columnWidth = windowWidth / columnCount; // TODO: Consider flooring this to get things aligned to the pixel
const rowHeight = columnWidth * SKIN_RATIO;
return { columnWidth, rowHeight, columnCount };

View file

@ -60,7 +60,6 @@ function Header() {
const showFeedbackForm = useActionCreator(Actions.showFeedbackForm);
const requestRandomSkin = useActionCreator(Actions.requestedRandomSkin);
const requestedAboutPage = useActionCreator(Actions.requestedAboutPage);
// const setScale = useActionCreator((scale) => ({ type: "SET_SCALE", scale }));
const setInput = useFocusOnSlash();
return (
@ -122,6 +121,7 @@ function Header() {
onClick={() => {
requestRandomSkin();
}}
title="Random Skin"
style={{
paddingLeft: "0.2rem",
paddingRight: "0.2rem",

View file

@ -1,4 +1,4 @@
import React from "react";
import React, { useMemo } from "react";
import "./App.css";
import { connect } from "react-redux";
import * as Selectors from "./redux/selectors";
@ -6,6 +6,7 @@ import * as Actions from "./redux/actionCreators";
import { FixedSizeGrid as Grid } from "react-window";
import Cell from "./Cell";
import { HEADING_HEIGHT } from "./constants";
import Zoom from "./Zoom";
const SkinTable = ({
columnCount,
@ -30,31 +31,56 @@ const SkinTable = ({
return skin ? skin.hash : `unfectched-index-${requestToken}`;
}
const gridRef = React.useRef();
const itemRef = React.useRef();
React.useLayoutEffect(() => {
if (gridRef.current == null) {
return;
}
gridRef.current.scrollTo({ scrollLeft: 0, scrollTop: 0 });
}, [skinCount]);
React.useLayoutEffect(() => {
if (gridRef.current == null) {
return;
}
const itemRow = Math.floor(itemRef.current / columnCount);
gridRef.current.scrollTo({ scrollLeft: 0, scrollTop: rowHeight * itemRow });
}, [rowHeight, columnCount]);
const showGrid = loadingSearchQuery || skinCount > 0 || searchQuery === "";
const onScroll = useMemo(() => {
const half = Math.round(columnCount / 2);
return (scrollData) => {
itemRef.current =
Math.round(scrollData.scrollTop / rowHeight) * columnCount + half;
};
}, [columnCount, rowHeight]);
return (
<div id="infinite-skins" style={{ marginTop: HEADING_HEIGHT }}>
{showGrid ? (
<Grid
ref={gridRef}
itemKey={itemKey}
itemData={{ columnCount, width: columnWidth, height: rowHeight }}
columnCount={columnCount}
columnWidth={columnWidth}
height={windowHeight - HEADING_HEIGHT}
rowCount={Math.ceil(skinCount / columnCount)}
rowHeight={rowHeight}
width={windowWidth}
overscanRowsCount={5}
style={{ overflowY: "scroll" }}
>
{Cell}
</Grid>
<>
<Grid
ref={gridRef}
itemKey={itemKey}
itemData={{ columnCount, width: columnWidth, height: rowHeight }}
columnCount={columnCount}
columnWidth={columnWidth}
height={windowHeight - HEADING_HEIGHT}
rowCount={Math.ceil(skinCount / columnCount)}
rowHeight={rowHeight}
width={windowWidth}
overscanRowsCount={5}
onScroll={onScroll}
style={{ overflowY: "scroll" }}
>
{Cell}
</Grid>
<Zoom columnCount={columnCount} windowWidth={windowWidth} />
</>
) : (
<div
style={{

97
src/Zoom.js Normal file
View file

@ -0,0 +1,97 @@
import React from "react";
import { useActionCreator } from "./hooks";
import { SCREENSHOT_WIDTH } from "./constants";
function getScaleForColumnCount(columnCount, windowWidth) {
return windowWidth / (columnCount * SCREENSHOT_WIDTH);
}
const BACKGROUND_COLOR = "#000";
const Zoom = ({ columnCount, windowWidth }) => {
const scaleUp = getScaleForColumnCount(columnCount - 1, windowWidth);
const scaleDown = getScaleForColumnCount(columnCount + 1, windowWidth);
const zoom = useActionCreator((scale) => ({ type: "SET_SCALE", scale }));
const zoomIn = () => zoom(scaleUp);
const zoomOut = () => zoom(scaleDown);
return (
<div
id="zoom"
style={{
position: "absolute",
backgroundColor: BACKGROUND_COLOR,
background: `linear-gradient(
0deg,
rgba(17, 17, 25, 1) 0%,
rgba(40, 39, 66, 1) 66%,
rgba(25, 25, 39, 1) 100%
)`,
boxShadow: "10px 10px 15px 0px rgb(0 0 0 / 85%)",
bottom: 5,
right: 5,
display: "flex",
flexDirection: "column",
border: "1px solid black",
borderStyle: "solid",
borderWidth: "1px",
borderBottomColor: "rgb(87, 86, 102)",
borderTopColor: "rgb(32, 31, 51)",
borderRadius: 5,
}}
>
<Button
title={"Zoom In"}
onClick={zoomIn}
disabled={scaleUp * SCREENSHOT_WIDTH >= 400}
style={{ margin: 0 }}
>
+
</Button>
<hr
style={{
border: "none",
backgroundColor: "rgba(255, 2550, 2550, 0.2)",
color: "rgba(255, 2550, 2550, 0.4)",
height: 1,
marginTop: 0,
marginBottom: 0,
marginLeft: 3,
marginRight: 3,
padding: 0,
}}
/>
<Button
onClick={zoomOut}
title={"Zoom Out"}
disabled={scaleDown * SCREENSHOT_WIDTH <= 100}
>
{""}
</Button>
</div>
);
};
function Button({ ...props }) {
return (
<button
{...props}
title={props.disabled ? `${props.title} (disabled)` : props.title}
style={{
margin: 0,
border: "none",
cursor: props.disabled ? "default" : "pointer",
font: "inherit",
fontWeight: 'bold',
outline: "inherit",
background: "none",
paddingLeft: 14,
paddingRight: 14,
paddingTop: 9,
paddingBottom: 9,
}}
/>
);
}
export default Zoom;

View file

@ -1,6 +1,5 @@
const urlSearchParams = new URLSearchParams(window.location.search);
const params = Object.fromEntries(urlSearchParams.entries());
console.log(params)
export const SCREENSHOT_WIDTH = 275;
export const SCREENSHOT_HEIGHT = 348;