Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions packages/presentation/src/___tests___/drawing.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -593,5 +593,54 @@ describe('drawing module tests', () => {
])
})
})

describe('tools selection', () => {
it('select color after panning', () => {
const colorsList: ColorsList = [
['alpha', new ThemeAwareColor('red', 'yellow')],
['beta', new ThemeAwareColor('blue', 'blue')]
]

const toolChangedSpy = jest.fn()

const initialPenColor: ColorMetaNameOrHex = 'alpha'
const systemUnderTest = drawing(drawingPlugInPoint, {
colorsList,
getCurrentTheme: () => 'theme-light',
subscribeOnThemeChange: () => {},
readonly: false,
imageWidth: 400,
imageHeight: 300,
commands: [],
tool: 'pen',
penColor: initialPenColor,
toolChanged: toolChangedSpy
})

systemUnderTest.update?.({
colorsList,
getCurrentTheme: () => 'theme-light',
subscribeOnThemeChange: () => {},
readonly: false,
tool: 'pan',
toolChanged: toolChangedSpy
})

expect(toolChangedSpy).toHaveBeenCalledWith('pan')
toolChangedSpy.mockClear()

const newColor: ColorMetaNameOrHex = 'beta'
systemUnderTest.update?.({
colorsList,
getCurrentTheme: () => 'theme-light',
subscribeOnThemeChange: () => {},
readonly: false,
penColor: newColor,
toolChanged: toolChangedSpy
})

expect(toolChangedSpy).toHaveBeenCalledWith('pen')
})
})
})
})
4 changes: 4 additions & 0 deletions packages/presentation/src/components/DrawingBoard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@
penWidth,
eraserWidth,
fontSize,
enableMiddleMousePanning: false,
changingCmdId,
cmdAdded: addCommand,
cmdChanging: showCommandProps,
Expand All @@ -240,6 +241,9 @@
cmdDeleted: deleteCommand,
editorCreated: (editor) => {
cmdEditor = editor
},
toolChanged: (newTool) => {
tool = newTool
}
}}
>
Expand Down
77 changes: 60 additions & 17 deletions packages/presentation/src/drawing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export interface DrawingProps {
changingCmdId?: CommandUid
personCursorPos?: Point
personCursorVisible?: boolean
enableMiddleMousePanning?: boolean
cmdAdded?: (cmd: DrawingCmd) => void
cmdChanging?: (id: CommandUid) => void
cmdUnchanged?: (id: CommandUid) => void
Expand All @@ -67,6 +68,7 @@ export interface DrawingProps {
personCursorMoved?: (nodePos: Point) => void
panning?: (offset: Point) => void
panned?: (offset: Point) => void
toolChanged?: (tool: DrawingTool) => void
}

export type DrawingTool = 'pen' | 'erase' | 'pan' | 'text'
Expand All @@ -81,6 +83,7 @@ type PointStatus = 'last-point' | 'intermediate-point'

class DrawState {
on = false
usedBeforePanningTool: DrawingTool | undefined = undefined
tool: DrawingTool = 'pen'
penColor: ColorMetaNameOrHex = 'alpha'
penWidth = 4
Expand Down Expand Up @@ -373,6 +376,7 @@ export function drawing (
resizeObserver.observe(canvas)

let touchId: number | undefined
let isMiddleMousePanning = false

function findTouch (touches: TouchList, id: number | undefined = touchId): Touch | undefined {
for (let i = 0; i < touches.length; i++) {
Expand All @@ -398,7 +402,8 @@ export function drawing (
}
const touch = e.changedTouches[0]
touchId = touch.identifier
drawStart(touchToNodePoint(touch, canvas))
const forcePan = false
drawStart(touchToNodePoint(touch, canvas), forcePan)
}

canvas.ontouchmove = (e) => {
Expand All @@ -407,7 +412,8 @@ export function drawing (
}
const touch = findTouch(e.changedTouches)
if (touch !== undefined) {
drawContinue(touchToNodePoint(touch, canvas))
const forcePan = false
drawContinue(touchToNodePoint(touch, canvas), forcePan)
}
}

Expand All @@ -417,7 +423,8 @@ export function drawing (
}
const touch = findTouch(e.changedTouches)
if (touch !== undefined) {
drawEnd(touchToNodePoint(touch, canvas))
const forcePan = false
drawEnd(touchToNodePoint(touch, canvas), forcePan)
}
touchId = undefined
}
Expand All @@ -428,20 +435,31 @@ export function drawing (
if (readonly) {
return
}
const MiddleMouseButton = 1
if (e.button === MiddleMouseButton && props.enableMiddleMousePanning === true) {
e.preventDefault()
isMiddleMousePanning = true
canvas.setPointerCapture(e.pointerId)
const forcePan = true
drawStart(pointerToNodePoint(e), forcePan)
return
}
if (e.button !== 0) {
return
}
e.preventDefault()
canvas.setPointerCapture(e.pointerId)
drawStart(pointerToNodePoint(e))
const forcePan = false
drawStart(pointerToNodePoint(e), forcePan)
}

canvas.onpointermove = (e) => {
if (readonly) {
return
}
e.preventDefault()
drawContinue(pointerToNodePoint(e))
const forcePan = isMiddleMousePanning
drawContinue(pointerToNodePoint(e), forcePan)
}

canvas.onpointerup = (e) => {
Expand All @@ -450,10 +468,23 @@ export function drawing (
}
e.preventDefault()
canvas.releasePointerCapture(e.pointerId)
drawEnd(pointerToNodePoint(e))
const forcePan = isMiddleMousePanning
drawEnd(pointerToNodePoint(e), forcePan)
if (e.button === 1) {
isMiddleMousePanning = false
}
}

canvas.onpointercancel = canvas.onpointerup
canvas.onpointercancel = (e) => {
if (readonly) {
return
}
e.preventDefault()
canvas.releasePointerCapture(e.pointerId)
const forcePan = isMiddleMousePanning
drawEnd(pointerToNodePoint(e), forcePan)
isMiddleMousePanning = false
}

canvas.onpointerenter = () => {
if (!readonly && draw.isDrawingTool()) {
Expand All @@ -472,20 +503,20 @@ export function drawing (
return makeMouseScaledPoint(scaled.x, scaled.y)
}

function drawStart (p: NodePoint): void {
function drawStart (p: NodePoint, forcePan: boolean): void {
const scaledPoint = rescaleWithCss(p)
draw.on = true
draw.points = []
prevPos = scaledPoint
if (draw.isDrawingTool()) {
if (!forcePan && draw.isDrawingTool()) {
draw.addPoint(scaledPoint)
}
}

function drawContinue (p: NodePoint): void {
function drawContinue (p: NodePoint, forcePan: boolean): void {
const scaledPoint = rescaleWithCss(p)

if (draw.isDrawingTool()) {
if (!forcePan && draw.isDrawingTool()) {
const cursorSize = draw.cursorWidth()

const canvasOffsetInParent = offsetInParent(node, canvas)
Expand All @@ -501,7 +532,7 @@ export function drawing (
}
}

if (draw.on && draw.tool === 'pan') {
if (draw.on && (draw.tool === 'pan' || forcePan)) {
requestAnimationFrame(() => {
draw.offset.x += scaledPoint.x - prevPos.x
draw.offset.y += scaledPoint.y - prevPos.y
Expand All @@ -513,22 +544,22 @@ export function drawing (
})
}

if (draw.on && draw.tool === 'text') {
if (draw.on && draw.tool === 'text' && !forcePan) {
prevPos = scaledPoint
}

if (props.pointerMoved !== undefined) {
if (props.pointerMoved !== undefined && !forcePan) {
props.pointerMoved(draw.mouseToCanvasPoint(scaledPoint))
}
}

function drawEnd (p: NodePoint): void {
function drawEnd (p: NodePoint, forcePan: boolean): void {
const scaledPoint = rescaleWithCss(p)
if (draw.on) {
if (draw.isDrawingTool()) {
if (!forcePan && draw.isDrawingTool()) {
draw.drawLine(scaledPoint, 'last-point', props.getCurrentTheme())
storeLineCommand()
} else if (draw.tool === 'pan') {
} else if (draw.tool === 'pan' || forcePan) {
props.panned?.(draw.offset)
} else if (draw.tool === 'text') {
if (liveTextBox !== undefined) {
Expand Down Expand Up @@ -1024,13 +1055,22 @@ export function drawing (
}
if (props.tool !== undefined) {
if (draw.tool !== props.tool) {
if (props.tool === 'pan') {
draw.usedBeforePanningTool = draw.tool
} else {
draw.usedBeforePanningTool = props.tool
}
draw.tool = props.tool
syncToolCursor = true
toolChanged = true
}
}
if (props.penColor !== undefined) {
if (draw.penColor !== props.penColor) {
if (draw.tool === 'pan' && draw.usedBeforePanningTool != null) {
draw.tool = draw.usedBeforePanningTool
toolChanged = true
}
draw.penColor = props.penColor
syncLiveTextBox = true
syncToolCursor = true
Expand Down Expand Up @@ -1084,6 +1124,9 @@ export function drawing (
}
}

if (toolChanged) {
props.toolChanged?.(draw.tool)
}
if (syncToolCursor) {
updateToolCursor()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import { Loading, Component, themeStore } from '@hcengineering/ui'
import { onMount, onDestroy } from 'svelte'
import { Array as YArray, Map as YMap, Doc as YDoc } from 'yjs'
import { get } from 'svelte/store'

export let boardId: string
export let document: YDoc
Expand Down Expand Up @@ -262,6 +261,7 @@
eraserWidth,
fontSize,
personCursorPos: personCursorCanvasPos,
enableMiddleMousePanning: true,
changingCmdId,
cmdAdded: (commandToAdd) => {
commandsProcessor.addCommand(commandToAdd)
Expand All @@ -288,6 +288,9 @@
},
personCursorMoved: (nodePos) => {
personCursorNodePos = nodePos
},
toolChanged: (newTool) => {
tool = newTool
}
}}
>
Expand Down
Loading