Skip to content

Commit

Permalink
refactor: convert from arrays to maps for some types
Browse files Browse the repository at this point in the history
  • Loading branch information
pengx17 committed May 26, 2022
1 parent b878b12 commit 811d392
Show file tree
Hide file tree
Showing 17 changed files with 130 additions and 281 deletions.
156 changes: 0 additions & 156 deletions tldraw/apps/tldraw-logseq/src/documents/withEverything.ts

This file was deleted.

8 changes: 4 additions & 4 deletions tldraw/apps/tldraw-logseq/src/lib/shapes/LineShape.tsx
Expand Up @@ -17,10 +17,10 @@ export class LineShape extends TLLineShape<LineShapeProps> {
parentId: 'page',
type: 'line',
point: [0, 0],
handles: [
{ id: 'start', canBind: true, point: [0, 0] },
{ id: 'end', canBind: true, point: [1, 1] },
],
handles: {
start: { id: 'start', canBind: true, point: [0, 0] },
end: { id: 'end', canBind: true, point: [1, 1] },
},
stroke: '#000000',
fill: '#ffffff',
strokeWidth: 2,
Expand Down
2 changes: 1 addition & 1 deletion tldraw/packages/core/src/lib/TLApp/TLApp.ts
Expand Up @@ -223,7 +223,7 @@ export class TLApp<
/* ---------------------- Pages --------------------- */

@observable pages: Map<string, TLPage<S, K>> = new Map([
['page', new TLPage(this, { id: 'page', name: 'page', shapes: [], bindings: [] })],
['page', new TLPage(this, { id: 'page', name: 'page', shapes: [], bindings: {} })],
])

@observable currentPageId = 'page'
Expand Down
12 changes: 6 additions & 6 deletions tldraw/packages/core/src/lib/TLPage/TLPage.ts
Expand Up @@ -2,26 +2,26 @@
import { action, observable, makeObservable, computed, observe } from 'mobx'
import { TLBinding, TLEventMap, TLResizeCorner } from '~types'
import type { TLApp, TLShape, TLShapeModel } from '~lib'
import { BoundsUtils } from '~utils'
import { BoundsUtils, deepCopy } from '~utils'

export interface TLPageModel<S extends TLShape = TLShape> {
id: string
name: string
shapes: TLShapeModel<S['props']>[]
bindings: TLBinding[]
bindings: Record<string, TLBinding>
nonce?: number
}

export interface TLPageProps<S> {
id: string
name: string
shapes: S[]
bindings: TLBinding[]
bindings: Record<string, TLBinding>
}

export class TLPage<S extends TLShape = TLShape, E extends TLEventMap = TLEventMap> {
constructor(app: TLApp<S, E>, props = {} as TLPageProps<S>) {
const { id, name, shapes = [], bindings = [] } = props
const { id, name, shapes = [], bindings = {} } = props
this.id = id
this.name = name
this.bindings = bindings
Expand All @@ -38,14 +38,14 @@ export class TLPage<S extends TLShape = TLShape, E extends TLEventMap = TLEventM

@observable shapes: S[] = []

@observable bindings: TLBinding[]
@observable bindings: Record<string, TLBinding>

@computed get serialized(): TLPageModel<S> {
return {
id: this.id,
name: this.name,
shapes: this.shapes.map(shape => shape.serialized),
bindings: this.bindings.map(binding => ({ ...binding })),
bindings: deepCopy(this.bindings),
nonce: this.nonce,
}
}
Expand Down
Expand Up @@ -13,10 +13,10 @@ describe('A minimal test', () => {
type: 'dot',
parentId: 'page',
point: [0, 0],
handles: [
{ id: 'start', point: [0, 0] },
{ id: 'end', point: [0, 0] },
],
handles: {
start: { id: 'start', canBind: true, point: [0, 0] },
end: { id: 'end', canBind: true, point: [1, 1] },
},
stroke: 'black',
}
}
Expand Down
41 changes: 25 additions & 16 deletions tldraw/packages/core/src/lib/shapes/TLLineShape/TLLineShape.tsx
Expand Up @@ -5,7 +5,7 @@ import { BoundsUtils, deepMerge } from '~utils'
import { TLPolylineShape, TLPolylineShapeProps } from '../TLPolylineShape'

export interface TLLineShapeProps extends TLPolylineShapeProps {
handles: TLHandle[]
handles: Record<'start' | 'end' | string, TLHandle>
}

export class TLLineShape<
Expand All @@ -24,38 +24,45 @@ export class TLLineShape<
type: 'line',
parentId: 'page',
point: [0, 0],
handles: [
{ id: 'start', canBind: true, point: [0, 0] },
{ id: 'end', canBind: true, point: [1, 1] },
],
handles: {
start: { id: 'start', canBind: true, point: [0, 0] },
end: { id: 'end', canBind: true, point: [1, 1] },
},
}

validateProps = (props: Partial<P>) => {
if (props.point) props.point = [0, 0]
if (props.handles !== undefined && props.handles.length < 1)
props.handles = [{ point: [0, 0], id: 'start' }]
if (props.handles !== undefined && Object.values(props.handles).length < 1)
props.handles = TLLineShape.defaultProps['handles']
return props
}

getHandlesChange = (initialShape: P, handles: Partial<TLHandle>[]): P | void => {
let nextHandles = handles.map((h, i) => deepMerge(initialShape.handles[i] ?? {}, h))
nextHandles = nextHandles.map(h => ({ ...h, point: Vec.toFixed(h.point) }))
getHandlesChange = (shape: P, handles: Partial<P['handles']>): Partial<P> | undefined => {
let nextHandles = deepMerge(shape.handles, handles)

if (nextHandles.length !== 2 || Vec.isEqual(nextHandles[0].point, nextHandles[1].point)) {
return
}
nextHandles = deepMerge(nextHandles, {
start: {
point: Vec.toFixed(nextHandles.start.point),
},
end: {
point: Vec.toFixed(nextHandles.end.point),
},
})

// This will produce NaN values
if (Vec.isEqual(nextHandles.start.point, nextHandles.end.point)) return

const nextShape = {
...initialShape,
point: shape.point,
handles: nextHandles,
}

// Zero out the handles to prevent handles with negative points. If a handle's x or y
// is below zero, we need to move the shape left or up to make it zero.
const topLeft = initialShape.point
const topLeft = shape.point

const nextBounds = BoundsUtils.translateBounds(
BoundsUtils.getBoundsFromPoints(nextHandles.map(h => h.point)),
BoundsUtils.getBoundsFromPoints(Object.values(nextHandles).map(h => h.point)),
nextShape.point
)

Expand All @@ -67,6 +74,8 @@ export class TLLineShape<
})
nextShape.point = Vec.toFixed(Vec.add(nextShape.point, offset))
}

// @ts-expect-error ???
return nextShape
}
}
Expand Up @@ -12,10 +12,10 @@ describe('A minimal test', () => {
type: 'dot',
parentId: 'page',
point: [0, 0],
handles: [
{ id: 'start', point: [0, 0] },
{ id: 'end', point: [0, 0] },
],
handles: {
start: { id: 'start', canBind: true, point: [0, 0] },
end: { id: 'end', canBind: true, point: [1, 1] },
},
stroke: 'black',
}
}
Expand Down
Expand Up @@ -11,7 +11,7 @@ import { BoundsUtils, PointUtils, PolygonUtils } from '~utils'
import { TLShapeProps, TLResizeInfo, TLShape } from '../TLShape'

