Adjusts small example, makes inputs unique to each instance
This commit is contained in:
parent
2653f396bf
commit
8154ed5a2a
25 changed files with 190 additions and 81 deletions
|
@ -48,6 +48,7 @@
|
|||
"lerna": "^3.15.0",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"resize-observer-polyfill": "^1.5.1",
|
||||
"ts-jest": "^27.0.5",
|
||||
"tslib": "^2.3.0",
|
||||
"typedoc": "^0.21.9",
|
||||
|
@ -114,4 +115,4 @@
|
|||
"\\+(.*)": "<rootDir>/packages/core/src/$1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import { ErrorBoundary } from '+components/error-boundary'
|
|||
import { Brush } from '+components/brush'
|
||||
import { Defs } from '+components/defs'
|
||||
import { Page } from '+components/page'
|
||||
import { useResizeObserver } from '+hooks/useResizeObserver'
|
||||
|
||||
function resetError() {
|
||||
void null
|
||||
|
@ -35,10 +36,13 @@ export function Canvas<T extends TLShape>({
|
|||
hideIndicators = false,
|
||||
}: CanvasProps<T>): JSX.Element {
|
||||
const rCanvas = React.useRef<SVGSVGElement>(null)
|
||||
const rContainer = React.useRef<HTMLDivElement>(null)
|
||||
|
||||
const rGroup = useCameraCss(pageState)
|
||||
|
||||
useZoomEvents()
|
||||
useResizeObserver(rCanvas)
|
||||
|
||||
useZoomEvents(rCanvas)
|
||||
|
||||
useSafariFocusOutFix()
|
||||
|
||||
|
@ -47,7 +51,7 @@ export function Canvas<T extends TLShape>({
|
|||
const events = useCanvasEvents()
|
||||
|
||||
return (
|
||||
<div className="tl-container">
|
||||
<div className="tl-container" ref={rContainer}>
|
||||
<svg id="canvas" className="tl-canvas" ref={rCanvas} {...events}>
|
||||
<ErrorBoundary FallbackComponent={ErrorFallback} onReset={resetError}>
|
||||
<Defs zoom={pageState.camera.zoom} />
|
||||
|
|
|
@ -10,6 +10,7 @@ import type {
|
|||
TLBinding,
|
||||
} from '../../types'
|
||||
import { Canvas } from '../canvas'
|
||||
import { Inputs } from '../../inputs'
|
||||
import { useTLTheme, TLContext, TLContextType } from '../../hooks'
|
||||
|
||||
export interface RendererProps<T extends TLShape, M extends Record<string, unknown>>
|
||||
|
@ -87,6 +88,7 @@ export function Renderer<T extends TLShape, M extends Record<string, unknown>>({
|
|||
shapeUtils,
|
||||
rScreenBounds,
|
||||
rPageState,
|
||||
inputs: new Inputs(),
|
||||
}))
|
||||
|
||||
return (
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import * as React from 'react'
|
||||
import { inputs } from '+inputs'
|
||||
import { useTLContext } from './useTLContext'
|
||||
|
||||
export function useBoundsEvents() {
|
||||
const { callbacks } = useTLContext()
|
||||
const { callbacks, inputs } = useTLContext()
|
||||
|
||||
const onPointerDown = React.useCallback(
|
||||
(e: React.PointerEvent) => {
|
||||
|
@ -15,7 +14,7 @@ export function useBoundsEvents() {
|
|||
callbacks.onPointBounds?.(info, e)
|
||||
callbacks.onPointerDown?.(info, e)
|
||||
},
|
||||
[callbacks]
|
||||
[callbacks, inputs]
|
||||
)
|
||||
|
||||
const onPointerUp = React.useCallback(
|
||||
|
@ -36,7 +35,7 @@ export function useBoundsEvents() {
|
|||
callbacks.onReleaseBounds?.(info, e)
|
||||
callbacks.onPointerUp?.(info, e)
|
||||
},
|
||||
[callbacks]
|
||||
[callbacks, inputs]
|
||||
)
|
||||
|
||||
const onPointerMove = React.useCallback(
|
||||
|
@ -49,21 +48,21 @@ export function useBoundsEvents() {
|
|||
const info = inputs.pointerMove(e, 'bounds')
|
||||
callbacks.onPointerMove?.(info, e)
|
||||
},
|
||||
[callbacks]
|
||||
[callbacks, inputs]
|
||||
)
|
||||
|
||||
const onPointerEnter = React.useCallback(
|
||||
(e: React.PointerEvent) => {
|
||||
callbacks.onHoverBounds?.(inputs.pointerEnter(e, 'bounds'), e)
|
||||
},
|
||||
[callbacks]
|
||||
[callbacks, inputs]
|
||||
)
|
||||
|
||||
const onPointerLeave = React.useCallback(
|
||||
(e: React.PointerEvent) => {
|
||||
callbacks.onUnhoverBounds?.(inputs.pointerEnter(e, 'bounds'), e)
|
||||
},
|
||||
[callbacks]
|
||||
[callbacks, inputs]
|
||||
)
|
||||
|
||||
const onTouchStart = React.useCallback((e: React.TouchEvent) => {
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import * as React from 'react'
|
||||
import { inputs } from '+inputs'
|
||||
import type { TLBoundsEdge, TLBoundsCorner } from '+types'
|
||||
import { useTLContext } from './useTLContext'
|
||||
|
||||
export function useBoundsHandleEvents(id: TLBoundsCorner | TLBoundsEdge | 'rotate') {
|
||||
const { callbacks } = useTLContext()
|
||||
const { callbacks, inputs } = useTLContext()
|
||||
|
||||
const onPointerDown = React.useCallback(
|
||||
(e: React.PointerEvent) => {
|
||||
|
@ -16,7 +15,7 @@ export function useBoundsHandleEvents(id: TLBoundsCorner | TLBoundsEdge | 'rotat
|
|||
callbacks.onPointBoundsHandle?.(info, e)
|
||||
callbacks.onPointerDown?.(info, e)
|
||||
},
|
||||
[callbacks, id]
|
||||
[inputs, callbacks, id]
|
||||
)
|
||||
|
||||
const onPointerUp = React.useCallback(
|
||||
|
@ -37,7 +36,7 @@ export function useBoundsHandleEvents(id: TLBoundsCorner | TLBoundsEdge | 'rotat
|
|||
callbacks.onReleaseBoundsHandle?.(info, e)
|
||||
callbacks.onPointerUp?.(info, e)
|
||||
},
|
||||
[callbacks, id]
|
||||
[inputs, callbacks, id]
|
||||
)
|
||||
|
||||
const onPointerMove = React.useCallback(
|
||||
|
@ -48,21 +47,21 @@ export function useBoundsHandleEvents(id: TLBoundsCorner | TLBoundsEdge | 'rotat
|
|||
const info = inputs.pointerMove(e, id)
|
||||
callbacks.onPointerMove?.(info, e)
|
||||
},
|
||||
[callbacks, id]
|
||||
[inputs, callbacks, id]
|
||||
)
|
||||
|
||||
const onPointerEnter = React.useCallback(
|
||||
(e: React.PointerEvent) => {
|
||||
callbacks.onHoverBoundsHandle?.(inputs.pointerEnter(e, id), e)
|
||||
},
|
||||
[callbacks, id]
|
||||
[inputs, callbacks, id]
|
||||
)
|
||||
|
||||
const onPointerLeave = React.useCallback(
|
||||
(e: React.PointerEvent) => {
|
||||
callbacks.onUnhoverBoundsHandle?.(inputs.pointerEnter(e, id), e)
|
||||
},
|
||||
[callbacks, id]
|
||||
[inputs, callbacks, id]
|
||||
)
|
||||
|
||||
const onTouchStart = React.useCallback((e: React.TouchEvent) => {
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import * as React from 'react'
|
||||
import { useTLContext } from './useTLContext'
|
||||
import { inputs } from '+inputs'
|
||||
|
||||
export function useCanvasEvents() {
|
||||
const { callbacks } = useTLContext()
|
||||
const { callbacks, inputs } = useTLContext()
|
||||
|
||||
const onPointerDown = React.useCallback(
|
||||
(e: React.PointerEvent) => {
|
||||
|
@ -16,7 +15,7 @@ export function useCanvasEvents() {
|
|||
callbacks.onPointerDown?.(info, e)
|
||||
}
|
||||
},
|
||||
[callbacks]
|
||||
[callbacks, inputs]
|
||||
)
|
||||
|
||||
const onPointerMove = React.useCallback(
|
||||
|
@ -28,7 +27,7 @@ export function useCanvasEvents() {
|
|||
const info = inputs.pointerMove(e, 'canvas')
|
||||
callbacks.onPointerMove?.(info, e)
|
||||
},
|
||||
[callbacks]
|
||||
[callbacks, inputs]
|
||||
)
|
||||
|
||||
const onPointerUp = React.useCallback(
|
||||
|
@ -47,7 +46,7 @@ export function useCanvasEvents() {
|
|||
callbacks.onReleaseCanvas?.(info, e)
|
||||
callbacks.onPointerUp?.(info, e)
|
||||
},
|
||||
[callbacks]
|
||||
[callbacks, inputs]
|
||||
)
|
||||
|
||||
return {
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import * as React from 'react'
|
||||
import { inputs } from '+inputs'
|
||||
import { useTLContext } from './useTLContext'
|
||||
|
||||
export function useHandleEvents(id: string) {
|
||||
const { callbacks } = useTLContext()
|
||||
const { inputs, callbacks } = useTLContext()
|
||||
|
||||
const onPointerDown = React.useCallback(
|
||||
(e: React.PointerEvent) => {
|
||||
|
@ -15,7 +14,7 @@ export function useHandleEvents(id: string) {
|
|||
callbacks.onPointHandle?.(info, e)
|
||||
callbacks.onPointerDown?.(info, e)
|
||||
},
|
||||
[callbacks, id]
|
||||
[inputs, callbacks, id]
|
||||
)
|
||||
|
||||
const onPointerUp = React.useCallback(
|
||||
|
@ -36,7 +35,7 @@ export function useHandleEvents(id: string) {
|
|||
}
|
||||
callbacks.onPointerUp?.(info, e)
|
||||
},
|
||||
[callbacks]
|
||||
[inputs, callbacks]
|
||||
)
|
||||
|
||||
const onPointerMove = React.useCallback(
|
||||
|
@ -48,7 +47,7 @@ export function useHandleEvents(id: string) {
|
|||
const info = inputs.pointerMove(e, id)
|
||||
callbacks.onPointerMove?.(info, e)
|
||||
},
|
||||
[callbacks, id]
|
||||
[inputs, callbacks, id]
|
||||
)
|
||||
|
||||
const onPointerEnter = React.useCallback(
|
||||
|
@ -56,7 +55,7 @@ export function useHandleEvents(id: string) {
|
|||
const info = inputs.pointerEnter(e, id)
|
||||
callbacks.onHoverHandle?.(info, e)
|
||||
},
|
||||
[callbacks, id]
|
||||
[inputs, callbacks, id]
|
||||
)
|
||||
|
||||
const onPointerLeave = React.useCallback(
|
||||
|
@ -64,7 +63,7 @@ export function useHandleEvents(id: string) {
|
|||
const info = inputs.pointerEnter(e, id)
|
||||
callbacks.onUnhoverHandle?.(info, e)
|
||||
},
|
||||
[callbacks, id]
|
||||
[inputs, callbacks, id]
|
||||
)
|
||||
|
||||
const onTouchStart = React.useCallback((e: React.TouchEvent) => {
|
||||
|
|
41
packages/core/src/hooks/useResizeObserver.ts
Normal file
41
packages/core/src/hooks/useResizeObserver.ts
Normal file
|
@ -0,0 +1,41 @@
|
|||
import { useTLContext } from '+hooks'
|
||||
import * as React from 'react'
|
||||
|
||||
export function useResizeObserver<T extends HTMLElement | SVGElement>(ref: React.RefObject<T>) {
|
||||
const { inputs } = useTLContext()
|
||||
|
||||
React.useEffect(() => {
|
||||
function handleScroll() {
|
||||
const rect = ref.current?.getBoundingClientRect()
|
||||
if (rect) {
|
||||
inputs.offset = [rect.left, rect.top]
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('scroll', handleScroll)
|
||||
return () => {
|
||||
window.removeEventListener('scroll', handleScroll)
|
||||
}
|
||||
}, [inputs])
|
||||
|
||||
React.useEffect(() => {
|
||||
const resizeObserver = new ResizeObserver((entries) => {
|
||||
if (inputs.isPinching) return
|
||||
|
||||
if (entries[0].contentRect) {
|
||||
const rect = ref.current?.getBoundingClientRect()
|
||||
if (rect) {
|
||||
inputs.offset = [rect.left, rect.top]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if (ref.current) {
|
||||
resizeObserver.observe(ref.current)
|
||||
}
|
||||
|
||||
return () => {
|
||||
resizeObserver.disconnect()
|
||||
}
|
||||
}, [ref, inputs])
|
||||
}
|
|
@ -1,10 +1,9 @@
|
|||
import * as React from 'react'
|
||||
import { inputs } from '+inputs'
|
||||
import { Utils } from '+utils'
|
||||
import { TLContext } from '+hooks'
|
||||
|
||||
export function useShapeEvents(id: string, disable = false) {
|
||||
const { rPageState, rScreenBounds, callbacks } = React.useContext(TLContext)
|
||||
const { rPageState, rScreenBounds, callbacks, inputs } = React.useContext(TLContext)
|
||||
|
||||
const onPointerDown = React.useCallback(
|
||||
(e: React.PointerEvent) => {
|
||||
|
@ -38,7 +37,7 @@ export function useShapeEvents(id: string, disable = false) {
|
|||
callbacks.onPointShape?.(info, e)
|
||||
callbacks.onPointerDown?.(info, e)
|
||||
},
|
||||
[callbacks, id, disable]
|
||||
[inputs, callbacks, id, disable]
|
||||
)
|
||||
|
||||
const onPointerUp = React.useCallback(
|
||||
|
@ -60,7 +59,7 @@ export function useShapeEvents(id: string, disable = false) {
|
|||
callbacks.onReleaseShape?.(info, e)
|
||||
callbacks.onPointerUp?.(info, e)
|
||||
},
|
||||
[callbacks, id, disable]
|
||||
[inputs, callbacks, id, disable]
|
||||
)
|
||||
|
||||
const onPointerMove = React.useCallback(
|
||||
|
@ -77,7 +76,7 @@ export function useShapeEvents(id: string, disable = false) {
|
|||
|
||||
callbacks.onPointerMove?.(info, e)
|
||||
},
|
||||
[callbacks, id, disable]
|
||||
[inputs, callbacks, id, disable]
|
||||
)
|
||||
|
||||
const onPointerEnter = React.useCallback(
|
||||
|
@ -86,7 +85,7 @@ export function useShapeEvents(id: string, disable = false) {
|
|||
const info = inputs.pointerEnter(e, id)
|
||||
callbacks.onHoverShape?.(info, e)
|
||||
},
|
||||
[callbacks, id, disable]
|
||||
[inputs, callbacks, id, disable]
|
||||
)
|
||||
|
||||
const onPointerLeave = React.useCallback(
|
||||
|
@ -95,7 +94,7 @@ export function useShapeEvents(id: string, disable = false) {
|
|||
const info = inputs.pointerEnter(e, id)
|
||||
callbacks.onUnhoverShape?.(info, e)
|
||||
},
|
||||
[callbacks, id, disable]
|
||||
[inputs, callbacks, id, disable]
|
||||
)
|
||||
|
||||
const onTouchStart = React.useCallback((e: React.TouchEvent) => {
|
||||
|
|
|
@ -185,14 +185,13 @@ const tlcss = css`
|
|||
pointer-events: none;
|
||||
}
|
||||
.tl-canvas {
|
||||
position: fixed;
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
touch-action: none;
|
||||
z-index: 100;
|
||||
pointer-events: all;
|
||||
}
|
||||
.tl-container {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import * as React from 'react'
|
||||
import type { Inputs } from '+inputs'
|
||||
import type { TLCallbacks, TLShape, TLBounds, TLPageState, TLShapeUtils } from '+types'
|
||||
|
||||
export interface TLContextType {
|
||||
|
@ -7,6 +8,7 @@ export interface TLContextType {
|
|||
shapeUtils: TLShapeUtils<TLShape>
|
||||
rPageState: React.MutableRefObject<TLPageState>
|
||||
rScreenBounds: React.MutableRefObject<TLBounds | null>
|
||||
inputs: Inputs
|
||||
}
|
||||
|
||||
export const TLContext = React.createContext<TLContextType>({} as TLContextType)
|
||||
|
|
|
@ -1,20 +1,22 @@
|
|||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
import { useRef } from 'react'
|
||||
import * as React from 'react'
|
||||
import { useTLContext } from './useTLContext'
|
||||
import { Vec } from '+utils'
|
||||
import { useWheel, usePinch } from 'react-use-gesture'
|
||||
import { inputs } from '+inputs'
|
||||
|
||||
// Capture zoom gestures (pinches, wheels and pans)
|
||||
export function useZoomEvents() {
|
||||
const rPinchDa = useRef<number[] | undefined>(undefined)
|
||||
const rOriginPoint = useRef<number[] | undefined>(undefined)
|
||||
const rPinchPoint = useRef<number[] | undefined>(undefined)
|
||||
export function useZoomEvents<T extends HTMLElement | SVGElement>(ref: React.RefObject<T>) {
|
||||
const rPinchDa = React.useRef<number[] | undefined>(undefined)
|
||||
const rOriginPoint = React.useRef<number[] | undefined>(undefined)
|
||||
const rPinchPoint = React.useRef<number[] | undefined>(undefined)
|
||||
|
||||
const { callbacks } = useTLContext()
|
||||
const { inputs, callbacks } = useTLContext()
|
||||
|
||||
useWheel(
|
||||
({ event: e, delta }) => {
|
||||
const elm = ref.current
|
||||
if (!(e.target === elm || elm?.contains(e.target as Node))) return
|
||||
|
||||
e.preventDefault()
|
||||
|
||||
if (Vec.isEqual(delta, [0, 0])) return
|
||||
|
@ -24,15 +26,20 @@ export function useZoomEvents() {
|
|||
callbacks.onPan?.(info, e)
|
||||
},
|
||||
{
|
||||
domTarget: typeof document === 'undefined' ? undefined : document.body,
|
||||
domTarget: window,
|
||||
eventOptions: { passive: false },
|
||||
}
|
||||
)
|
||||
|
||||
usePinch(
|
||||
({ pinching, da, origin, event: e }) => {
|
||||
const elm = ref.current
|
||||
if (!(e.target === elm || elm?.contains(e.target as Node))) return
|
||||
|
||||
const info = inputs.pinch(origin, origin)
|
||||
|
||||
if (!pinching) {
|
||||
const info = inputs.pinch(origin, origin)
|
||||
inputs.isPinching = false
|
||||
callbacks.onPinchEnd?.(
|
||||
info,
|
||||
e as React.WheelEvent<Element> | WheelEvent | React.TouchEvent<Element> | TouchEvent
|
||||
|
@ -44,14 +51,14 @@ export function useZoomEvents() {
|
|||
}
|
||||
|
||||
if (rPinchPoint.current === undefined) {
|
||||
const info = inputs.pinch(origin, origin)
|
||||
inputs.isPinching = true
|
||||
callbacks.onPinchStart?.(
|
||||
info,
|
||||
e as React.WheelEvent<Element> | WheelEvent | React.TouchEvent<Element> | TouchEvent
|
||||
)
|
||||
rPinchDa.current = da
|
||||
rPinchPoint.current = origin
|
||||
rOriginPoint.current = origin
|
||||
rPinchPoint.current = info.point
|
||||
rOriginPoint.current = info.point
|
||||
}
|
||||
|
||||
if (!rPinchDa.current) throw Error('No pinch direction!')
|
||||
|
@ -59,8 +66,6 @@ export function useZoomEvents() {
|
|||
|
||||
const [distanceDelta] = Vec.sub(rPinchDa.current, da)
|
||||
|
||||
const info = inputs.pinch(rPinchPoint.current, origin)
|
||||
|
||||
callbacks.onPinch?.(
|
||||
{
|
||||
...info,
|
||||
|
@ -75,7 +80,7 @@ export function useZoomEvents() {
|
|||
rPinchPoint.current = origin
|
||||
},
|
||||
{
|
||||
domTarget: typeof document === 'undefined' ? undefined : document.body,
|
||||
domTarget: window,
|
||||
eventOptions: { passive: false },
|
||||
}
|
||||
)
|
||||
|
|
|
@ -4,10 +4,13 @@ import { Vec, Utils } from './utils'
|
|||
|
||||
const DOUBLE_CLICK_DURATION = 250
|
||||
|
||||
class Inputs {
|
||||
export class Inputs {
|
||||
pointer?: TLPointerInfo<string>
|
||||
keyboard?: TLKeyboardInfo
|
||||
keys: Record<string, boolean> = {}
|
||||
isPinching = false
|
||||
|
||||
offset = [0, 0]
|
||||
|
||||
pointerUpTime = 0
|
||||
|
||||
|
@ -69,7 +72,7 @@ class Inputs {
|
|||
pointerDown<T extends string>(e: PointerEvent | React.PointerEvent, target: T): TLPointerInfo<T> {
|
||||
const { shiftKey, ctrlKey, metaKey, altKey } = e
|
||||
|
||||
const point = Inputs.getPoint(e)
|
||||
const point = Inputs.getPoint(e, this.offset)
|
||||
|
||||
const info: TLPointerInfo<T> = {
|
||||
target,
|
||||
|
@ -95,7 +98,7 @@ class Inputs {
|
|||
): TLPointerInfo<T> {
|
||||
const { shiftKey, ctrlKey, metaKey, altKey } = e
|
||||
|
||||
const point = Inputs.getPoint(e)
|
||||
const point = Inputs.getPoint(e, this.offset)
|
||||
|
||||
const info: TLPointerInfo<T> = {
|
||||
target,
|
||||
|
@ -120,7 +123,7 @@ class Inputs {
|
|||
|
||||
const prev = this.pointer
|
||||
|
||||
const point = Inputs.getPoint(e)
|
||||
const point = Inputs.getPoint(e, this.offset)
|
||||
|
||||
const delta = prev?.point ? Vec.sub(point, prev.point) : [0, 0]
|
||||
|
||||
|
@ -148,7 +151,7 @@ class Inputs {
|
|||
|
||||
const prev = this.pointer
|
||||
|
||||
const point = Inputs.getPoint(e)
|
||||
const point = Inputs.getPoint(e, this.offset)
|
||||
|
||||
const delta = prev?.point ? Vec.sub(point, prev.point) : [0, 0]
|
||||
|
||||
|
@ -182,7 +185,7 @@ class Inputs {
|
|||
origin: this.pointer?.origin || [0, 0],
|
||||
delta: [0, 0],
|
||||
pressure: 0.5,
|
||||
point: Inputs.getPoint(e),
|
||||
point: Inputs.getPoint(e, this.offset),
|
||||
shiftKey,
|
||||
ctrlKey,
|
||||
metaKey,
|
||||
|
@ -203,7 +206,7 @@ class Inputs {
|
|||
|
||||
const prev = this.pointer
|
||||
|
||||
const point = Inputs.getPoint(e)
|
||||
const point = Inputs.getPoint(e, this.offset)
|
||||
|
||||
const info: TLPointerInfo<'wheel'> = {
|
||||
...prev,
|
||||
|
@ -281,9 +284,9 @@ class Inputs {
|
|||
const info: TLPointerInfo<'pinch'> = {
|
||||
pointerId: 0,
|
||||
target: 'pinch',
|
||||
origin: prev?.origin || Vec.round(point),
|
||||
origin: prev?.origin || Vec.sub(Vec.round(point), this.offset),
|
||||
delta: delta,
|
||||
point: Vec.round(point),
|
||||
point: Vec.sub(Vec.round(point), this.offset),
|
||||
pressure: 0.5,
|
||||
shiftKey,
|
||||
ctrlKey,
|
||||
|
@ -304,9 +307,13 @@ class Inputs {
|
|||
}
|
||||
|
||||
static getPoint(
|
||||
e: PointerEvent | React.PointerEvent | Touch | React.Touch | WheelEvent
|
||||
e: PointerEvent | React.PointerEvent | Touch | React.Touch | WheelEvent,
|
||||
offset = [0, 0]
|
||||
): number[] {
|
||||
return [Number(e.clientX.toPrecision(5)), Number(e.clientY.toPrecision(5))]
|
||||
return [
|
||||
Number(e.clientX.toPrecision(5)) - offset[0],
|
||||
Number(e.clientY.toPrecision(5)) - offset[1],
|
||||
]
|
||||
}
|
||||
|
||||
static getPressure(e: PointerEvent | React.PointerEvent | Touch | React.Touch | WheelEvent) {
|
||||
|
|
|
@ -3,6 +3,7 @@ import type { TLPageState, TLBounds } from '../types'
|
|||
import { mockDocument } from './mockDocument'
|
||||
import { mockUtils } from './mockUtils'
|
||||
import { useTLTheme, TLContext } from '../hooks'
|
||||
import { Inputs } from '+inputs'
|
||||
|
||||
export const ContextWrapper: React.FC = ({ children }) => {
|
||||
useTLTheme()
|
||||
|
@ -14,6 +15,7 @@ export const ContextWrapper: React.FC = ({ children }) => {
|
|||
shapeUtils: mockUtils,
|
||||
rScreenBounds,
|
||||
rPageState,
|
||||
inputs: new Inputs(),
|
||||
}))
|
||||
|
||||
return <TLContext.Provider value={context}>{children}</TLContext.Provider>
|
||||
|
|
|
@ -9,6 +9,10 @@ if (!fs.existsSync('./dist')) {
|
|||
fs.mkdirSync('./dist')
|
||||
}
|
||||
|
||||
fs.copyFile('./src/styles.css', './dist/styles.css', (err) => {
|
||||
if (err) throw err
|
||||
})
|
||||
|
||||
fs.copyFile('./src/index.html', './dist/index.html', (err) => {
|
||||
if (err) throw err
|
||||
})
|
||||
|
|
|
@ -2,7 +2,8 @@ import * as React from 'react'
|
|||
import Basic from './basic'
|
||||
import Controlled from './controlled'
|
||||
import Imperative from './imperative'
|
||||
import Small from './small'
|
||||
|
||||
export default function App(): JSX.Element {
|
||||
return <Basic />
|
||||
return <Small />
|
||||
}
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<link rel="icon" href="favicon.ico" />
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>tldraw</title>
|
||||
</head>
|
||||
|
|
30
packages/dev/src/small.tsx
Normal file
30
packages/dev/src/small.tsx
Normal file
|
@ -0,0 +1,30 @@
|
|||
import * as React from 'react'
|
||||
import Editor from './components/editor'
|
||||
|
||||
export default function BasicUsage(): JSX.Element {
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
margin: '5%',
|
||||
width: 'calc(100% - 100px)',
|
||||
height: '500px',
|
||||
}}
|
||||
>
|
||||
<Editor id="small1" />
|
||||
</div>
|
||||
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
margin: '5%',
|
||||
width: 'calc(100% - 100px)',
|
||||
height: '500px',
|
||||
}}
|
||||
>
|
||||
<Editor id="small2" />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
8
packages/dev/src/styles.css
Normal file
8
packages/dev/src/styles.css
Normal file
|
@ -0,0 +1,8 @@
|
|||
html,
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
overscroll-behavior: none;
|
||||
}
|
|
@ -5,7 +5,7 @@ import styled from '~styles'
|
|||
/* -------------------------------------------------- */
|
||||
|
||||
export const DialogContent = styled('div', {
|
||||
position: 'fixed',
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: 'translate(-50%, -50%)',
|
||||
|
|
|
@ -227,17 +227,16 @@ const MenuButtons = styled('div', {
|
|||
gap: 8,
|
||||
})
|
||||
|
||||
const Layout = styled('main', {
|
||||
position: 'fixed',
|
||||
const Layout = styled('div', {
|
||||
overflow: 'hidden',
|
||||
top: 0,
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
position: 'absolute',
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
top: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
padding: '8px 8px 0 8px',
|
||||
zIndex: 200,
|
||||
display: 'flex',
|
||||
alignItems: 'flex-start',
|
||||
justifyContent: 'flex-start',
|
||||
|
@ -253,5 +252,7 @@ const Layout = styled('main', {
|
|||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
})
|
||||
|
|
|
@ -139,7 +139,7 @@ export const ToolsPanel = React.memo((): JSX.Element => {
|
|||
})
|
||||
|
||||
const ToolsPanelContainer = styled('div', {
|
||||
position: 'fixed',
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
|
|
|
@ -2231,11 +2231,11 @@ export class TLDrawState extends StateManager<Data> {
|
|||
}
|
||||
|
||||
onPinchEnd: TLPinchEventHandler = () => {
|
||||
if (this.state.settings.isZoomSnap) {
|
||||
const i = Math.round((this.pageState.camera.zoom * 100) / 25)
|
||||
const nextZoom = TLDR.getCameraZoom(i * 0.25)
|
||||
this.zoomTo(nextZoom, inputs.pointer?.point)
|
||||
}
|
||||
// if (this.state.settings.isZoomSnap) {
|
||||
// const i = Math.round((this.pageState.camera.zoom * 100) / 25)
|
||||
// const nextZoom = TLDR.getCameraZoom(i * 0.25)
|
||||
// this.zoomTo(nextZoom, inputs.pointer?.point)
|
||||
// }
|
||||
this.setStatus(this.appState.status.previous)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
import '@testing-library/jest-dom/extend-expect'
|
||||
import "fake-indexeddb/auto"
|
||||
import 'fake-indexeddb/auto'
|
||||
global.ResizeObserver = require('resize-observer-polyfill')
|
||||
|
|
|
@ -11417,6 +11417,11 @@ require_optional@^1.0.1:
|
|||
resolve-from "^2.0.0"
|
||||
semver "^5.1.0"
|
||||
|
||||
resize-observer-polyfill@^1.5.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464"
|
||||
integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==
|
||||
|
||||
resolve-cwd@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
|
||||
|
|
Loading…
Reference in a new issue