feat(text): create text boxes by dragging
This commit is contained in:
parent
6a0009b25c
commit
f3fbc94abf
|
|
@ -3,7 +3,7 @@ import type { Ref } from 'vue'
|
||||||
import type { Editor } from '@open-pencil/core/editor'
|
import type { Editor } from '@open-pencil/core/editor'
|
||||||
|
|
||||||
import { startPenInput } from '#vue/canvas/pen-input/use'
|
import { startPenInput } from '#vue/canvas/pen-input/use'
|
||||||
import { startShapeDraw, startTextTool } from '#vue/shared/input/draw'
|
import { startShapeDraw, startTextDraw } from '#vue/shared/input/draw'
|
||||||
import { startPanDrag } from '#vue/shared/input/pan'
|
import { startPanDrag } from '#vue/shared/input/pan'
|
||||||
import { handleSelectDown } from '#vue/shared/input/select'
|
import { handleSelectDown } from '#vue/shared/input/select'
|
||||||
import type { HitTestFns } from '#vue/shared/input/select'
|
import type { HitTestFns } from '#vue/shared/input/select'
|
||||||
|
|
@ -67,7 +67,7 @@ export function handleToolMouseDown({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tool === 'TEXT') {
|
if (tool === 'TEXT') {
|
||||||
startTextTool(cx, cy, editor)
|
startTextDraw(cx, cy, editor, setDrag)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,17 @@ import type { Editor } from '@open-pencil/core/editor'
|
||||||
import { TOOL_TO_NODE } from '#vue/shared/input/types'
|
import { TOOL_TO_NODE } from '#vue/shared/input/types'
|
||||||
import type { DragDraw, DragState } from '#vue/shared/input/types'
|
import type { DragDraw, DragState } from '#vue/shared/input/types'
|
||||||
|
|
||||||
export function startTextTool(cx: number, cy: number, editor: Editor) {
|
export function startTextDraw(
|
||||||
const nodeId = editor.createShape('TEXT', cx, cy, DEFAULT_TEXT_WIDTH, DEFAULT_TEXT_HEIGHT)
|
cx: number,
|
||||||
|
cy: number,
|
||||||
|
editor: Editor,
|
||||||
|
setDrag: (d: DragState) => void
|
||||||
|
) {
|
||||||
|
editor.undo.beginBatch('Create text')
|
||||||
|
const nodeId = editor.createShape('TEXT', cx, cy, 0, 0)
|
||||||
editor.graph.updateNode(nodeId, { text: '' })
|
editor.graph.updateNode(nodeId, { text: '' })
|
||||||
editor.select([nodeId])
|
editor.select([nodeId])
|
||||||
editor.startTextEditing(nodeId)
|
setDrag({ type: 'draw', startX: cx, startY: cy, nodeId })
|
||||||
editor.setTool('SELECT')
|
|
||||||
editor.requestRender()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function startShapeDraw(
|
export function startShapeDraw(
|
||||||
|
|
@ -54,7 +58,14 @@ export function handleDrawMove(
|
||||||
|
|
||||||
export function handleDrawUp(d: DragDraw, editor: Editor) {
|
export function handleDrawUp(d: DragDraw, editor: Editor) {
|
||||||
const node = editor.graph.getNode(d.nodeId)
|
const node = editor.graph.getNode(d.nodeId)
|
||||||
if (node && node.width < 2 && node.height < 2) {
|
if (node?.type === 'TEXT') {
|
||||||
|
const isPointText = node.width < 2 && node.height < 2
|
||||||
|
editor.updateNode(d.nodeId, {
|
||||||
|
width: isPointText ? DEFAULT_TEXT_WIDTH : node.width,
|
||||||
|
height: isPointText ? DEFAULT_TEXT_HEIGHT : node.height,
|
||||||
|
textAutoResize: isPointText ? 'WIDTH_AND_HEIGHT' : 'NONE'
|
||||||
|
})
|
||||||
|
} else if (node && node.width < 2 && node.height < 2) {
|
||||||
editor.updateNode(d.nodeId, { width: 100, height: 100 })
|
editor.updateNode(d.nodeId, { width: 100, height: 100 })
|
||||||
}
|
}
|
||||||
if (node?.type === 'SECTION') {
|
if (node?.type === 'SECTION') {
|
||||||
|
|
@ -63,4 +74,5 @@ export function handleDrawUp(d: DragDraw, editor: Editor) {
|
||||||
editor.commitResize(d.nodeId, { x: d.startX, y: d.startY, width: 0, height: 0 })
|
editor.commitResize(d.nodeId, { x: d.startX, y: d.startY, width: 0, height: 0 })
|
||||||
editor.undo.commitBatch()
|
editor.undo.commitBatch()
|
||||||
editor.setTool('SELECT')
|
editor.setTool('SELECT')
|
||||||
|
if (node?.type === 'TEXT') editor.startTextEditing(node.id)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,9 +39,10 @@ test('clicking with text tool creates a text node', async () => {
|
||||||
expect(textNode).toBeTruthy()
|
expect(textNode).toBeTruthy()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('text node is selected after creation', async () => {
|
test('point text is selected and auto-sizes after creation', async () => {
|
||||||
const node = await getSelectedNode(editor.page)
|
const node = await getSelectedNode(editor.page)
|
||||||
expect(node?.type).toBe('TEXT')
|
expect(node?.type).toBe('TEXT')
|
||||||
|
expect(node?.textAutoResize).toBe('WIDTH_AND_HEIGHT')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('typography section appears for text node', async () => {
|
test('typography section appears for text node', async () => {
|
||||||
|
|
@ -63,6 +64,26 @@ test('text node has default font properties', async () => {
|
||||||
expect(node?.fontFamily).toBeTruthy()
|
expect(node?.fontFamily).toBeTruthy()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('dragging with the text tool creates a fixed-width text box', async () => {
|
||||||
|
await editor.page.keyboard.press('Escape')
|
||||||
|
await editor.page.keyboard.press('t')
|
||||||
|
await editor.canvas.drag(300, 120, 520, 240)
|
||||||
|
await editor.canvas.waitForRender()
|
||||||
|
|
||||||
|
const node = expectDefined(await getSelectedNode(editor.page), 'selected text box')
|
||||||
|
expect(node.type).toBe('TEXT')
|
||||||
|
expect(node.width).toBeCloseTo(220)
|
||||||
|
expect(node.height).toBeCloseTo(120)
|
||||||
|
expect(node.textAutoResize).toBe('NONE')
|
||||||
|
|
||||||
|
const editingTextId = await editor.page.evaluate(() => {
|
||||||
|
const store = window.openPencil?.getStore?.()
|
||||||
|
if (!store) throw new Error('OpenPencil store not initialized')
|
||||||
|
return store.state.editingTextId
|
||||||
|
})
|
||||||
|
expect(editingTextId).toBe(node.id)
|
||||||
|
})
|
||||||
|
|
||||||
test('creating text via store works', async () => {
|
test('creating text via store works', async () => {
|
||||||
await editor.page.keyboard.press('Escape')
|
await editor.page.keyboard.press('Escape')
|
||||||
await editor.canvas.waitForRender()
|
await editor.canvas.waitForRender()
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,8 @@ export function getSelectedNode(page: Page) {
|
||||||
fontSize: n.fontSize,
|
fontSize: n.fontSize,
|
||||||
fontFamily: n.fontFamily,
|
fontFamily: n.fontFamily,
|
||||||
fontWeight: n.fontWeight,
|
fontWeight: n.fontWeight,
|
||||||
italic: n.italic
|
italic: n.italic,
|
||||||
|
textAutoResize: n.textAutoResize
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue