【问题标题】:Best way to programmatically manipulate an hand-drawn line以编程方式操作手绘线的最佳方法
【发布时间】:2013-12-17 12:16:02
【问题描述】:

请注意,我没有数学或计算机图形学背景。

如果可能的话,我想知道以编程方式操作手绘线的最佳方法。

绘制动作必须在 html 页面中完成。 (可能无关紧要)

我坚持的方法:

  1. 在画布上画一条线(有上下的手绘线)-> 转换为位图-> 以某种方式在位图上解释线并操纵其形式(这可能吗?)

    李>
  2. 不是从位图解释,而是在绘图时有一种按钮来打开/关闭捕获,捕获后,生成某种我能够操作的数学函数并从中生成新的位图

【问题讨论】:

    标签: html canvas graphics bitmap 2d


    【解决方案1】:

    是的,你可以。

    这并不难,但是有很多小的编码方面需要学习。

    如果您处于“绘图”模式,您将收集用户单击的鼠标点并从所有这些点画一条线。

    如果您处于“编辑”模式,您可以让用户将其中一个收集的点拖动到新坐标,并从所有已编辑的点组成一条线。

    以下是供您查看和学习的起始代码以及 Fiddle:http://jsfiddle.net/m1erickson/J5PrN/

    <!doctype html>
    <html>
    <head>
    <link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
    <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
    
    <style>
        body{ background-color: ivory; }
        #canvas{border:1px solid red;}
    </style>
    
    <script>
    $(function(){
    
        var canvas=document.getElementById("canvas");
        var ctx=canvas.getContext("2d");
        ctx.lineCap = "round";
        ctx.lineJoin = "round";
        ctx.lineWidth=3;
    
        var canvasOffset=$("#canvas").offset();
        var offsetX=canvasOffset.left;
        var offsetY=canvasOffset.top;
        var isDown=false;
        var startX;
        var startY;
    
        var points=[];
        var selected=-1;
        var mode="draw";
    
        function draw(){
            ctx.clearRect(0,0,canvas.width,canvas.height);
            ctx.beginPath();
            ctx.moveTo(points[0].x,points[0].y);
            for(var i=1;i<points.length;i++){
                ctx.lineTo(points[i].x,points[i].y);
            }
            ctx.stroke();
            if(mode=="edit"){
                for(var i=0;i<points.length;i++){
                    ctx.beginPath();
                    ctx.arc(points[i].x,points[i].y,10,0,Math.PI*2);
                    ctx.closePath();
                    ctx.fill();
                }
            }
        }
    
        function handleMouseDown(e){
          startX=parseInt(e.clientX-offsetX);
          startY=parseInt(e.clientY-offsetY);
    
          if(mode=="draw"){
              points.push({x:startX,y:startY});
              draw();
          }else if(mode=="edit"){
              for(var i=0;i<points.length;i++){
                  var pt=points[i];
                  var dx=startX-pt.x;
                  var dy=startY-pt.y;
                  if(dx*dx+dy*dy<100){
                      selected=i;
                      return;
                  }
              }
          }
    
        }
    
        function handleMouseUp(e){
            selected=-1;
        }
    
        function handleMouseOut(e){
            selected=-1;
        }
    
        function handleMouseMove(e){
          if(selected<0){return;}
    
          mouseX=parseInt(e.clientX-offsetX);
          mouseY=parseInt(e.clientY-offsetY);
    
          // Put your mousemove stuff here
          if(selected<0){return;}
          var dx=mouseX-startX;
          var dy=mouseY-startY;
          startX=mouseX;
          startY=mouseY;
          var pt=points[selected];
          points[selected]={x:pt.x+dx,y:pt.y+dy};
          draw();
        }
    
        $("#canvas").mousedown(function(e){handleMouseDown(e);});
        $("#canvas").mousemove(function(e){handleMouseMove(e);});
        $("#canvas").mouseup(function(e){handleMouseUp(e);});
        $("#canvas").mouseout(function(e){handleMouseOut(e);});
    
        $("#draw").click(function(){ 
            mode="draw"; 
            draw(); 
            $instructions.text("Click points to draw a line");
        });
        $("#edit").click(function(){ 
            mode="edit"; 
            draw(); 
            $instructions.text("Drag points to move the line");
        });
        $instructions=$("#instructions");
    
    
    }); // end $(function(){});
    </script>
    
    </head>
    
    <body>
        <button id="draw">Add to Line</button>
        <button id="edit">Change Line</button><br>
        <p id="instructions">Click points to draw a line</p>
        <canvas id="canvas" width=300 height=300></canvas>
    </body>
    </html>
    

    【讨论】:

      【解决方案2】:

      我不会说 HTML,但在我见过的大多数应用程序中 (such as this one),手绘线被分成小的直线段。这是因为传感系统(触摸或鼠标)为您的应用程序提供了(有点)连续的点流;它没有给出实际的线路。然后使用各个段来完成应用程序的目标。

      在画线的情况下,当画线时,应用程序会获取点并对它们进行平滑处理(三次样条、最小二乘多项式拟合、b 样条等),然后将平滑的线绘制到屏幕上颜色和样式(钢笔、铅笔、粉笔等)。这可以让用户立即反馈他们的手在哪里移动等。

      在手势控制的情况下,可能会绘制一些覆盖线来给用户反馈,但对这些片段进行不同的处理以确定手势(这可能非常复杂)。

      将行缓存为一系列手势为您提供了撤消/重做的选项。您还可以将绘图存储为一系列手势,而不是固定的位图。

      这有帮助吗?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-08-08
        • 1970-01-01
        • 2016-07-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-18
        相关资源
        最近更新 更多