fix: pinching state for tools

This commit is contained in:
Peng Xiao
2022-08-17 11:10:43 +08:00
parent 92286819ed
commit fda26c291f
13 changed files with 89 additions and 19 deletions

View File

@@ -17,8 +17,8 @@ export class IdleState<
}
onPinchStart: TLStateEvents<S, K>['onPinchStart'] = (...args) => {
this.app.transition('select', { returnTo: 'box' })
this.app.onPinchStart?.(...args)
this.app.transition('select', { returnTo: this.app.currentState.id })
this.app._events.onPinchStart?.(...args)
}
onKeyDown: TLStateEvents<S>['onKeyDown'] = (info, e) => {

View File

@@ -17,8 +17,8 @@ export class IdleState<
}
onPinchStart: TLStateEvents<S, K>['onPinchStart'] = (...args) => {
this.app.transition('select', { returnTo: 'box' })
this.app.onPinchStart?.(...args)
this.app.transition('select', { returnTo: this.app.currentState.id })
this.app._events.onPinchStart?.(...args)
}
onKeyDown: TLStateEvents<S>['onKeyDown'] = (info, e) => {

View File

@@ -17,7 +17,7 @@ export class IdleState<
}
onPinchStart: TLStateEvents<S, K>['onPinchStart'] = (...args) => {
this.app.transition('select', { returnTo: 'draw' })
this.app.transition('select', { returnTo: this.app.currentState.id })
this.app._events.onPinchStart?.(...args)
}

View File

@@ -16,8 +16,8 @@ export class IdleState<
}
onPinchStart: TLStateEvents<S, K>['onPinchStart'] = (...args) => {
this.app.transition('select', { returnTo: 'draw' })
this.app.onPinchStart?.(...args)
this.app.transition('select', { returnTo: this.app.currentState.id })
this.app._events.onPinchStart?.(...args)
}
onKeyDown: TLStateEvents<S>['onKeyDown'] = (info, e) => {

View File

@@ -17,8 +17,8 @@ export class IdleState<
}
onPinchStart: TLStateEvents<S, K>['onPinchStart'] = (...args) => {
this.app.transition('select', { returnTo: 'Line' })
this.app.onPinchStart?.(...args)
this.app.transition('select', { returnTo: this.app.currentState.id })
this.app._events.onPinchStart?.(...args)
}
onKeyDown: TLStateEvents<S>['onKeyDown'] = (info, e) => {

View File

@@ -1,6 +1,6 @@
import { TLApp, TLShape, TLTool } from '~lib'
import { TLCursor, TLEventMap } from '~types'
import { IdleHoldState, IdleState, PanningState } from './states'
import { TLCursor, TLEventMap, TLStateEvents } from '~types'
import { IdleHoldState, IdleState, PanningState, PinchingState } from './states'
export class TLMoveTool<
S extends TLShape = TLShape,
@@ -10,7 +10,7 @@ export class TLMoveTool<
static id = 'move'
static shortcut = ['h']
static states = [IdleState, IdleHoldState, PanningState]
static states = [IdleState, IdleHoldState, PanningState, PinchingState]
static initial = 'idle'
@@ -21,4 +21,13 @@ export class TLMoveTool<
onEnter = (info: any) => {
this.prevTool = info?.prevTool
}
onKeyDown: TLStateEvents<S>['onKeyDown'] = (info, e) => {
switch (e.key) {
case 'Escape': {
this.app.transition('select')
break
}
}
}
}

View File

@@ -1,5 +1,5 @@
import { TLApp, TLShape, TLToolState } from '~lib'
import type { TLEventMap, TLStateEvents } from '~types'
import type { TLEventMap, TLEvents, TLStateEvents } from '~types'
import type { TLMoveTool } from '../TLMoveTool'
export class IdleHoldState<
@@ -14,4 +14,8 @@ export class IdleHoldState<
if (info.order) return
this.tool.transition('panning', { prevState: 'idleHold' })
}
onPinchStart: TLEvents<S>['pinch'] = (info, event) => {
this.tool.transition('pinching', { info, event })
}
}

