Skip to content

Commit

Permalink
Use Vector3 in all coordinate spaces
Browse files Browse the repository at this point in the history
  • Loading branch information
axelboc committed Jan 9, 2023
1 parent c4ed4d9 commit 2f06b32
Show file tree
Hide file tree
Showing 18 changed files with 71 additions and 79 deletions.
24 changes: 12 additions & 12 deletions apps/storybook/src/Context.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@ useVisCanvasContext(): VisCanvasContextValue
const { visSize, dataToWorld, worldToData } = useVisCanvasContext();
```

| Name | Description | Type |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- |
| `canvasSize` | Canvas size (equivalent to `useThree((state) => state.size)`) | <code>Size</code> |
| `canvasRatio` | Canvas ratio (i.e. `width / height`) | <code>number</code> |
| `visRatio` | Visualization ratio: defined when `VisCanvas` receives `aspect="equal"` or `aspect={number}` (e.g. `HeatmapVis` with "keep ratio" enabled); `undefined` otherwise | <code>number &#124; undefined</code> |
| `visSize` | Visualization size (different from canvas size when `visRatio` is defined) | <code>Size</code> |
| `abscissaConfig` | Abscissa configuration object passed to `VisCanvas` | <code>AxisConfig</code> |
| `ordinateConfig` | Ordinate configuration object passed to `VisCanvas` | <code>AxisConfig</code> |
| `abscissaScale` | Computes the X coordinate in world space of a given abscissa value (or the opposite with `abscissaScale.invert()`) | <code>AxisScale</code> |
| `ordinateScale` | Computes the Y coordinate in world space of a given ordinate value (or the opposite with `ordinateScale.invert()`) | <code>AxisScale</code> |
| `dataToWorld` | Converts a vector from data space to world space (calls `abscissaScale()` and `ordinateScale`) | <code>(vec: Vector2 &#124; Vector3) => Vector2</code> |
| `worldToData` | Converts a vector from world space to data space (calls `abscissaScale.invert()` and `ordinateScale.invert`) | <code>(vec: Vector2 &#124; Vector3) => Vector2</code> |
| Name | Description | Type |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- |
| `canvasSize` | Canvas size (equivalent to `useThree((state) => state.size)`) | <code>Size</code> |
| `canvasRatio` | Canvas ratio (i.e. `width / height`) | <code>number</code> |
| `visRatio` | Visualization ratio: defined when `VisCanvas` receives `aspect="equal"` or `aspect={number}` (e.g. `HeatmapVis` with "keep ratio" enabled); `undefined` otherwise | <code>number &#124; undefined</code> |
| `visSize` | Visualization size (different from canvas size when `visRatio` is defined) | <code>Size</code> |
| `abscissaConfig` | Abscissa configuration object passed to `VisCanvas` | <code>AxisConfig</code> |
| `ordinateConfig` | Ordinate configuration object passed to `VisCanvas` | <code>AxisConfig</code> |
| `abscissaScale` | Computes the X coordinate in world space of a given abscissa value (or the opposite with `abscissaScale.invert()`) | <code>AxisScale</code> |
| `ordinateScale` | Computes the Y coordinate in world space of a given ordinate value (or the opposite with `ordinateScale.invert()`) | <code>AxisScale</code> |
| `dataToWorld` | Converts a vector from data space to world space (calls `abscissaScale()` and `ordinateScale`) | <code>(vec: Vector3) => Vector3</code> |
| `worldToData` | Converts a vector from world space to data space (calls `abscissaScale.invert()` and `ordinateScale.invert`) | <code>(vec: Vector3) => Vector3</code> |

> This table is not exhaustive. Please consider any undocumented property as experimental or meant for internal use only.
4 changes: 2 additions & 2 deletions apps/storybook/src/SelectionTool.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ModifierKey, Rect2, Selection } from '@h5web/lib';
import type { ModifierKey, Rect, Selection } from '@h5web/lib';
import { DataToWorld } from '@h5web/lib';
import { SvgLine, SvgRect } from '@h5web/lib';
import {
Expand Down Expand Up @@ -90,7 +90,7 @@ CustomStyles.argTypes = {

export const PersistedDataSelection: Story<TemplateProps> = (args) => {
const { selectionModifierKey, panModifierKey } = args;
const [persistedDataSelection, setPersistedDataSelection] = useState<Rect2>();
const [persistedDataSelection, setPersistedDataSelection] = useState<Rect>();

if (selectionModifierKey === panModifierKey) {
return (
Expand Down
8 changes: 4 additions & 4 deletions apps/storybook/src/SvgLine.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { DataToWorldProps, Rect2, SvgLineProps } from '@h5web/lib';
import type { DataToWorldProps, Rect, SvgLineProps } from '@h5web/lib';
import {
DefaultInteractions,
SvgLine,
VisCanvas,
DataToWorld,
} from '@h5web/lib';
import type { Meta, Story } from '@storybook/react';
import { Vector2, Vector3 } from 'three';
import { Vector3 } from 'three';

import FillHeight from './decorators/FillHeight';

Expand Down Expand Up @@ -35,7 +35,7 @@ Custom.args = {
};

export const WithDataToWorld: Story<
Omit<SvgLineProps, 'coords'> & DataToWorldProps<Rect2>
Omit<SvgLineProps, 'coords'> & DataToWorldProps<Rect>
> = (args) => {
const { coords, ...lineProps } = args;
return (
Expand All @@ -53,7 +53,7 @@ export const WithDataToWorld: Story<

WithDataToWorld.storyName = 'With DataToWorld';
WithDataToWorld.args = {
coords: [new Vector2(5, 15), new Vector2(30, 5)],
coords: [new Vector3(5, 15), new Vector3(30, 5)],
strokeWidth: 2,
stroke: 'orangered',
};
Expand Down
8 changes: 4 additions & 4 deletions apps/storybook/src/SvgRect.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { DataToWorldProps, Rect2, SvgRectProps } from '@h5web/lib';
import type { DataToWorldProps, Rect, SvgRectProps } from '@h5web/lib';
import {
DefaultInteractions,
SvgRect,
VisCanvas,
DataToWorld,
} from '@h5web/lib';
import type { Meta, Story } from '@storybook/react';
import { Vector2, Vector3 } from 'three';
import { Vector3 } from 'three';

import FillHeight from './decorators/FillHeight';

Expand Down Expand Up @@ -35,7 +35,7 @@ Custom.args = {
};

export const WithDataToWorld: Story<
Omit<SvgRectProps, 'coords'> & DataToWorldProps<Rect2>
Omit<SvgRectProps, 'coords'> & DataToWorldProps<Rect>
> = (args) => {
const { coords, ...lineProps } = args;
return (
Expand All @@ -53,7 +53,7 @@ export const WithDataToWorld: Story<

WithDataToWorld.storyName = 'With DataToWorld';
WithDataToWorld.args = {
coords: [new Vector2(5, 15), new Vector2(20, 10)],
coords: [new Vector3(5, 15), new Vector3(20, 10)],
fill: 'orangered',
fillOpacity: 0.6,
};
Expand Down
10 changes: 5 additions & 5 deletions apps/storybook/src/Utilities.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ The hook accepts a callback, which:
```ts
const htmlPt = useCameraState(
(camera, context) => dataToHtml(camera, context, new Vector2(x, y)),
(camera, context) => dataToHtml(camera, context, new Vector3(x, y)),
[x, y]
);
```
Expand All @@ -239,31 +239,31 @@ The utilities documented in this section require access to the R3F `camera` obje
Convert a point from world space to HTML space
```ts
worldToHtml(camera: Camera, context: VisCanvasContextValue, worldPt: Vector3): Vector2
worldToHtml(camera: Camera, context: VisCanvasContextValue, worldPt: Vector3): Vector3
```
#### htmlToWorld
Convert a point from HTML space to world space
```ts
htmlToWorld(camera: Camera, context: VisCanvasContextValue, htmlPt: Vector2): Vector3
htmlToWorld(camera: Camera, context: VisCanvasContextValue, htmlPt: Vector3): Vector3
```
#### dataToHtml
Convert a point from data space to HTML space.
```ts
dataToHtml(camera: Camera, context: VisCanvasContextValue, dataPt: Vector2): Vector2
dataToHtml(camera: Camera, context: VisCanvasContextValue, dataPt: Vector3): Vector3
```
#### htmlToData
Convert a point from HTML space to data space.
```ts
htmlToData(camera: Camera, context: VisCanvasContextValue, htmlPt: Vector2): Vector2
htmlToData(camera: Camera, context: VisCanvasContextValue, htmlPt: Vector3): Vector3
```
#### getWorldFOV
Expand Down
4 changes: 2 additions & 2 deletions apps/storybook/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { Rect2 } from '@h5web/lib';
import type { Rect } from '@h5web/lib';
import { format } from 'd3-format';

const formatCoord = format('.2f');

export function getTitleForSelection(selection: Rect2 | undefined) {
export function getTitleForSelection(selection: Rect | undefined) {
if (!selection) {
return 'No selection';
}
Expand Down
2 changes: 0 additions & 2 deletions packages/lib/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,6 @@ export type {
ModifierKey,
Selection,
Rect,
Rect2,
Rect3,
CanvasEvent,
CanvasEventCallbacks,
} from './interactions/models';
Expand Down
6 changes: 3 additions & 3 deletions packages/lib/src/interactions/AxialSelectionTool.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useVisCanvasContext } from '../vis/shared/VisCanvasProvider';
import { getWorldFOV } from '../vis/utils';
import type { SelectionToolProps } from './SelectionTool';
import SelectionTool from './SelectionTool';
import type { Rect2, Rect3, Selection } from './models';
import type { Rect, Selection } from './models';

interface Props extends SelectionToolProps {
axis: Axis;
Expand All @@ -29,7 +29,7 @@ function AxialSelectionTool(props: Props) {
const [worldStart, worldEnd] = selection.world;
const { bottomLeft, topRight } = getWorldFOV(camera);

const axialWorldSelection: Rect3 =
const axialWorldSelection: Rect =
axis === 'x'
? [
new Vector3(worldStart.x, bottomLeft.y, 0),
Expand All @@ -42,7 +42,7 @@ function AxialSelectionTool(props: Props) {

return {
world: axialWorldSelection,
data: axialWorldSelection.map(worldToData) as Rect2,
data: axialWorldSelection.map(worldToData) as Rect,
};
}

Expand Down
4 changes: 2 additions & 2 deletions packages/lib/src/interactions/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useEventListener, useToggle } from '@react-hookz/web';
import { useThree } from '@react-three/fiber';
import { useState } from 'react';
import { useCallback, useEffect } from 'react';
import { Vector2, Vector3 } from 'three';
import { Vector3 } from 'three';

import { useVisCanvasContext } from '../vis/shared/VisCanvasProvider';
import { htmlToWorld } from '../vis/utils';
Expand Down Expand Up @@ -136,7 +136,7 @@ export function useCanvasEvents(callbacks: CanvasEventCallbacks): void {
<T extends PointerEvent | WheelEvent>(sourceEvent: T): CanvasEvent<T> => {
const { offsetX, offsetY } = sourceEvent;

const htmlPt = new Vector2(offsetX, offsetY);
const htmlPt = new Vector3(offsetX, offsetY);
const worldPt = htmlToWorld(camera, context, htmlPt);
const dataPt = context.worldToData(worldPt);

Expand Down
15 changes: 6 additions & 9 deletions packages/lib/src/interactions/models.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Vector2, Vector3 } from 'three';
import type { Vector3 } from 'three';

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

Expand All @@ -7,19 +7,16 @@ export enum MouseButton {
'Middle' = 1,
}

export type Rect = [Vector3, Vector3];
export interface Selection {
world: Rect3;
data: Rect2;
world: Rect;
data: Rect;
}

export type Rect<T extends Vector2 | Vector3> = [T, T];
export type Rect2 = Rect<Vector2>;
export type Rect3 = Rect<Vector3>;

export interface CanvasEvent<T extends MouseEvent> {
htmlPt: Vector2;
htmlPt: Vector3;
worldPt: Vector3;
dataPt: Vector2;
dataPt: Vector3;
sourceEvent: T;
}

Expand Down
4 changes: 2 additions & 2 deletions packages/lib/src/svg/SvgLine.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { SVGProps } from 'react';

import type { Rect3 } from '../interactions/models';
import type { Rect } from '../interactions/models';
import { useHtmlCoords } from '../vis/hooks';
import SvgElement from './SvgElement';

interface Props extends SVGProps<SVGLineElement> {
coords: Rect3;
coords: Rect;
}

function SvgLine(props: Props) {
Expand Down
4 changes: 2 additions & 2 deletions packages/lib/src/svg/SvgRect.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { SVGProps } from 'react';

import type { Rect3 } from '../interactions/models';
import type { Rect } from '../interactions/models';
import { useHtmlCoords } from '../vis/hooks';
import SvgElement from './SvgElement';

interface Props extends SVGProps<SVGRectElement> {
coords: Rect3;
coords: Rect;
}

function SvgRect(props: Props) {
Expand Down
6 changes: 3 additions & 3 deletions packages/lib/src/vis/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type { Camera } from '@react-three/fiber';
import { useFrame, useThree } from '@react-three/fiber';
import { useEffect, useCallback, useMemo, useState } from 'react';
import type { RefCallback } from 'react';
import type { Vector2, Vector3 } from 'three';
import type { Vector3 } from 'three';

import { useVisCanvasContext } from './shared/VisCanvasProvider';
import type { VisCanvasContextValue } from './shared/VisCanvasProvider';
Expand Down Expand Up @@ -102,12 +102,12 @@ export function useCssColors(

export function useHtmlCoords<T extends Vector3[]>(
...worldCoords: T
): MappedTuple<T, Vector2> {
): MappedTuple<T, Vector3> {
return useCameraState(
(...args) =>
worldCoords.map((pt) => worldToHtml(...args, pt)) as MappedTuple<
T,
Vector2
Vector3
>,
worldCoords // eslint-disable-line react-hooks/exhaustive-deps
);
Expand Down
4 changes: 2 additions & 2 deletions packages/lib/src/vis/shared/Annotation.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { HTMLAttributes } from 'react';
import { Vector2 } from 'three';
import { Vector3 } from 'three';

import { useCameraState } from '../hooks';
import { dataToHtml } from '../utils';
Expand Down Expand Up @@ -33,7 +33,7 @@ function Annotation(props: Props) {

const { htmlPt, cameraScale } = useCameraState(
(camera, context) => ({
htmlPt: dataToHtml(camera, context, new Vector2(x, y)),
htmlPt: dataToHtml(camera, context, new Vector3(x, y)),
cameraScale: camera.scale.clone(),
}),
[x, y]
Expand Down
6 changes: 3 additions & 3 deletions packages/lib/src/vis/shared/DataToWorld.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import type { MappedTuple } from '@h5web/shared';
import type { ReactNode } from 'react';
import type { Vector2, Vector3 } from 'three';
import type { Vector3 } from 'three';

import { useVisCanvasContext } from './VisCanvasProvider';

interface Props<T extends Vector2[]> {
interface Props<T extends Vector3[]> {
coords: T;
children: (...coords: MappedTuple<T, Vector3>) => ReactNode;
}

function DataToWorld<T extends Vector2[]>(props: Props<T>) {
function DataToWorld<T extends Vector3[]>(props: Props<T>) {
const { coords, children } = props;

const { dataToWorld } = useVisCanvasContext();
Expand Down
4 changes: 2 additions & 2 deletions packages/lib/src/vis/shared/ViewportCenterer.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { useFrame, useThree } from '@react-three/fiber';
import { useEffect, useRef } from 'react';
import type { Vector2 } from 'three';
import type { Vector3 } from 'three';

import { useMoveCameraTo } from '../../interactions/hooks';
import { useVisCanvasContext } from './VisCanvasProvider';

function ViewportCenterer() {
const { dataToWorld, worldToData } = useVisCanvasContext();
const viewportCenter = useRef<Vector2>();
const viewportCenter = useRef<Vector3>();
const camera = useThree((state) => state.camera);

const moveCameraTo = useMoveCameraTo();
Expand Down
Loading

0 comments on commit 2f06b32

Please sign in to comment.