canvas-学写字

一、逻辑思维

  1. 初始化的时候加入画布,先画田字格,方法很简单,线条画
  2. 四种操作,点击(onmousedown),移开(onmouseup),移走(onmouseout),移动(onmousemove)
  3. 点击的时候进行操作:记录点击区域坐标,可以画
  4. 移开,移走的时候进行操作:不可以画
  5. 移动:记录位置变化,记录速度改变线宽,连接线条,上一次位置,上一次时间,上一次线宽不断更替
  6. 速度算法,自由发挥

二、代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>writeFont</title>
</head>

<body>
  <canvas id="canvas" width="500" height="500"></canvas>

  <script>
    window.onload = function () {
      var canvas = document.getElementById("canvas");
      var context = canvas.getContext('2d');
      var color = 'green';

      drawGrid();

      // 画田字格
      function drawGrid() {
        context.save();
        context.strokeStyle = "rgb(230,11,9)";
        context.beginPath();
        context.moveTo(3, 3);
        context.lineTo(canvas.width - 3, 3);
        context.lineTo(canvas.width - 3, canvas.height - 3);
        context.lineTo(3, canvas.height - 3);
        context.closePath();

        context.lineWidth = 6;
        context.stroke();

        context.beginPath();
        context.moveTo(0, 0);
        context.lineTo(canvas.width, canvas.height);

        context.moveTo(canvas.width, 0);
        context.lineTo(0, canvas.height);

        context.moveTo(canvas.width / 2, 0);
        context.lineTo(canvas.width / 2, canvas.height);

        context.moveTo(0, canvas.width / 2);
        context.lineTo(canvas.width, canvas.height / 2);
        context.lineWidth = 1;
        context.stroke();
        context.restore();
      }

      var isMouseDown = false; //鼠标是否按下
      var lastLoc = { x: null, y: null };//鼠标上一次所在位置
      var lastTimestamp = 0;//时间戳
      var lastLineWidth = -1;//上一次线条宽度
      //鼠标按下
      canvas.onmousedown = function (e) {
        e.preventDefault();
        initLoc(e.clientX, e.clientY);
        isMouseDown = true;
      }
      //鼠标起来
      canvas.onmouseup = function (e) {
        e.preventDefault();
        isMouseDown = false;
      }
      //鼠标离开
      canvas.onmouseout = function (e) {
        e.preventDefault();
        isMouseDown = false;
      }
      //鼠标移动
      canvas.onmousemove = function (e) {
        e.preventDefault();
        if (isMouseDown) {
          //draw
          var curLoc = windowToCanvas(e.clientX, e.clientY);//获得当前坐标
          var curTimestamp = new Date().getTime();//当前时间
          var s = calcDistance(curLoc, lastLoc);//获得运笔距离
          var t = curTimestamp - lastTimestamp;//运笔时间
          var lineWidth = calcLineWidth(t, s);

          context.lineWidth = lineWidth;

          context.beginPath();
          context.moveTo(lastLoc.x, lastLoc.y);
          context.lineTo(curLoc.x, curLoc.y);

          context.strokeStyle = color;
          context.lineCap = "round"
          context.lineJoin = "round"
          context.stroke();

          lastLoc = curLoc;
          lastLineWidth = lineWidth;
          lastTimestamp = curTimestamp;
        }

      }

      //获得canvas坐标
      function windowToCanvas(x, y) {
        var bbox = canvas.getBoundingClientRect();
        return { x: Math.round(x - bbox.left), y: Math.round(y - bbox.top) };
        if(!lastLoc.x){
          lastLoc = { x: Math.round(x - bbox.left), y: Math.round(y - bbox.top) };
        }
      }
      //初始化上一次loc坐标
      function initLoc(x, y) {
        var bbox = canvas.getBoundingClientRect();
        lastLoc = { x: Math.round(x - bbox.left), y: Math.round(y - bbox.top) };
      }
      //求两点之间距离
      function calcDistance(loc1, loc2) {
        return Math.sqrt((loc1.x - loc2.x) * (loc1.x - loc2.x) + (loc1.y - loc2.y) * (loc1.y - loc2.y));
      }
      //求速度
      function calcLineWidth(t, s) {
        var v = s / t;
        var resultLineWidth;
        if (v <= 0.1) {
          resultLineWidth = 30;
        } else if (v >= 10) {
          resultLineWidth = 1;
        } else {
          resultLineWidth = 30 - (v - 0.1) / (10 - 0.1) * (30 - 1);
        }
        if (lastLineWidth == -1) {
          return resultLineWidth;
        }
        return lastLineWidth * 2 / 3 + resultLineWidth * 1 / 3;
      }
    }
  </script>
</body>

</html>

 

posted @ 2019-06-05 11:27  IT-蓝童鞋  阅读(220)  评论(0编辑  收藏  举报