Skip to content

On pointer move is recording coordinates too frequent, adding a throttling to optimise #163

Open
@Louis116

Description

@Louis116

Is your feature request related to a problem? Please describe.

  • The current interval of recording the coordinates on pointer move is around 1ms, depending on how fast could the browser run
    (please correct me if the time is not correct)
  • which cause a problem of :

  1. recording too much , marking unnescecery coordinates
  2. the smoothing may not be working as much as expected due to the point is too close, the smoothing effects is reduced
  3. possible performance issue

Describe the solution you'd like
- i have tried to add a interval inside the handlePointerMove function of <Canvas/>

  • which tested throttling of around 10ms to 20ms works the best
  • which could reduce the coordinates point recorded and make the line smoother

Updated on 7 Aug

  • since the handleOnPointerMove handler is still triggering every ms
  • Tried another approach of storing reference of an interval for move event throttle
    const currentPointerDownEventInterval = React.useRef<NodeJS.Timeout | null>(
        null,
    )
    const handlePointerUp = useCallback(
        (event: React.PointerEvent<HTMLDivElement> | PointerEvent): void => {
            if (event.pointerType === 'mouse' && event.button !== 0) {
                return
            }

            // Allow only chosen pointer type
            if (
                allowOnlyPointerType !== 'all' &&
                event.pointerType !== allowOnlyPointerType
            ) {
                return
            }

            onPointerUp(event)
            if (currentPointerDownEventInterval.current !== null) {
                clearInterval(currentPointerDownEventInterval.current)
            }
        },
        [allowOnlyPointerType, onPointerUp],
    )
    const ON_POINTER_MOVE_THROTTLE_MS = 20
     const handlePointerMove = useCallback(
        (event: React.PointerEvent<HTMLDivElement>): void => {
            if (!isDrawing) {
                return
            }

            // Allow only chosen pointer type
            if (
                allowOnlyPointerType !== 'all' &&
                event.pointerType !== allowOnlyPointerType
            ) {
                return
            }

            if (currentPointerDownEventInterval.current !== null) {
                return
            }

            function handleOnPointerMove() {
                const point = getCoordinates(event)
                onPointerMove(point)
                currentPointerDownEventInterval.current = null
            }
            const interval = setTimeout(
                handleOnPointerMove,
                ON_POINTER_MOVE_THROTTLE_MS,
            )
            currentPointerDownEventInterval.current = interval
        },
        [allowOnlyPointerType, getCoordinates, isDrawing, onPointerMove],
    )

below is a result comparsion (please forgive my poor hand writing)

without throttling with throttling of 20ms
image image

Draw Back
however, this solution have some draw back:
the throtting ms is kind of limited if you are aiming for the best result.
when drawing too fast, the path will 'wiggle', especially when the throttling is above 50 ms, i am still studying the root
cause, would love to have some advise if anyone have any insight, but i think this draw back is not critial
1. the path is not going to change too much when wiggling (if throttling is under 20ms)
2. personally think it look like a fun visual effect of drawing on the board

  • draw back is gone with updated approach

Describe alternatives you've considered

  • tried to tune the the smoothing factor inside <Path/>, but result is not as good as expected due to the coordinates are too close

Additional context

  • this throttling ms could be a configable props, but due to the 'wiggle' issue, maybe a fixed number just like the smoothing inside <Path/> is also considerable
  • 'wiggle' not exist on new approach

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions