UNPKG

@uiw/react-signature

Version:

A signature board component for react.

104 lines 3.73 kB
import _extends from "@babel/runtime/helpers/extends"; import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose"; var _excluded = ["className", "prefixCls", "style", "readonly", "onPointer", "options", "children"]; import React, { useEffect, useRef, useId, forwardRef, useImperativeHandle } from 'react'; import { getBoundingClientRect, getClinetXY, useEvent } from "../utils.js"; import { useDispatch } from "../store.js"; import { useOptionDispatch } from "../options.js"; import { jsx as _jsx } from "react/jsx-runtime"; export var defaultStyle = { '--w-signature-background': '#fff', touchAction: 'none', position: 'relative', backgroundColor: 'var(--w-signature-background)' }; export var Signature = /*#__PURE__*/forwardRef((props, ref) => { var { className, prefixCls = 'w-signature', style, readonly = false, onPointer, children } = props, others = _objectWithoutPropertiesLoose(props, _excluded); var cls = [className, prefixCls].filter(Boolean).join(' '); var $canvas = useRef(null); var $path = useRef(); var pointsRef = useRef(); var pointCount = useRef(0); var pointId = useId(); var dispatch = useDispatch(); var dispatchOption = useOptionDispatch(); useImperativeHandle(ref, () => ({ canvas: $canvas.current, dispatch, clear: () => { var _$canvas$current, _$canvas$current2, _$canvas$current3; dispatch({}); var ctx = (_$canvas$current = $canvas.current) == null ? void 0 : _$canvas$current.getContext('2d'); ctx == null || ctx.clearRect(0, 0, ((_$canvas$current2 = $canvas.current) == null ? void 0 : _$canvas$current2.width) || 0, ((_$canvas$current3 = $canvas.current) == null ? void 0 : _$canvas$current3.height) || 0); } }), [$canvas.current, dispatch]); var handlePointerDown = useEvent(e => { if (readonly) return; pointCount.current += 1; var { offsetY, offsetX } = getBoundingClientRect($canvas.current); var clientX = e.clientX || e.nativeEvent.clientX; var clientY = e.clientY || e.nativeEvent.clientY; pointsRef.current = [[clientX - offsetX, clientY - offsetY]]; var pathElm = document.createElementNS('http://www.w3.org/2000/svg', 'path'); $path.current = pathElm; $canvas.current.appendChild(pathElm); dispatch({ [pointId + pointCount.current]: pointsRef.current }); }); var handlePointerMove = useEvent(e => { if ($path.current) { var { offsetY, offsetX } = getBoundingClientRect($canvas.current); var { clientX, clientY } = getClinetXY(e); pointsRef.current = [...pointsRef.current, [clientX - offsetX, clientY - offsetY]]; dispatch({ [pointId + pointCount.current]: pointsRef.current }); } }); var handlePointerUp = useEvent(() => { var result = pointsRef.current || []; onPointer && props.onPointer(result); $path.current = undefined; pointsRef.current = undefined; }); useEffect(() => { if ($canvas.current) { dispatchOption({ container: $canvas.current }); } if (readonly) return; document.addEventListener('pointermove', handlePointerMove); document.addEventListener('pointerup', handlePointerUp); return () => { if (readonly) return; document.removeEventListener('pointermove', handlePointerMove); document.removeEventListener('pointerup', handlePointerUp); }; }, []); return /*#__PURE__*/_jsx("canvas", _extends({}, others, { ref: $canvas, className: cls, onPointerDown: handlePointerDown, style: _extends({}, defaultStyle, style), children: children })); });