Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Put interaction components and utils in a dedicated folder #1019

Merged
merged 1 commit into from
Mar 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/storybook/src/Pan.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Pan, ResetZoomButton, VisCanvas, Zoom } from '@h5web/lib';
import type { ModifierKey as ModifierKeyType } from '@h5web/lib/src/vis/models';
import type { ModifierKey as ModifierKeyType } from '@h5web/lib';
import type { Meta, Story } from '@storybook/react';

import VisCanvasStoriesConfig from './VisCanvas.stories';
Expand Down
2 changes: 1 addition & 1 deletion apps/storybook/src/SelectToZoom.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
SelectToZoom,
ResetZoomButton,
} from '@h5web/lib';
import type { ModifierKey as ModifierKeyType } from '@h5web/lib/src/vis/models';
import type { ModifierKey as ModifierKeyType } from '@h5web/lib';
import type { Meta, Story } from '@storybook/react';
import { range } from 'lodash';

Expand Down
2 changes: 1 addition & 1 deletion apps/storybook/src/Selection.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Selection, ModifierKey } from '@h5web/lib';
import {
Pan,
SelectionLine,
Expand All @@ -7,7 +8,6 @@ import {
Zoom,
ResetZoomButton,
} from '@h5web/lib';
import type { ModifierKey, Selection } from '@h5web/lib/src/vis/models';
import type { Meta, Story } from '@storybook/react';
import { format } from 'd3-format';
import { useState } from 'react';
Expand Down
2 changes: 1 addition & 1 deletion apps/storybook/src/XZoom.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Pan, ResetZoomButton, VisCanvas, XAxisZoom } from '@h5web/lib';
import type { ModifierKey as ModifierKeyType } from '@h5web/lib/src/vis/models';
import type { ModifierKey as ModifierKeyType } from '@h5web/lib';
import type { Meta, Story } from '@storybook/react';

import VisCanvasStoriesConfig from './VisCanvas.stories';
Expand Down
2 changes: 1 addition & 1 deletion apps/storybook/src/YZoom.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Pan, ResetZoomButton, VisCanvas, YAxisZoom } from '@h5web/lib';
import type { ModifierKey as ModifierKeyType } from '@h5web/lib/src/vis/models';
import type { ModifierKey as ModifierKeyType } from '@h5web/lib';
import type { Meta, Story } from '@storybook/react';

import VisCanvasStoriesConfig from './VisCanvas.stories';
Expand Down
2 changes: 1 addition & 1 deletion apps/storybook/src/Zoom.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Pan, ResetZoomButton, VisCanvas, Zoom } from '@h5web/lib';
import type { ModifierKey as ModifierKeyType } from '@h5web/lib/src/vis/models';
import type { ModifierKey as ModifierKeyType } from '@h5web/lib';
import type { Meta, Story } from '@storybook/react';

import VisCanvasStoriesConfig from './VisCanvas.stories';
Expand Down
30 changes: 18 additions & 12 deletions packages/lib/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,6 @@ export { default as InteractionHelp } from './toolbar/controls/InteractionHelp';
// Building blocks
export { default as VisCanvas } from './vis/shared/VisCanvas';
export type { VisCanvasProps } from './vis/shared/VisCanvas';
export { default as Pan } from './vis/shared/Pan';
export { default as Zoom } from './vis/shared/Zoom';
export { default as XAxisZoom } from './vis/shared/XAxisZoom';
export { default as YAxisZoom } from './vis/shared/YAxisZoom';
export { default as SelectToZoom } from './vis/shared/SelectToZoom';
export { default as ResetZoomButton } from './vis/shared/ResetZoomButton';
export { default as TooltipMesh } from './vis/shared/TooltipMesh';
export type { TooltipMeshProps } from './vis/shared/TooltipMesh';
export { default as VisMesh } from './vis/shared/VisMesh';
Expand All @@ -43,14 +37,22 @@ export type { HeatmapMeshProps } from './vis/heatmap/HeatmapMesh';
export { default as DataCurve } from './vis/line/DataCurve';
export { default as Html } from './vis/shared/Html';
export { default as Annotation } from './vis/shared/Annotation';
export { default as SelectionTool } from './vis/shared/SelectionTool';
export type { SelectionProps } from './vis/shared/SelectionTool';
export { default as SelectionLine } from './vis/shared/SelectionLine';
export { default as SelectionRect } from './vis/shared/SelectionRect';
export { default as TiledHeatmap } from './vis/tiles/TiledHeatmap';
export type { TiledHeatmapProps } from './vis/tiles/TiledHeatmap';
export { getLayerSizes, TilesApi } from './vis/tiles/api';

