stickies: create multiple when holding shift key down

pull/3102/head
Mime Čuvalo 2024-03-11 10:20:42 +00:00
rodzic a8b7d4e2d0
commit 0f25266eba
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: BA84499022AC984D
2 zmienionych plików z 87 dodań i 52 usunięć

Wyświetl plik

@ -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

Wyświetl plik

@ -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)!
}