Skip to content

Commit

Permalink
feat: improve zoom
Browse files Browse the repository at this point in the history
  • Loading branch information
AriTheElk committed Dec 15, 2024
1 parent d768104 commit b31186d
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 20 deletions.
26 changes: 14 additions & 12 deletions src/client/ImagePickerView/ImagePickerView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,18 @@ export const ImagePickerView = () => {
const [loadedImages, setLoadedImages] = useState<Record<string, string>>({})
const [nextImageIndex, setNextImageIndex] = useState(0)

const [rowHeight, setRowHeight] = useState(
(plugin.settings.zoom || DEFAULT_SETTINGS.zoom) * ROW_HEIGHT
const hydratedCSS = useRef(false)
const [zoom, setZoom] = useState(
plugin.settings.zoom || DEFAULT_SETTINGS.zoom
)
const [rowHeight, setRowHeight] = useState(zoom * ROW_HEIGHT)

const [zoom, setZoom] = useState(1)
useEffect(() => {
if (!hydratedCSS.current) {
setGridHeight(zoom)
hydratedCSS.current = true
}
}, [zoom])

const updateZoomSetting = useMemo(
() =>
Expand Down Expand Up @@ -182,12 +189,9 @@ export const ImagePickerView = () => {
(container: HTMLDivElement) => {
const height = container.clientHeight
const width = container.clientWidth

const newRows = Math.floor(height / ROW_HEIGHT)
const newColumns = calculateGrid(gridRef, width, rowHeight)

setColumns(newColumns)
setItemsPerPage(newRows * newColumns)
const [col, row] = calculateGrid(gridRef, [width, height], rowHeight)
setColumns(col)
setItemsPerPage(col * row)
},
[rowHeight]
)
Expand Down Expand Up @@ -294,13 +298,11 @@ export const ImagePickerView = () => {
*/
useEffect(() => {
if (!isEqual(images, cachedImages.current)) {
console.log('Images changed:', images.length)
setLoadedImages({})
setNextImageIndex(0)
setCurrentPage(1)
cachedImages.current = images
}
}, [images])
}, [images, totalPages])

return (
<>
Expand Down
4 changes: 2 additions & 2 deletions src/client/ImagePickerView/Pagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ export const Pagination: FC<PaginationProps> = ({
onZoom,
}) => {
return (
<div className="image-picker-pagination">
<div className="image-picker-footer">
<button onClick={onPrev} disabled={current === 1}>
Previous
</button>
<input
type="range"
min={MIN_THUMBNAIL_ZOOM}
max={MAX_THUMBNAIL_ZOOM}
step={0.1}
step={0.025}
value={zoom}
onChange={(e) => onZoom(parseFloat(e.target.value))}
/>
Expand Down
2 changes: 1 addition & 1 deletion src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,5 @@ export const DEFAULT_SETTINGS: ImagePickerSettings = {
* The zoom is applied to the baseline ROW_HEIGHT
* to determine the thumbnail size.
*/
export const MIN_THUMBNAIL_ZOOM = 0.8
export const MIN_THUMBNAIL_ZOOM = 0.5
export const MAX_THUMBNAIL_ZOOM = 2
30 changes: 25 additions & 5 deletions src/styles.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
$header-height: 60px;
$footer-height: 40px;

.image-picker-responsive-container {
width: 100%;
height: 100%;
}

.image-picker-controls {
width: 100%;
height: $header-height;
Expand All @@ -25,10 +30,10 @@ $footer-height: 40px;

.image-picker-grid {
position: relative;
height: 100%;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
grid-gap: 10px;
padding: 0 10px;
}

.image-picker-item {
Expand All @@ -39,7 +44,8 @@ $footer-height: 40px;
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
overflow: hidden;
height: 100px;
height: var(--image-picker-grid-height);
min-height: var(--image-picker-grid-height);

img {
max-width: 100%;
Expand All @@ -62,20 +68,34 @@ $footer-height: 40px;
}
}

.image-picker-pagination {
.image-picker-footer {
width: 100%;
height: $footer-height;
display: flex;
justify-content: space-between;
padding: 0 0.5rem;
align-items: center;
flex: 0 0 auto;
margin-top: 1rem;

> *:first-child {
margin-left: 0;
}

> *:last-child {
margin-right: 0;
}

button {
margin: 0 5px;
padding: 5px 10px;
font-size: 14px;
font-size: 12px;
cursor: pointer;
flex: 0 0 auto;
}

input[type='range'] {
flex: 1 1 auto;
margin: 0 5px;
}
}

Expand Down
34 changes: 34 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,37 @@ export const nodeToEmbed = (
export const truncate = (text: string, length: number): string => {
return text.length > length ? `${text.substring(0, length)}...` : text
}

export const setGridHeight = (zoom: number): void => {
document.documentElement.style.setProperty(
'--image-picker-grid-height',
ROW_HEIGHT * zoom + 'px'
)
}

/**
* Returns the number of columns and rows that can fit in the container
*
* The height is always fixed, so we first calculate the rnumber of
* columns that can fit in the container, then calculate the number of
* rows based on the container size and the asset height.
*/
export const calculateGrid = (
gridRef: React.RefObject<HTMLDivElement | null>,
containerSize: [number, number],
assetHeight: number
): [number, number] => {
if (gridRef.current) {
const [containerWidth, containerHeight] = containerSize
const computedStyle = window.getComputedStyle(gridRef.current)
const gap = parseInt(computedStyle.getPropertyValue('gap'), 10) || 0
const totalGapsWidth =
containerWidth < assetHeight * 2 + gap
? 0
: gap * (Math.floor(containerWidth / assetHeight) - 1)
const columns = Math.floor((containerWidth - totalGapsWidth) / assetHeight)
const rows = Math.floor(containerHeight / (assetHeight + gap))
return [columns, rows]
}
return [0, 0]
}

0 comments on commit b31186d

Please sign in to comment.