// Interactions
export { default as Pan } from './interactions/Pan';
export { default as Zoom } from './interactions/Zoom';
export { default as XAxisZoom } from './interactions/XAxisZoom';
export { default as YAxisZoom } from './interactions/YAxisZoom';
export { default as SelectToZoom } from './interactions/SelectToZoom';
export { default as ResetZoomButton } from './interactions/ResetZoomButton';
export { default as SelectionLine } from './interactions/SelectionLine';
export { default as SelectionRect } from './interactions/SelectionRect';
export { default as SelectionTool } from './interactions/SelectionTool';
export type { SelectionProps } from './interactions/SelectionTool';

// Context hook
export { useAxisSystemContext } from './vis/shared/AxisSystemContext';
export type { AxisSystemParams } from './vis/shared/AxisSystemContext';
Expand Down Expand Up @@ -82,13 +84,17 @@ export {
export { useVisDomain, useSafeDomain } from './vis/heatmap/hooks';

export { scaleGamma } from './vis/scaleGamma';
export { useCanvasEvents } from './vis/shared/hooks';
export { useCanvasEvents } from './interactions/hooks';

// Models
export { INTERPOLATORS } from './vis/heatmap/interpolators';
export { ScaleType } from '@h5web/shared';
export { CurveType } from './vis/line/models';
export type { Interaction } from './vis/models';
export type {
Interaction,
ModifierKey,
Selection,
} from './interactions/models';

export type { Domain, Dims } from '@h5web/shared';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { useThree } from '@react-three/fiber';
import { useRef, useCallback } from 'react';
import type { Vector3 } from 'three';

import type { CanvasEvent, ModifierKey } from '../models';
import { checkModifierKey } from '../utils';
import { useCanvasEvents, useMoveCameraTo } from './hooks';
import type { CanvasEvent, ModifierKey } from './models';
import { checkModifierKey } from './utils';

interface Props {
disabled?: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
}

.btn {
composes: btn from '../../toolbar/Toolbar.module.css';
composes: btn from '../toolbar/Toolbar.module.css';
padding: 0.5rem !important; /* FIX style ordering issue with Vite */
pointer-events: auto;
font-size: 0.875em;
}

.btnLike {
composes: btnLike from '../../toolbar/Toolbar.module.css';
composes: btnLike from '../toolbar/Toolbar.module.css';
background-color: rgba(255, 255, 255, 0.7);
box-shadow: rgba(0, 0, 0, 0.1) 0px 0px 0px 1px,
rgba(0, 0, 0, 0.1) 0px 4px 11px;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useThree } from '@react-three/fiber';

import { useFrameRendering } from '../hooks';
import Html from './Html';
import { useFrameRendering } from '../vis/hooks';
import Html from '../vis/shared/Html';
import styles from './ResetZoomButton.module.css';
import { useMoveCameraTo } from './hooks';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { useThree } from '@react-three/fiber';

import type { ModifierKey, Selection } from '../models';
import { getRatioEndPoint } from '../utils';
import { useAxisSystemContext } from './AxisSystemContext';
import { useAxisSystemContext } from '../vis/shared/AxisSystemContext';
import SelectionRect from './SelectionRect';
import SelectionTool from './SelectionTool';
import { useMoveCameraTo } from './hooks';
import type { ModifierKey, Selection } from './models';
import { getRatioEndPoint } from './utils';

interface Props {
modifierKey?: ModifierKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { useThree } from '@react-three/fiber';
import type { SVGProps } from 'react';
import type { Vector2 } from 'three';

import { useAxisSystemContext } from './AxisSystemContext';
import Html from './Html';
import { useAxisSystemContext } from '../vis/shared/AxisSystemContext';
import Html from '../vis/shared/Html';

interface Props extends SVGProps<SVGLineElement> {
startPoint: Vector2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { useThree } from '@react-three/fiber';
import type { SVGProps } from 'react';
import type { Vector2 } from 'three';

import { useAxisSystemContext } from './AxisSystemContext';
import Html from './Html';
import { useAxisSystemContext } from '../vis/shared/AxisSystemContext';
import Html from '../vis/shared/Html';

interface Props extends SVGProps<SVGRectElement> {
startPoint: Vector2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import type { ReactElement } from 'react';
import { useCallback, useState } from 'react';
import type { Vector2 } from 'three';

import type { CanvasEvent, ModifierKey, Selection } from '../models';
import { boundPointToFOV, checkModifierKey } from '../utils';
import { useAxisSystemContext } from './AxisSystemContext';
import { useAxisSystemContext } from '../vis/shared/AxisSystemContext';
import { useCanvasEvents } from './hooks';
import type { CanvasEvent, ModifierKey, Selection } from './models';
import { boundPointToFOV, checkModifierKey } from './utils';

interface Props {
onSelectionStart?: () => void;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ModifierKey } from '../models';
import { useCanvasEvents, useZoomOnWheel } from './hooks';
import type { ModifierKey } from './models';

interface Props {
disabled?: boolean;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ModifierKey } from '../models';
import { useCanvasEvents, useZoomOnWheel } from './hooks';
import type { ModifierKey } from './models';

interface Props {
disabled?: boolean;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { ModifierKey } from '../models';
import { checkModifierKey } from '../utils';
import { useCanvasEvents, useZoomOnWheel } from './hooks';
import type { ModifierKey } from './models';
import { checkModifierKey } from './utils';

interface Props {
disabled?: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import { clamp } from 'lodash';
import { useCallback } from 'react';
import { Vector3 } from 'three';

import { useWheelCapture } from '../hooks';
import type { CanvasEvent, CanvasEventCallbacks } from '../models';
import { getCameraFOV } from '../utils';
import { useAxisSystemContext } from './AxisSystemContext';
import { useAxisSystemContext } from '../vis/shared/AxisSystemContext';
import { getCameraFOV } from '../vis/utils';
import type { CanvasEvent, CanvasEventCallbacks } from './models';

const ZOOM_FACTOR = 0.95;

Expand Down Expand Up @@ -43,6 +42,18 @@ export function useMoveCameraTo() {
);
}

function onWheel(evt: WheelEvent) {
evt.preventDefault();
}

function useWheelCapture() {
const { domElement } = useThree((state) => state.gl);

// Handler must be registed as non-passive for `preventDefault` to have an effect
// (React's `onWheel` prop registers handlers as passive)
useEventListener(domElement, 'wheel', onWheel, { passive: false });
}

export function useZoomOnWheel(
isZoomAllowed: (sourceEvent: WheelEvent) => { x: boolean; y: boolean },
disabled?: boolean
Expand Down
25 changes: 25 additions & 0 deletions packages/lib/src/interactions/models.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { Vector2, Vector3 } from 'three';

export type ModifierKey = 'Alt' | 'Control' | 'Shift';

export interface Selection {
startPoint: Vector2;
endPoint: Vector2;
}

export interface CanvasEvent<T extends PointerEvent | WheelEvent> {
unprojectedPoint: Vector3;
sourceEvent: T;
}

export interface CanvasEventCallbacks {
onPointerDown?: (evt: CanvasEvent<PointerEvent>) => void;
onPointerMove?: (evt: CanvasEvent<PointerEvent>) => void;
onPointerUp?: (evt: CanvasEvent<PointerEvent>) => void;
onWheel?: (evt: CanvasEvent<WheelEvent>) => void;
}

export interface Interaction {
shortcut: string;
description: string;
}
55 changes: 55 additions & 0 deletions packages/lib/src/interactions/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import type { Camera } from '@react-three/fiber';
import { clamp } from 'lodash';
import type { Vector3 } from 'three';
import { Vector2 } from 'three';

import { getCameraFOV } from '../vis/utils';
import type { ModifierKey } from './models';

export function boundPointToFOV(
unboundedPoint: Vector2 | Vector3,
camera: Camera
): Vector2 {
const { topRight, bottomLeft } = getCameraFOV(camera);
const boundedX = clamp(unboundedPoint.x, bottomLeft.x, topRight.x);
const boundedY = clamp(unboundedPoint.y, bottomLeft.y, topRight.y);
return new Vector2(boundedX, boundedY);
}

export function checkModifierKey(
modifierKey: ModifierKey | undefined,
event: MouseEvent | KeyboardEvent
) {
if (!modifierKey) {
return !event.altKey && !event.ctrlKey && !event.shiftKey;
}

return event.getModifierState(modifierKey);
}

export function getRatioEndPoint(
startPoint: Vector2,
endPoint: Vector2,
ratio: number
) {
const widthSign = Math.sign(endPoint.x - startPoint.x);
const width = Math.abs(endPoint.x - startPoint.x);

const heightSign = Math.sign(endPoint.y - startPoint.y);
const height = Math.abs(endPoint.y - startPoint.y);

const originalRatio =
Math.abs(endPoint.x - startPoint.x) / Math.abs(endPoint.y - startPoint.y);

if (originalRatio < ratio) {
return new Vector2(
startPoint.x + widthSign * height * ratio,
startPoint.y + heightSign * height
);
}

return new Vector2(
startPoint.x + widthSign * width,
startPoint.y + (heightSign * width) / ratio
);
}
2 changes: 1 addition & 1 deletion packages/lib/src/toolbar/Toolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useMap, useMeasure } from '@react-hookz/web';
import type { ReactElement, ReactNode } from 'react';
import flattenChildren from 'react-keyed-flatten-children';

import type { Interaction } from '../vis/models';
import type { Interaction } from '../interactions/models';
import MeasuredControl from './MeasuredControl';
import OverflowMenu from './OverflowMenu';
import Separator from './Separator';
Expand Down
2 changes: 1 addition & 1 deletion packages/lib/src/toolbar/controls/InteractionHelp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useClickOutside, useToggle } from '@react-hookz/web';
import { useRef } from 'react';
import { FiHelpCircle } from 'react-icons/fi';

import type { Interaction } from '../../vis/models';
import type { Interaction } from '../../interactions/models';
import styles from './InteractionHelp.module.css';
import ToggleBtn from './ToggleBtn';

Expand Down
8 changes: 4 additions & 4 deletions packages/lib/src/vis/heatmap/HeatmapVis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import type { NdArray } from 'ndarray';
import type { ReactElement, ReactNode } from 'react';

import { XAxisZoom, YAxisZoom } from '../..';
import Pan from '../../interactions/Pan';
import ResetZoomButton from '../../interactions/ResetZoomButton';
import SelectToZoom from '../../interactions/SelectToZoom';
import Zoom from '../../interactions/Zoom';
import { useAxisDomain, useValueToIndexScale } from '../hooks';
import type { AxisParams, VisScaleType } from '../models';
import Pan from '../shared/Pan';
import ResetZoomButton from '../shared/ResetZoomButton';
import SelectToZoom from '../shared/SelectToZoom';
import TooltipMesh from '../shared/TooltipMesh';
import VisCanvas from '../shared/VisCanvas';
import Zoom from '../shared/Zoom';
import { DEFAULT_DOMAIN, formatNumType } from '../utils';
import ColorBar from './ColorBar';
import HeatmapMesh from './HeatmapMesh';
Expand Down
Loading