View File

@@ -1,5 +1,5 @@
import { TLApp, TLShape, TLToolState } from '~lib'
import type { TLEventMap, TLStateEvents } from '~types'
import type { TLEventMap, TLEvents, TLStateEvents } from '~types'
import type { TLMoveTool } from '../TLMoveTool'
export class IdleState<
@@ -20,6 +20,10 @@ export class IdleState<
}
}
onPinchStart: TLEvents<S>['pinch'] = (info, event) => {
this.tool.transition('pinching', { info, event })
}
onPointerDown: TLStateEvents<S, K>['onPointerDown'] = (info, e) => {
if (info.order) return
this.tool.transition('panning')

View File

@@ -0,0 +1,46 @@
import { Vec } from '@tldraw/vec'
import { TLApp, TLMoveTool, TLShape, TLToolState } from '~lib'
import type { TLEventInfo, TLEventMap, TLEvents } from '~types'
type GestureInfo<
S extends TLShape,
K extends TLEventMap,
E extends TLEventInfo<S> = TLEventInfo<S>
> = {
info: E & { delta: number[]; point: number[]; offset: number[] }
event: K['wheel'] | K['pointer'] | K['touch'] | K['keyboard'] | K['gesture']
}
export class PinchingState<
S extends TLShape,
K extends TLEventMap,
R extends TLApp<S, K>,
P extends TLMoveTool<S, K, R>
> extends TLToolState<S, K, R, P> {
static id = 'pinching'
private origin: number[] = [0, 0]
private prevDelta: number[] = [0, 0]
private pinchCamera(point: number[], delta: number[], zoom: number) {
const { camera } = this.app.viewport
const nextPoint = Vec.sub(camera.point, Vec.div(delta, camera.zoom))
const p0 = Vec.sub(Vec.div(point, camera.zoom), nextPoint)
const p1 = Vec.sub(Vec.div(point, zoom), nextPoint)
this.app.setCamera(Vec.toFixed(Vec.add(nextPoint, Vec.sub(p1, p0))), zoom)
}
onEnter = (info: GestureInfo<S, K>) => {
this.prevDelta = info.info.delta
this.origin = info.info.point
}
onPinch: TLEvents<S>['pinch'] = info => {
this.pinchCamera(info.point, [0, 0], info.offset[0])
}
onPinchEnd: TLEvents<S>['pinch'] = () => {
this.tool.transition('idle')
}
}

View File

@@ -1,3 +1,4 @@
export * from './PanningState'
export * from './IdleState'
export * from './IdleHoldState'
export * from './PinchingState'

View File

@@ -53,4 +53,10 @@ export class TLSelectTool<
PinchingState,
EditingShapeState,
]
returnTo = ''
onEnter = (info: { fromId: string, returnTo: string } & any) => {
this.returnTo = info?.returnTo
}
}

View File

@@ -11,9 +11,9 @@ export class IdleState<
static id = 'idle'
onEnter = (info: { fromId: string } & any) => {
// if (info.fromId === 'editingShape') {
// this.onPointerDown(info as any, {} as any)
// }
if (info.fromId === 'pinching' && this.parent.returnTo) {
this.app.transition(this.parent.returnTo)
}
}
onExit = () => {

View File

@@ -17,8 +17,8 @@ export class IdleState<
}
onPinchStart: TLStateEvents<S, K>['onPinchStart'] = (...args) => {
this.app.transition('select', { returnTo: 'box' })
this.app.onPinchStart?.(...args)
this.app.transition('select', { returnTo: this.app.currentState.id })
this.app._events.onPinchStart?.(...args)
}
onKeyDown: TLStateEvents<S>['onKeyDown'] = (info, e) => {