Skip to content

Commit

Permalink
Merge pull request #1482 from silx-kit/min-zoom
Browse files Browse the repository at this point in the history
Allow zooming on very thin selection boxes
  • Loading branch information
axelboc authored Aug 29, 2023
2 parents 855d159 + 602590d commit e53129e
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 10 deletions.
2 changes: 1 addition & 1 deletion packages/lib/src/interactions/SelectToZoom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ function SelectToZoom(props: Props) {
<SelectionTool
id="SelectToZoom"
transform={computeZoomSelection}
validate={({ html }) => Box.fromPoints(...html).hasMinSize(minZoom)}
validate={({ html }) => html[0].manhattanDistanceTo(html[1]) >= minZoom}
onValidSelection={zoomOnSelection}
{...commonProps}
>
Expand Down
6 changes: 5 additions & 1 deletion packages/lib/src/interactions/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@ export function useZoomOnSelection() {

// Update camera scale first (since `moveCameraTo` relies on camera scale)
const { width: zoomWidth, height: zoomHeight } = zoomBox.size;
camera.scale.set(zoomWidth / width, zoomHeight / height, 1);
camera.scale.set(
Math.max(zoomWidth, 1) / width,
Math.max(zoomHeight, 1) / height,
1,
);

// Then move camera position
moveCameraTo(zoomBox.center);
Expand Down
15 changes: 7 additions & 8 deletions packages/lib/src/interactions/svg/SvgRect.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type { SVGProps } from 'react';

import Box from '../box';
import type { Rect } from '../models';

interface Props extends SVGProps<SVGRectElement> {
interface Props extends SVGProps<SVGPathElement> {
coords: Rect;
strokePosition?: 'inside' | 'outside'; // no effect without `stroke` prop; assumes `strokeWidth` of 1 unless specified explicitely as prop (CSS ignored)
strokeWidth?: number; // forbid string
Expand All @@ -11,22 +12,20 @@ interface Props extends SVGProps<SVGRectElement> {
function SvgRect(props: Props) {
const { coords, strokePosition, ...svgProps } = props;

const [start, end] = coords;
const { stroke, strokeWidth = 1 } = svgProps;

// Shrink/grow rectangle to simulate positioning stroke inside/outside
// https://stackoverflow.com/questions/7241393/can-you-control-how-an-svgs-stroke-width-is-drawn
const offset =
stroke && strokePosition
? (strokeWidth / 2) * (strokePosition === 'inside' ? 1 : -1)
? strokeWidth * (strokePosition === 'outside' ? 1 : -1)
: 0;

const { min, max } = Box.fromPoints(...coords).expandBySize(offset, offset);

return (
<rect
x={Math.min(start.x, end.x) + offset}
y={Math.min(start.y, end.y) + offset}
width={Math.abs(end.x - start.x) - offset * 2}
height={Math.abs(end.y - start.y) - offset * 2}
<path
d={`M ${min.x},${min.y} H ${max.x} V ${max.y} H ${min.x} z`}
{...svgProps}
/>
);
Expand Down

0 comments on commit e53129e

Please sign in to comment.