• react使用canvas手写签名优化


    优化点

    1、当顶部有其他元素或组件时,画板笔画起笔不在落笔位置,如添加backHome组件
    2、更改清除画图时,起笔长度变长问题

    BackHome.js

    import React, {useImperativeHandle} from 'react'
    import { useHistory } from 'react-router-dom'
    import { useLocation } from 'react-router-dom'
    import { Button, Divider } from 'antd'
    
    // 使用forwardRef 可以在父组件中获取到ref
    const BackHome = React.forwardRef((props, ref) => {
      useImperativeHandle(ref, () => ({
        ref: ref.current
      }));
      const location = useLocation();
      const history = useHistory();
      const toHome = () => {
        history.push('/')
      }
      let name = (location.state && location.state.name) || location.pathname.slice(1, location.pathname.length)
      return (
        <div ref={ref}>
          <Button onClick={toHome}>返回首页</Button>
          <div style={{'padding': '1px 0'}}>
            <Divider orientation="center">
              当前:{name}
            </Divider>
          </div>
          
        </div>
      )
    })
    
    export default BackHome;

    Autograph.js

    import React, { Component } from 'react'
    import { Button, Divider, Row, Col } from 'antd'
    import BackHome from '../component/BackHome'
    class Autograph extends Component {
      state = {
        base: '' // base64形式的图片
      }
      ref=React.createRef();
      componentDidMount () {
        this.initCanvasEvent()
      }
      initCanvas () {
        // 自适应设置画布大小
        const vWidth = document.body.clientWidth
        const can = document.getElementById('canvas')
        can.width = vWidth
        can.height = vWidth
        // 画布准备
        const context = can.getContext('2d')
        // 添加背景色
        context.fillStyle = '#ccc'
        context.fillRect(0, 0, can.width, can.height)
        // 笔尖设置
        context.strokeStyle = '#000' // 笔尖颜色
        context.lineWidth = 6 // 笔尖粗度
        return {
          can,
          context
        }
      }
      initCanvasEvent () {
        // 获取canvas 及 context
        const { can, context } = this.initCanvas()
        // 顶部组件的高,解决笔记不在落笔的位置
        // console.log(this.ref.current.ref.clientHeight)
        const refHeight = this.ref.current.ref && this.ref.current.ref.clientHeight
        // 监听触屏事件
        can.addEventListener('touchstart', (e) => {
          context.beginPath()
          context.moveTo(e.touches[0].pageX, e.touches[0].pageY - refHeight)
        })
        can.addEventListener('touchmove', (e) => {
          e.preventDefault(); // 阻止页面拖动,如部分移动端,上下左右滑动手势,等
          context.lineTo(e.touches[0].pageX, e.touches[0].pageY - refHeight)
          context.stroke()
        })
        can.addEventListener('touchend', () => {
          context.closePath()
        })
      }
      blankCanvas () {
        const blank = document.createElement('canvas')
        const canImg = document.getElementById('canvas')
        blank.width = canImg.width
        blank.height = canImg.height
        // 为使空画布与现有画图相同 (可根据实际需要修改)
        const context = blank.getContext('2d')
        context.fillStyle = '#ccc'
        context.fillRect(0, 0, blank.width, blank.height)
        // 为true 则为空画图
        // console.log(canImg.toDataURL() === blank.toDataURL());
        return canImg.toDataURL() === blank.toDataURL()
      }
      getCanvasImg () {
        const isFull = this.blankCanvas()
        if (isFull) {
          // 根据项目ui组件自行更改设置
          alert('请签名')
          return
        }
        // 获取到base64代码
        // console.log(document.querySelector('canvas').toDataURL());
        this.setState({
          base: document.querySelector('canvas').toDataURL()
        })
      }
      clearCanvas () {
        // canvas每当高度或宽度被重设时,画布内容就会被清空,所以会导致之前画的圆都被删除,所以重新抽离出 initCanvas ,与事件分开
        this.initCanvas()
      }
      render () {
        return (
          <div>
            <BackHome ref={this.ref} />
            <canvas id='canvas' disable-scroll="true"></canvas>
            <Divider orientation="center">手写签名</Divider>
            <Row justify="space-around" align="middle">
              <Col>
                <Button onClick={this.getCanvasImg.bind(this)}>提交签名</Button>
              </Col>
              <Col>
                <Button onClick={this.clearCanvas.bind(this )}>清除签名</Button>
              </Col>
            </Row>
            <div style={{'wordBreak': 'break-all'}}>
              base64图片: <br/> {this.state.base}
            </div>
          </div>
        )
      }
    }
    export default Autograph
    
    /*
      https://www.w3school.com.cn/tags/html_ref_canvas.asp
      https://blog.csdn.net/Luckyzhoufangbing/article/details/87784843
      https://blog.csdn.net/weixin_30471561/article/details/97082558
    */ 
  • 相关阅读:
    从Prism中学习设计模式之Event Aggregator 模式
    Apache的HttpClient调用Https忽略证书校验
    SaltStack安装及API开启
    Java连接WebSocket服务忽略证书校验
    SpringBoot实现WebSocket服务
    MySQL主从复制搭建
    Matlab基础知识(持续更新中)
    FIFO基础知识
    图像常识知识
    VC调试记录(持续更新中)
  • 原文地址:https://www.cnblogs.com/-roc/p/14566487.html
Copyright © 2020-2023  润新知