import React, { memo, useState, useEffect, useCallback } from 'react';
import styles from './index.less'
export default memo(() => {
const [image, setImage] = useState("")
const [mousePressed, setMousePressed] = useState(false)
const [c, setC] = useState("")
const [ctx, setCtx] = useState("")
useEffect(() => {
// 监听touchstart事件,touchmove事件,touchend事件等事件
c && InitThis()
}, [c, mousePressed])
const InitThis = useCallback(() => {
let beginX
let beginY
// 触摸屏
c.addEventListener(
"touchstart",
function (event) {
if (event.targetTouches.length == 1) {
event.preventDefault(); // 阻止浏览器默认事件,重要
var touch = event.targetTouches[0];
setMousePressed(true)
beginX = touch.pageX - c.offsetLeft;
beginY = touch.pageY - c.offsetTop;
}
},
false
);
c.addEventListener(
"touchmove",
function (event) {
if (event.targetTouches.length == 1) {
event.preventDefault(); // 阻止浏览器默认事件,重要
var touch = event.targetTouches[0];
if (mousePressed) {
let stopX = touch.pageX - c.offsetLeft;
let stopY = touch.pageY - c.offsetTop;
Draw(
stopX,
stopY,
beginX,
beginY,
true
);
beginX = stopX; // 这一步很关键,需要不断更新起点,否则画出来的是射线簇
beginY = stopY;
}
}
},
false
);
c.addEventListener(
"touchend",
function (event) {
if (event.targetTouches.length == 1) {
event.preventDefault(); // 阻止浏览器默认事件,防止手写的时候拖动屏幕,重要
setMousePressed(false)
}
},
false
);
}, [ctx, mousePressed])
const Draw = useCallback((x, y, beginX, beginY, isDown) => {
if (isDown) {
ctx.beginPath();
ctx.strokeStyle = "#000"; // 颜色
ctx.lineWidth = 3; // 线宽
ctx.lineJoin = "round";
ctx.lineMax = 10; // 设置画笔最大线宽
ctx.lineMin = 3; // 设置画笔最小线宽
ctx.linePressure = 1.2; // 设置画笔笔触压力
ctx.smoothness = 30; // 设置画笔笔触大小变化的平滑度
ctx.moveTo(beginX, beginY);
ctx.lineTo(x, y);
ctx.closePath();
ctx.stroke();
}
}, [ctx, c])
const checkEmpty = useCallback(() => {
if (isCanvasBlank(c)) {
alert("请在签名区域签名后再次确认");
return;
} else {
var image = c.toDataURL("image/png"); // 得到生成后的签名base64位 url 地址
console.log(image); // 打印图片base64 url
}
}, [c])
// 验证canvas画布是否为空函数
const isCanvasBlank = (canvas) => {
var blank = document.createElement("canvas"); // 系统获取一个空canvas对象
blank.width = canvas.width;
blank.height = canvas.height;
blank.getContext('2d').clearRect(0, 0, canvas.width, canvas.height);
return canvas.toDataURL() === blank.toDataURL(); // 比较值相等则为空
}
const canvasRef = useCallback(node => {
if (node) {
setC(node)
setCtx(node.getContext("2d"))
var signWrap = document.getElementById("signWrap");
node.width = signWrap.clientWidth; // 设置宽度
node.height = signWrap.clientHeight; // 设置高度
}
}, [c, ctx]);
// 清空画板
const clearArea = useCallback(() => {
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
}, [ctx])
// 提交签名
const saveSign = () => {
checkEmpty(); // 调用 表单非空验证
}
return (
<div className={[styles.page, styles.signPage].join(" ")}>
<div className={styles.content}>
<div className={styles.signWrap} id="signWrap">
<canvas id="myCanvas" ref={canvasRef} width="100%" height="100%"></canvas>
</div>
</div>
<div className={styles.conBtn}>
<span className={[styles.stagingBtn, styles.size14].join(" ")} onClick={clearArea}>清除签名</span>
<span className={[styles.submitBtn, styles.size14].join(" ")} onClick={saveSign} > 确认签名</span >
</div >
</div >
)
})
.page {
width: 100%;
.content {
width: 100%;
height: 3rem;
// background: url(../assets/img/photo_qmq.png) no-repeat;
background-size: 100% 100%;
background-position: center center;
.signWrap {
width: 100%;
height: 100%;
}
}
.conBtn {
width: 100%;
display: flex;
align-content: center;
justify-content: space-between;
opacity: 0.75;
span {
font-size: 0.14rem;
width: 100%;
height: 0.48rem;
display: flex;
align-items: center;
justify-content: center;
}
.stagingBtn {
color: #4154ff;
background: #fff;
}
.submitBtn {
color: #fff;
background: #4154ff;
}
}
}