利用canvas实现在线签名功能

该代码示例展示了如何在HTML5canvas上处理鼠标和触摸事件,允许用户在画布上绘制并清除图形。当鼠标或手指移动时,它会创建线条,按下和松开则开始和结束绘画。同时,提供了清除画布和提交画布数据到URL的功能。
摘要由CSDN通过智能技术生成
<!DOCTYPE html>
<html>
  <body>
    <canvas style="border: 1px solid black; margin: 10px 0 10px 0; cursor: pointer" id="canvas" width="800" height="600"></canvas>
    <div>
      <button onclick="clearCanvas()">Clear</button>
      <button onclick="submitCanvas()">submit</button>
    </div>
  </body>
  <script>
    var arr_touches = [];

    var canvas;

    var ctx;

    var down = false; //mouse is pressed

    var color = 'black'; //default drawing color

    var width = 5; // drawing width

    //calling window.onload to make sure the HTML is loaded

    window.onload = function () {
      canvas = document.getElementById('canvas');

      ctx = canvas.getContext('2d');

      ctx.lineWidth = width;

      //handling mouse click and move events

      canvas.addEventListener('mousemove', handleMove);

      canvas.addEventListener('mousedown', handleDown);

      canvas.addEventListener('mouseup', handleUp);

      //handling mobile touch events

      canvas.addEventListener('touchstart', handleStart, false);

      canvas.addEventListener('touchend', handleEnd, false);

      canvas.addEventListener('touchcancel', handleCancel, false);

      canvas.addEventListener('touchleave', handleEnd, false);

      canvas.addEventListener('touchmove', handleTouchMove, false);
    };

    function handleMove(e) {
      xPos = e.clientX - canvas.offsetLeft;

      yPos = e.clientY - canvas.offsetTop;

      if (down == true) {
        ctx.lineTo(xPos, yPos); //create a line from old point to new one

        ctx.strokeStyle = color;

        ctx.stroke();
      }
    }

    function handleDown() {
      down = true;

      ctx.beginPath();

      ctx.moveTo(xPos, yPos);
    }

    function handleUp() {
      down = false;
    }

    function handleStart(evt) {
      var touches = evt.changedTouches;

      for (var i = 0; i < touches.length; i++) {
        if (isValidTouch(touches[i])) {
          evt.preventDefault();

          arr_touches.push(copyTouch(touches[i]));

          ctx.beginPath();

          ctx.fillStyle = color;

          ctx.fill();
        }
      }
    }

    function handleTouchMove(evt) {
      var touches = evt.changedTouches;

      var offset = findPos(canvas);

      for (var i = 0; i < touches.length; i++) {
        if (isValidTouch(touches[i])) {
          evt.preventDefault();

          var idx = ongoingTouchIndexById(touches[i].identifier);

          if (idx >= 0) {
            ctx.beginPath();

            ctx.moveTo(arr_touches[idx].clientX - offset.x, arr_touches[idx].clientY - offset.y);

            ctx.lineTo(touches[i].clientX - offset.x, touches[i].clientY - offset.y);

            ctx.strokeStyle = color;

            ctx.stroke();

            arr_touches.splice(idx, 1, copyTouch(touches[i]));
          }
        }
      }
    }

    function handleEnd(evt) {
      var touches = evt.changedTouches;

      var offset = findPos(canvas);

      for (var i = 0; i < touches.length; i++) {
        if (isValidTouch(touches[i])) {
          evt.preventDefault();

          var idx = ongoingTouchIndexById(touches[i].identifier);

          if (idx >= 0) {
            ctx.lineWidth = 4;

            ctx.fillStyle = color;

            ctx.beginPath();

            ctx.moveTo(arr_touches[idx].clientX - offset.x, arr_touches[idx].clientY - offset.y);

            ctx.lineTo(touches[i].clientX - offset.x, touches[i].clientY - offset.y);

            arr_touches.splice(i, 1);
          }
        }
      }
    }

    function handleCancel(evt) {
      evt.preventDefault();

      var touches = evt.changedTouches;

      for (var i = 0; i < touches.length; i++) {
        arr_touches.splice(i, 1);
      }
    }

    function copyTouch(touch) {
      return { identifier: touch.identifier, clientX: touch.clientX, clientY: touch.clientY };
    }

    function ongoingTouchIndexById(idToFind) {
      for (var i = 0; i < arr_touches.length; i++) {
        var id = arr_touches[i].identifier;

        if (id == idToFind) {
          return i;
        }
      }

      return -1;
    }

    function clearCanvas() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
    }

    function submitCanvas() {
      let canvas = document.getElementById('canvas');
      let url = canvas.toDataURL();
      console.log('url', url);
    }

    function isValidTouch(touch) {
      var curleft = 0,
        curtop = 0;

      var offset = 0;

      if (canvas.offsetParent) {
        do {
          curleft += canvas.offsetLeft;

          curtop += canvas.offsetTop;
        } while (touch == canvas.offsetParent);

        offset = { x: curleft - document.body.scrollLeft, y: curtop - document.body.scrollTop };
      }

      if (
        touch.clientX - offset.x > 0 &&
        touch.clientX - offset.x < parseFloat(canvas.width) &&
        touch.clientY - offset.y > 0 &&
        touch.clientY - offset.y < parseFloat(canvas.height)
      ) {
        return true;
      } else {
        return false;
      }
    }

    function findPos(obj) {
      var curleft = 0,
        curtop = 0;

      if (obj.offsetParent) {
        do {
          curleft += obj.offsetLeft;

          curtop += obj.offsetTop;
        } while (obj == obj.offsetParent);

        return { x: curleft - document.body.scrollLeft, y: curtop - document.body.scrollTop };
      }
    }
  </script>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值