Skip to content

Commit

Permalink
Merge pull request #349 from quadratichq/zoom-to-selection
Browse files Browse the repository at this point in the history
Zoom to selection
  • Loading branch information
jimniels authored Mar 14, 2023
2 parents 72f4380 + ee352c8 commit c4c2aac
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 11 deletions.
1 change: 1 addition & 0 deletions src/constants/gridConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export const CELL_TEXT_MARGIN_TOP = -1;
export const GRID_SIZE = 150;
export const ZOOM_ANIMATION_TIME_MS = 250;
export const HEADING_SIZE = 20;
export const ZOOM_BUFFER = 1.2;
40 changes: 34 additions & 6 deletions src/gridGL/helpers/zoom.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as PIXI from 'pixi.js';
import { Rectangle, Point } from 'pixi.js';
import { Viewport } from 'pixi-viewport';
import { Sheet } from '../../grid/sheet/Sheet';
import { ZOOM_ANIMATION_TIME_MS } from '../../constants/gridConstants';
import { ZOOM_ANIMATION_TIME_MS, ZOOM_BUFFER } from '../../constants/gridConstants';
import { GridInteractionState } from '../../atoms/gridInteractionStateAtom';

export function zoomToFit(sheet: Sheet, viewport: Viewport): void {
const gridBounds = sheet.getGridBounds(false);
Expand All @@ -14,14 +15,14 @@ export function zoomToFit(sheet: Sheet, viewport: Viewport): void {
);

// calc scale, and leave a little room on the top and sides
let scale = viewport.findFit(screenRectangle.width * 1.2, screenRectangle.height * 1.2);
let scale = viewport.findFit(screenRectangle.width * ZOOM_BUFFER, screenRectangle.height * ZOOM_BUFFER);

// Don't zoom in more than a factor of 2
if (scale > 2.0) scale = 2;
if (scale > 2) scale = 2;

viewport.animate({
time: ZOOM_ANIMATION_TIME_MS,
position: new PIXI.Point(
position: new Point(
screenRectangle.x + screenRectangle.width / 2,
screenRectangle.y + screenRectangle.height / 2
),
Expand All @@ -30,7 +31,7 @@ export function zoomToFit(sheet: Sheet, viewport: Viewport): void {
} else {
viewport.animate({
time: ZOOM_ANIMATION_TIME_MS,
position: new PIXI.Point(0, 0),
position: new Point(0, 0),
scale: 1,
});
}
Expand All @@ -54,3 +55,30 @@ export function zoomOut(viewport: Viewport) {
export function zoomTo100(viewport: Viewport) {
zoomInOut(viewport, 1);
}

export function zoomToSelection(interactionState: GridInteractionState, sheet: Sheet, viewport: Viewport): void {
let screenRectangle: Rectangle;
if (interactionState.showMultiCursor) {
const cursor = interactionState.multiCursorPosition;
screenRectangle = sheet.gridOffsets.getScreenRectangle(
cursor.originPosition.x,
cursor.originPosition.y,
cursor.terminalPosition.x - cursor.originPosition.x,
cursor.terminalPosition.y - cursor.originPosition.y
);
} else {
const cursor = interactionState.cursorPosition;
screenRectangle = sheet.gridOffsets.getScreenRectangle(cursor.x, cursor.y, 1, 1);
}
// calc scale, and leave a little room on the top and sides
let scale = viewport.findFit(screenRectangle.width * ZOOM_BUFFER, screenRectangle.height * ZOOM_BUFFER);

// Don't zoom in more than a factor of 2
if (scale > 2) scale = 2;

viewport.animate({
time: ZOOM_ANIMATION_TIME_MS,
position: new Point(screenRectangle.x + screenRectangle.width / 2, screenRectangle.y + screenRectangle.height / 2),
scale,
});
}
10 changes: 9 additions & 1 deletion src/gridGL/interaction/keyboard/keyboardViewport.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { Viewport } from 'pixi-viewport';
import { MultipleFormat } from '../../../ui/menus/TopBar/SubMenus/useGetSelection';
import { Sheet } from '../../../grid/sheet/Sheet';
import { zoomIn, zoomOut, zoomTo100, zoomToFit } from '../../helpers/zoom';
import { zoomIn, zoomOut, zoomTo100, zoomToFit, zoomToSelection } from '../../helpers/zoom';
import { EditorInteractionState } from '../../../atoms/editorInteractionStateAtom';
import { Pointer } from '../pointer/Pointer';
import { GridInteractionState } from '../../../atoms/gridInteractionStateAtom';

export function keyboardViewport(options: {
event: KeyboardEvent;
sheet: Sheet;
viewport?: Viewport;
interactionState: GridInteractionState;
editorInteractionState: EditorInteractionState;
setEditorInteractionState: React.Dispatch<React.SetStateAction<EditorInteractionState>>;
clearAllFormatting: Function;
Expand All @@ -27,6 +29,7 @@ export function keyboardViewport(options: {
format,
sheet,
viewport,
interactionState,
editorInteractionState,
setEditorInteractionState,
presentationMode,
Expand Down Expand Up @@ -90,6 +93,11 @@ export function keyboardViewport(options: {
return true;
}

if ((event.metaKey || event.ctrlKey) && event.code === 'Digit8') {
zoomToSelection(interactionState, sheet, viewport);
return true;
}

if ((event.metaKey || event.ctrlKey) && event.code === 'Digit9') {
zoomToFit(sheet, viewport);
return true;
Expand Down
3 changes: 2 additions & 1 deletion src/gridGL/interaction/keyboard/useKeyboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export const useKeyboard = (props: IProps): { onKeyDown: (event: React.KeyboardE
if (
keyboardViewport({
event,
interactionState,
editorInteractionState,
setEditorInteractionState,
viewport: app?.viewport,
Expand All @@ -65,7 +66,7 @@ export const useKeyboard = (props: IProps): { onKeyDown: (event: React.KeyboardE
}
},
[
interactionState.showInput,
interactionState,
editorInteractionState,
setEditorInteractionState,
app?.viewport,
Expand Down
6 changes: 5 additions & 1 deletion src/gridGL/pixiApp/PixiApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { AxesLines } from '../UI/AxesLines';
import { GridHeadings } from '../UI/gridHeadings/GridHeadings';
import { Cursor } from '../UI/Cursor';
import { Cells } from '../UI/cells/Cells';
import { zoomInOut, zoomToFit } from '../helpers/zoom';
import { zoomInOut, zoomToFit, zoomToSelection } from '../helpers/zoom';
import { Quadrants } from '../quadrants/Quadrants';
import { QUADRANT_SCALE } from '../quadrants/quadrantConstants';
import { debugAlwaysShowCache, debugNeverShowCache, debugShowCacheFlag } from '../../debugFlags';
Expand Down Expand Up @@ -198,6 +198,10 @@ export class PixiApp {
zoomToFit(this.sheet, this.viewport);
}

setZoomToSelection(): void {
zoomToSelection(this.settings.interactionState, this.sheet, this.viewport);
}

// called before and after a quadrant render
prepareForQuadrantRendering(): Container {
this.gridLines.visible = false;
Expand Down
16 changes: 14 additions & 2 deletions src/ui/menus/CommandPalette/ListItems/View.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { CommandPaletteListItem } from '../CommandPaletteListItem';
import { CommandPaletteListItemSharedProps } from '../CommandPaletteListItem';
import { CommandPaletteListItemCheckbox } from '../CommandPaletteListItemCheckbox';
import { zoomIn, zoomOut, zoomToFit, zoomTo100 } from '../../../../gridGL/helpers/zoom';
import { zoomIn, zoomOut, zoomToFit, zoomTo100, zoomToSelection } from '../../../../gridGL/helpers/zoom';
import { KeyboardSymbols } from '../../../../helpers/keyboardSymbols';
import { useGridSettings } from '../../TopBar/SubMenus/useGridSettings';

Expand Down Expand Up @@ -141,7 +141,19 @@ const ListItems = [
/>
),
},

{
label: 'View: Zoom to selection',
Component: (props: CommandPaletteListItemSharedProps) => (
<CommandPaletteListItem
{...props}
action={() => {
zoomToSelection(props.interactionState, props.app.sheet, props.app.viewport);
}}
shortcut="8"
shortcutModifiers={[KeyboardSymbols.Command]}
/>
),
},
{
label: 'View: Zoom to fit',
Component: (props: CommandPaletteListItemSharedProps) => (
Expand Down
3 changes: 3 additions & 0 deletions src/ui/menus/TopBar/ZoomDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ export const ZoomDropdown = (props: Props) => {
<MenuLineItem primary="Zoom out" secondary={KeyboardSymbols.Command + '−'} />
</MenuItem>
<MenuDivider></MenuDivider>
<MenuItem onClick={() => props.app.setZoomToSelection()}>
<MenuLineItem primary="Zoom to selection" secondary={KeyboardSymbols.Command + '8'} />
</MenuItem>
<MenuItem onClick={() => props.app.setZoomToFit()}>
<MenuLineItem primary="Zoom to fit" secondary={KeyboardSymbols.Command + '9'} />
</MenuItem>
Expand Down

0 comments on commit c4c2aac

Please sign in to comment.