zoukankan      html  css  js  c++  java
  • 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>
    
  • 相关阅读:
    Attach Files to Objects 将文件附加到对象
    Provide Several View Variants for End-Users 为最终用户提供多个视图变体
    Audit Object Changes 审核对象更改
    Toggle the WinForms Ribbon Interface 切换 WinForms 功能区界面
    Change Style of Navigation Items 更改导航项的样式
    Apply Grouping to List View Data 将分组应用于列表视图数据
    Choose the WinForms UI Type 选择 WinForms UI 类型
    Filter List Views 筛选器列表视图
    Make a List View Editable 使列表视图可编辑
    Add a Preview to a List View将预览添加到列表视图
  • 原文地址:https://www.cnblogs.com/it-cuiyi/p/10978602.html
Copyright © 2011-2022 走看看