H5实现签名(react)

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;
    }
  }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值