michaeldzjap / react-signature-pad-wrapper

A React wrapper for signature pad
MIT License
205 stars 27 forks source link

Adding event listeners #13

Closed canarc closed 4 years ago

canarc commented 4 years ago

FOA hello and thanks for this useful project. i want to add event listener on this canvas to take speed and acceleration data. is it possible that could you help me please?

michaeldzjap commented 4 years ago

I reckon you mean speed and acceleration of drawing with the mouse? That is a question which goes a little bit beyond this project. But the way I would approach it (note that I haven't actually tried this out); I would attach a debounced (so you are in control of the time between callback calls) "mousemove" event listener to the underlying canvas element in which I would compute the velocity. So something like:

import React, {PureComponent} from 'react';
import SignaturePad from 'react-signature-pad-wrapper';
import {debounce} from 'throttle-debounce';

class MyComponent extends PureComponent {

    static defaultProps = {
        debounceInterval = 150,
    }

    constructor(props) {
        super(props);

        this.state = {x1: null, y1: null};

        this._callMouseMoveHandler = debounce(
            this.props.debounceInterval,
            this.handleMouseMove.bind(this)
        );
    }

    componentDidMount() {
        if (this.signaturePad) {
            this.signaturePad.canvas.addEventListener('mousemove', this._callMouseMoveHandler);
        }
    }

    handleMouseMove(e) {
        const dt = this.props.debounceInterval;
        const {x1, y1} = this.state;

        if (x1 !== null && x2 !== null) {
            // Compute velocity and speed
            const vx = (e.clientX - this.state.x1) / dt;
            const vy = (e.clientY - this.state.y1) / dt;
            const s = Math.sqrt(vx * vx + vy * vy);
        }

        this.setState({x1: e.clientX, y1: e.clientY});
    }

    componentWillUnmount() {
        if (this.signaturePad) {
            this.signaturePad.canvas.removeEventListener('mousemove', this._callMouseMoveHandler);
        }
    }

    render() {
        return <SignaturePad ref={ref => this.signaturePad = ref} />;
    }

}

export default MyComponent;

Computing the acceleration would be pretty much the same procedure, but applied to vx and vy (i.e. you'd have to keep track of vx1 and vy1 in your state and do the same computations to get the acceleration).

canarc commented 4 years ago

Thank you so much.