export interface TLPolylineShapeProps extends TLShapeProps {
handles: TLHandle[]
handles: Record<string, TLHandle>
}

export class TLPolylineShape<
Expand All @@ -30,11 +30,11 @@ export class TLPolylineShape<
type: 'polyline',
parentId: 'page',
point: [0, 0],
handles: [{ id: '0', point: [0, 0] }],
handles: {},
}

@computed get points() {
return this.props.handles.map(h => h.point)
return Object.values(this.props.handles).map(h => h.point)
}

@computed get centroid() {
Expand All @@ -48,7 +48,7 @@ export class TLPolylineShape<
props: { handles, rotation },
} = this
if (!rotation) return this.points
return handles.map(h => Vec.rotWith(h.point, centroid, rotation))
return Object.values(handles).map(h => Vec.rotWith(h.point, centroid, rotation))
}

getBounds = (): TLBounds => {
Expand Down Expand Up @@ -76,7 +76,7 @@ export class TLPolylineShape<
} = this
this.scale = [...(this.props.scale ?? [1, 1])]
const size = [bounds.width, bounds.height]
this.normalizedHandles = handles.map(h => Vec.divV(h.point, size))
this.normalizedHandles = Object.values(handles).map(h => Vec.divV(h.point, size))
return this
}

Expand All @@ -95,7 +95,7 @@ export class TLPolylineShape<
if (scaleY < 0) nextScale[1] *= -1
return this.update({
point: [bounds.minX, bounds.minY],
handles: handles.map((handle, i) => ({
handles: Object.values(handles).map((handle, i) => ({
...handle,
point: Vec.mulV(normalizedHandles[i], size),
})),
Expand Down Expand Up @@ -146,7 +146,8 @@ export class TLPolylineShape<

validateProps = (props: Partial<P>) => {
if (props.point) props.point = [0, 0]
if (props.handles !== undefined && props.handles.length < 1) props.handles = [{ point: [0, 0] }]
if (props.handles !== undefined && Object.values(props.handles).length < 1)
props.handles = TLPolylineShape.defaultProps['handles']
return props
}
}
23 changes: 13 additions & 10 deletions tldraw/packages/core/src/lib/shapes/TLShape/TLShape.ts
Expand Up @@ -9,7 +9,7 @@ import Vec from '@tldraw/vec'
import { action, computed, makeObservable, observable, toJS } from 'mobx'
import { BINDING_DISTANCE } from '~constants'
import type { TLAsset, TLBounds, TLHandle, TLResizeCorner, TLResizeEdge } from '~types'
import { BoundsUtils, PointUtils } from '~utils'
import { BoundsUtils, deepCopy, PointUtils } from '~utils'

export type TLShapeModel<P extends TLShapeProps = TLShapeProps> = {
nonce?: number
Expand All @@ -30,7 +30,7 @@ export interface TLShapeProps {
point: number[]
scale?: number[]
rotation?: number
handles?: TLHandle[]
handles?: Record<string, TLHandle>
label?: string
labelPosition?: number[]
clipping?: number | number[]
Expand Down Expand Up @@ -64,7 +64,7 @@ export interface TLResetBoundsInfo<T extends TLAsset> {
}

export interface TLHandleChangeInfo {
index: number
id: string
delta: number[]
}

Expand Down Expand Up @@ -313,17 +313,20 @@ export abstract class TLShape<P extends TLShapeProps = TLShapeProps, M = any> {
return this
}

onHandleChange = (initialShape: any, { index, delta }: TLHandleChangeInfo) => {
onHandleChange = (initialShape: any, { id, delta }: TLHandleChangeInfo) => {
if (initialShape.handles === undefined) return
const nextHandles = [...initialShape.handles]
nextHandles[index] = {
...nextHandles[index],
point: Vec.add(delta, initialShape.handles[index].point),
const nextHandles: Record<string, TLHandle> = deepCopy(initialShape.handles)
nextHandles[id] = {
...nextHandles[id],
point: Vec.add(delta, initialShape.handles[id].point),
}
const topLeft = BoundsUtils.getCommonTopLeft(nextHandles.map(h => h.point))
const topLeft = BoundsUtils.getCommonTopLeft(Object.values(nextHandles).map(h => h.point))
Object.values(nextHandles).forEach(h => {
h.point = Vec.sub(h.point, topLeft)
})
this.update({
point: Vec.add(initialShape.point, topLeft),
handles: nextHandles.map(h => ({ ...h, point: Vec.sub(h.point, topLeft) })),
handles: nextHandles
})
}
}

0 comments on commit 811d392

Please sign in to comment.