kopia lustrzana https://github.com/Tldraw/Tldraw
stickies: create multiple when holding shift key down
rodzic
a8b7d4e2d0
commit
0f25266eba
|
@ -18,7 +18,7 @@ import { FONT_FAMILIES, LABEL_FONT_SIZES, TEXT_PROPS } from '../shared/default-s
|
|||
import { getFontDefForExport } from '../shared/defaultStyleDefs'
|
||||
import { getTextLabelSvgElement } from '../shared/getTextLabelSvgElement'
|
||||
|
||||
const NOTE_SIZE = 200
|
||||
export const INITIAL_NOTE_SIZE = 200
|
||||
|
||||
/** @public */
|
||||
export class NoteShapeUtil extends ShapeUtil<TLNoteShape> {
|
||||
|
@ -44,12 +44,12 @@ export class NoteShapeUtil extends ShapeUtil<TLNoteShape> {
|
|||
}
|
||||
|
||||
getHeight(shape: TLNoteShape) {
|
||||
return NOTE_SIZE + shape.props.growY
|
||||
return INITIAL_NOTE_SIZE + shape.props.growY
|
||||
}
|
||||
|
||||
getGeometry(shape: TLNoteShape) {
|
||||
const height = this.getHeight(shape)
|
||||
return new Rectangle2d({ width: NOTE_SIZE, height, isFilled: true })
|
||||
return new Rectangle2d({ width: INITIAL_NOTE_SIZE, height, isFilled: true })
|
||||
}
|
||||
|
||||
component(shape: TLNoteShape) {
|
||||
|
@ -68,7 +68,7 @@ export class NoteShapeUtil extends ShapeUtil<TLNoteShape> {
|
|||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
width: NOTE_SIZE,
|
||||
width: INITIAL_NOTE_SIZE,
|
||||
height: this.getHeight(shape),
|
||||
}}
|
||||
>
|
||||
|
@ -104,7 +104,7 @@ export class NoteShapeUtil extends ShapeUtil<TLNoteShape> {
|
|||
return (
|
||||
<rect
|
||||
rx="6"
|
||||
width={toDomPrecision(NOTE_SIZE)}
|
||||
width={toDomPrecision(INITIAL_NOTE_SIZE)}
|
||||
height={toDomPrecision(this.getHeight(shape))}
|
||||
/>
|
||||
)
|
||||
|
@ -121,7 +121,7 @@ export class NoteShapeUtil extends ShapeUtil<TLNoteShape> {
|
|||
|
||||
const rect1 = document.createElementNS('http://www.w3.org/2000/svg', 'rect')
|
||||
rect1.setAttribute('rx', '10')
|
||||
rect1.setAttribute('width', NOTE_SIZE.toString())
|
||||
rect1.setAttribute('width', INITIAL_NOTE_SIZE.toString())
|
||||
rect1.setAttribute('height', bounds.height.toString())
|
||||
rect1.setAttribute('fill', theme[adjustedColor].solid)
|
||||
rect1.setAttribute('stroke', theme[adjustedColor].solid)
|
||||
|
@ -130,7 +130,7 @@ export class NoteShapeUtil extends ShapeUtil<TLNoteShape> {
|
|||
|
||||
const rect2 = document.createElementNS('http://www.w3.org/2000/svg', 'rect')
|
||||
rect2.setAttribute('rx', '10')
|
||||
rect2.setAttribute('width', NOTE_SIZE.toString())
|
||||
rect2.setAttribute('width', INITIAL_NOTE_SIZE.toString())
|
||||
rect2.setAttribute('height', bounds.height.toString())
|
||||
rect2.setAttribute('fill', theme.background)
|
||||
rect2.setAttribute('opacity', '.28')
|
||||
|
@ -194,15 +194,15 @@ function getGrowY(editor: Editor, shape: TLNoteShape, prevGrowY = 0) {
|
|||
...TEXT_PROPS,
|
||||
fontFamily: FONT_FAMILIES[shape.props.font],
|
||||
fontSize: LABEL_FONT_SIZES[shape.props.size],
|
||||
maxWidth: NOTE_SIZE - PADDING * 2,
|
||||
maxWidth: INITIAL_NOTE_SIZE - PADDING * 2,
|
||||
})
|
||||
|
||||
const nextHeight = nextTextSize.h + PADDING * 2
|
||||
|
||||
let growY: number | null = null
|
||||
|
||||
if (nextHeight > NOTE_SIZE) {
|
||||
growY = nextHeight - NOTE_SIZE
|
||||
if (nextHeight > INITIAL_NOTE_SIZE) {
|
||||
growY = nextHeight - INITIAL_NOTE_SIZE
|
||||
} else {
|
||||
if (prevGrowY) {
|
||||
growY = 0
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
import {
|
||||
Editor,
|
||||
StateNode,
|
||||
TLEventHandlers,
|
||||
TLInterruptEvent,
|
||||
TLNoteShape,
|
||||
TLPointerEventInfo,
|
||||
TLShapeId,
|
||||
Vec,
|
||||
createShapeId,
|
||||
} from '@tldraw/editor'
|
||||
import { INITIAL_NOTE_SIZE } from '../NoteShapeUtil'
|
||||
|
||||
export class Pointing extends StateNode {
|
||||
static override id = 'pointing'
|
||||
|
@ -19,31 +23,60 @@ export class Pointing extends StateNode {
|
|||
markId = ''
|
||||
|
||||
shape = {} as TLNoteShape
|
||||
shapes = [] as TLNoteShape[]
|
||||
startingPoint = {} as Vec
|
||||
|
||||
override onEnter = () => {
|
||||
this.wasFocusedOnEnter = !this.editor.getIsMenuOpen()
|
||||
|
||||
if (this.wasFocusedOnEnter) {
|
||||
this.shape = this.createShape()
|
||||
const id = createShapeId()
|
||||
this.markId = `creating:${id}`
|
||||
this.editor.mark(this.markId)
|
||||
this.shape = createSticky(this.editor, id)
|
||||
this.shapes = [this.shape]
|
||||
}
|
||||
|
||||
this.startingPoint = this.editor.inputs.currentPagePoint.clone()
|
||||
}
|
||||
|
||||
override onPointerMove: TLEventHandlers['onPointerMove'] = (info) => {
|
||||
if (this.editor.inputs.isDragging) {
|
||||
if (!this.wasFocusedOnEnter) {
|
||||
this.shape = this.createShape()
|
||||
}
|
||||
if (info.shiftKey) {
|
||||
const distance =
|
||||
Math.abs(this.startingPoint.dist(this.editor.inputs.currentPagePoint)) +
|
||||
INITIAL_NOTE_SIZE * 1.1
|
||||
const numberOfNotesToCreate = Math.max(1, Math.floor(distance / (INITIAL_NOTE_SIZE / 0.9)))
|
||||
const prevNumberOfNotesToCreate = this.shapes.length
|
||||
if (numberOfNotesToCreate > prevNumberOfNotesToCreate) {
|
||||
const newShapes = new Array(numberOfNotesToCreate - prevNumberOfNotesToCreate).fill(
|
||||
createSticky(this.editor, undefined /* id */, this.editor.inputs.currentPagePoint)
|
||||
)
|
||||
this.shapes = this.shapes.concat(newShapes)
|
||||
this.shape = this.shapes[this.shapes.length - 1]
|
||||
} else if (numberOfNotesToCreate < prevNumberOfNotesToCreate) {
|
||||
const shapesToDelete = this.shapes.slice(numberOfNotesToCreate)
|
||||
this.editor.deleteShapes(shapesToDelete.map((s) => s.id))
|
||||
this.shapes = this.shapes.slice(0, numberOfNotesToCreate)
|
||||
this.shape = this.shapes[this.shapes.length - 1]
|
||||
}
|
||||
} else {
|
||||
if (!this.wasFocusedOnEnter) {
|
||||
this.shape = createSticky(this.editor, createShapeId())
|
||||
}
|
||||
|
||||
this.editor.setCurrentTool('select.translating', {
|
||||
...info,
|
||||
target: 'shape',
|
||||
shape: this.shape,
|
||||
onInteractionEnd: 'note',
|
||||
isCreating: true,
|
||||
onCreate: () => {
|
||||
this.editor.setEditingShape(this.shape.id)
|
||||
this.editor.setCurrentTool('select.editing_shape')
|
||||
},
|
||||
})
|
||||
this.editor.setCurrentTool('select.translating', {
|
||||
...info,
|
||||
target: 'shape',
|
||||
shape: this.shape,
|
||||
onInteractionEnd: 'note',
|
||||
isCreating: true,
|
||||
onCreate: () => {
|
||||
this.editor.setEditingShape(this.shape.id)
|
||||
this.editor.setCurrentTool('select.editing_shape')
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,46 +109,48 @@ export class Pointing extends StateNode {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
this.shapes = []
|
||||
}
|
||||
|
||||
private cancel() {
|
||||
this.shapes = []
|
||||
this.editor.bailToMark(this.markId)
|
||||
this.parent.transition('idle', this.info)
|
||||
}
|
||||
}
|
||||
|
||||
private createShape() {
|
||||
const {
|
||||
inputs: { originPagePoint },
|
||||
} = this.editor
|
||||
export function createSticky(editor: Editor, id?: TLShapeId, creationPoint?: Vec) {
|
||||
const {
|
||||
inputs: { originPagePoint },
|
||||
} = editor
|
||||
|
||||
const id = createShapeId()
|
||||
this.markId = `creating:${id}`
|
||||
this.editor.mark(this.markId)
|
||||
creationPoint = creationPoint || originPagePoint
|
||||
id = id || createShapeId()
|
||||
|
||||
this.editor
|
||||
.createShapes([
|
||||
{
|
||||
id,
|
||||
type: 'note',
|
||||
x: originPagePoint.x,
|
||||
y: originPagePoint.y,
|
||||
},
|
||||
])
|
||||
.select(id)
|
||||
|
||||
const shape = this.editor.getShape<TLNoteShape>(id)!
|
||||
const bounds = this.editor.getShapeGeometry(shape).bounds
|
||||
|
||||
// Center the text around the created point
|
||||
this.editor.updateShapes([
|
||||
editor
|
||||
.createShapes([
|
||||
{
|
||||
id,
|
||||
type: 'note',
|
||||
x: shape.x - bounds.width / 2,
|
||||
y: shape.y - bounds.height / 2,
|
||||
x: creationPoint.x,
|
||||
y: creationPoint.y,
|
||||
},
|
||||
])
|
||||
.select(id)
|
||||
|
||||
return this.editor.getShape<TLNoteShape>(id)!
|
||||
}
|
||||
const shape = editor.getShape<TLNoteShape>(id)!
|
||||
const bounds = editor.getShapeGeometry(shape).bounds
|
||||
|
||||
// Center the text around the created point
|
||||
editor.updateShapes([
|
||||
{
|
||||
id,
|
||||
type: 'note',
|
||||
x: shape.x - bounds.width / 2,
|
||||
y: shape.y - bounds.height / 2,
|
||||
},
|
||||
])
|
||||
|
||||
return editor.getShape<TLNoteShape>(id)!
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue