@nutui/nutui-react
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
127 lines (126 loc) • 5.22 kB
JavaScript
import { _ as __rest } from "./tslib.es6.js";
import React__default, { useRef, useState, useEffect, useImperativeHandle } from "react";
import { useConfig } from "./ConfigProvider.js";
import { C as ComponentDefaults } from "./typings.js";
import { c as canUseDom } from "./can-use-dom.js";
const defaultProps = Object.assign(Object.assign({}, ComponentDefaults), { type: "png", lineWidth: 2, strokeStyle: "#1a1a1a", unsupported: "" });
const InternalSignature = (props, ref) => {
const { locale } = useConfig();
const _a = Object.assign(Object.assign({}, defaultProps), props), { type, lineWidth, strokeStyle, unsupported, className, style, onConfirm, onClear } = _a, rest = __rest(_a, ["type", "lineWidth", "strokeStyle", "unsupported", "className", "style", "onConfirm", "onClear"]);
const classPrefix = `nut-signature`;
const canvasRef = useRef(null);
const wrapRef = useRef(null);
const [canvasHeight, setCanvasHeight] = useState(0);
const [canvasWidth, setCanvasWidth] = useState(0);
const ctx = useRef(null);
const checkCanvas = () => {
const elem = document.createElement("canvas");
return !!(elem.getContext && elem.getContext("2d"));
};
const [isCanvasSupported, setIsCanvasSupported] = useState(false);
const isSignedRef = useRef(false);
const isSupportTouch = canUseDom ? "ontouchstart" in window : false;
const events = isSupportTouch ? ["touchstart", "touchmove", "touchend", "touchleave"] : ["mousedown", "mousemove", "mouseup", "mouseleave"];
useEffect(() => {
setIsCanvasSupported(checkCanvas);
}, []);
useEffect(() => {
if (isCanvasSupported && canvasRef.current && wrapRef.current) {
ctx.current = canvasRef.current.getContext("2d");
setCanvasWidth(wrapRef.current.offsetWidth);
setCanvasHeight(wrapRef.current.offsetHeight);
addEvent();
}
}, [isCanvasSupported]);
const startEventHandler = (event) => {
event.preventDefault();
isSignedRef.current = true;
if (ctx.current && canvasRef.current) {
ctx.current.beginPath();
ctx.current.lineWidth = lineWidth;
ctx.current.strokeStyle = strokeStyle;
canvasRef.current.addEventListener(events[1], moveEventHandler, false);
canvasRef.current.addEventListener(events[2], endEventHandler, false);
canvasRef.current.addEventListener(events[3], leaveEventHandler, false);
}
};
const addEvent = () => {
if (canvasRef.current) {
canvasRef.current.addEventListener(events[0], startEventHandler, false);
}
};
const moveEventHandler = (event) => {
event.preventDefault();
const evt = isSupportTouch ? event.touches[0] : event;
if (canvasRef.current && ctx.current) {
const coverPos = canvasRef.current.getBoundingClientRect();
const mouseX = evt.clientX - coverPos.left;
const mouseY = evt.clientY - coverPos.top;
ctx.current.lineTo(mouseX, mouseY);
ctx.current.stroke();
}
};
const endEventHandler = (event) => {
event.preventDefault();
if (canvasRef.current) {
canvasRef.current.removeEventListener(events[1], moveEventHandler, false);
canvasRef.current.removeEventListener(events[2], endEventHandler, false);
}
};
const leaveEventHandler = (event) => {
event.preventDefault();
if (canvasRef.current) {
canvasRef.current.removeEventListener(events[1], moveEventHandler, false);
canvasRef.current.removeEventListener(events[2], endEventHandler, false);
}
};
const handleClearBtn = () => {
isSignedRef.current = false;
if (canvasRef.current && ctx.current) {
canvasRef.current.addEventListener(events[2], endEventHandler, false);
ctx.current.clearRect(0, 0, canvasWidth, canvasHeight);
ctx.current.closePath();
}
onClear && onClear();
};
const onSave = (canvas) => {
let dataurl = "";
if (!isSignedRef.current) {
onConfirm && onConfirm(canvas, dataurl, isSignedRef.current);
return;
}
switch (type) {
case "png":
dataurl = canvas.toDataURL("image/png");
break;
case "jpg":
dataurl = canvas.toDataURL("image/jpeg", 0.8);
break;
default:
dataurl = canvas.toDataURL("image/png");
}
onConfirm && onConfirm(canvas, dataurl, isSignedRef.current);
};
useImperativeHandle(ref, () => ({
confirm: () => {
onSave(canvasRef.current);
},
clear: () => {
handleClearBtn();
}
}));
return React__default.createElement(
"div",
Object.assign({ className: `${classPrefix} ${className}`, style }, rest),
React__default.createElement(
"div",
{ className: `${classPrefix}-inner`, ref: wrapRef },
React__default.createElement(React__default.Fragment, null, isCanvasSupported ? React__default.createElement("canvas", { ref: canvasRef, height: canvasHeight, width: canvasWidth }) : unsupported ? React__default.createElement(React__default.Fragment, null, unsupported) : React__default.createElement("p", { className: `${classPrefix}-unsupport` }, locale.signature.unsupported))
)
);
};
const Signature = React__default.forwardRef(InternalSignature);
Signature.displayName = "NutSignature";
export {
Signature as default
};