Html5 canvas 生成的图形提供了意外的输出

Html5 canvas 生成的图形提供了意外的输出,html5-canvas,konvajs,konva,Html5 Canvas,Konvajs,Konva,我正在尝试根据鼠标事件生成一个图形,我注意到一些有趣的渲染行为,我无法解释为什么会这样。下面是一个jsbin,它显示了这个示例: Konva免费绘图演示 身体{ 保证金:0; 填充:0; 溢出:隐藏; 背景色:#f0; } 工具: 刷子 橡皮擦 变量宽度=window.innerWidth; 变量高度=window.innerHeight-25; //首先,我们需要Konva的核心产品:舞台和舞台 var阶段=新Konva.阶段({ 容器:'容器', 宽度:宽度, 高度:高度 }); var

我正在尝试根据鼠标事件生成一个图形,我注意到一些有趣的渲染行为,我无法解释为什么会这样。下面是一个jsbin,它显示了这个示例:


Konva免费绘图演示
身体{
保证金:0;
填充:0;
溢出:隐藏;
背景色:#f0;
}
工具:
刷子
橡皮擦
变量宽度=window.innerWidth;
变量高度=window.innerHeight-25;
//首先,我们需要Konva的核心产品:舞台和舞台
var阶段=新Konva.阶段({
容器:'容器',
宽度:宽度,
高度:高度
});
var layer=新Konva.layer();
阶段。添加(层);
var isPaint=false;
变量模式='刷';
var lastLine;
stage.on('mousedown touchstart',函数(e){
isPaint=true;
var pos=e.pos;
lastLine=新Konva.Line({
笔划:“#df4b26”,
冲程宽度:5,
GlobalComposite操作:
模式=='brush'?'source over':'destination out',
点数:[位置x,位置y]
});
图层。添加(最后一行);
});
stage.on('mouseup touchend',function(){
isPaint=false;
});
//和核心功能-绘图
stage.on('mousemove touchmove',函数(e){
如果(!isPaint){
返回;
}
const pos=e.pos;
var newPoints=lastLine.points().concat([pos.x,pos.y]);
lastLine.points(新点);
layer.batchDraw();
});
var select=document.getElementById('tool');
select.addEventListener('change',function()){
模式=选择值;
});
常数线=[{
“et”:“md”,
“x”:109,
“y”:94
}, {
“et”:“mm”,
“x”:110,
“y”:98
}, {
“et”:“mm”,
“x”:110,
“y”:103
}, {
“et”:“mm”,
“x”:110,
“y”:111
}, {
“et”:“mm”,
“x”:110,
“y”:116
}, {
“et”:“mm”,
“x”:110,
“y”:123
}, {
“et”:“mm”,
“x”:110,
“y”:129
}, {
“et”:“mm”,
“x”:110,
“y”:135
}, {
“et”:“mm”,
“x”:110,
“y”:141
}, {
“et”:“mm”,
“x”:110,
“y”:143
}, {
“et”:“mm”,
“x”:110,
“y”:147
}, {
“et”:“mm”,
“x”:110,
“y”:150
}, {
“et”:“mm”,
“x”:111,
“y”:152
}, {
“et”:“mm”,
“x”:114,
“y”:155
}, {
“et”:“mm”,
“x”:112,
“y”:154
}, {
“et”:“mm”,
“x”:117,
“y”:155
}, {
“et”:“mm”,
“x”:120,
“y”:155
}, {
“et”:“mm”,
“x”:123,
“y”:154
}, {
“et”:“mm”,
“x”:127,
“y”:151
}, {
“et”:“mm”,
“x”:131,
“y”:148
}, {
“et”:“mm”,
“x”:135,
“y”:145
}, {
“et”:“mm”,
“x”:139,
“y”:140
}, {
“et”:“mm”,
“x”:142,
“y”:137
}, {
“et”:“mu”
}, ];
line.forEach(点=>{
如果(point.et=='mm'){
舞台火灾(“mousemove”{
pos:{
x:第x点,
y:点,y
}
});
}否则如果(point.et=='md'){
舞台火灾(“mousedown”{
pos:{
x:第x点,
y:点,y
}
});
}else如果(point.et=='mu'){
舞台火灾(‘鼠标’{
pos:{
x:第x点,
y:点,y
}
});
}
});      
这是那幅画有趣的部分:

你可以看到上面有两条在曲线上画的锐利的边/线。我无法解释这是怎么发生的。您还可以清楚地看到它不是5px宽(笔划宽度设置为5px)

有更多画布/konvajs绘图经验的人能解释一下这里发生了什么,我应该怎么做才能摆脱这种行为吗

谢谢,
K

我想我明白了问题所在。数据似乎有问题。下面是隔离相关数据的JSBin

数据似乎有问题,这可能是导致问题的原因。我现在需要弄清楚画布是如何生成看起来不正常的触摸事件的

<!DOCTYPE html>
<html>
  <head>
    <script src="https://unpkg.com/konva@4.2.0/konva.min.js"></script>
    <meta charset="utf-8" />
    <title>Konva Free Drawing Demo</title>
    <style>
      body {
        margin: 0;
        padding: 0;
        overflow: hidden;
        background-color: #f0f0f0;
      }
    </style>
  </head>

  <body>
    Tool:
    <select id="tool">
      <option value="brush">Brush</option>
      <option value="eraser">Eraser</option>
    </select>
    <div id="container"></div>
    <script>
      var width = window.innerWidth;
      var height = window.innerHeight - 25;

      // first we need Konva core things: stage and layer
      var stage = new Konva.Stage({
        container: 'container',
        width: width,
        height: height
      });

      var layer = new Konva.Layer();
      stage.add(layer);

      var isPaint = false;
      var mode = 'brush';
      var lastLine;

      stage.on('mousedown touchstart', function(e) {
        isPaint = true;
        var pos = e.pos;
        lastLine = new Konva.Line({
          stroke: '#df4b26',
          strokeWidth: 5,
          globalCompositeOperation:
            mode === 'brush' ? 'source-over' : 'destination-out',
          points: [pos.x, pos.y]
        });
        layer.add(lastLine);
      });

      stage.on('mouseup touchend', function() {
        isPaint = false;
      });

      // and core function - drawing
      stage.on('mousemove touchmove', function(e) {
        if (!isPaint) {
          return;
        }

        const pos = e.pos;
        var newPoints = lastLine.points().concat([pos.x, pos.y]);
        lastLine.points(newPoints);
        layer.batchDraw();
      });

      var select = document.getElementById('tool');
      select.addEventListener('change', function() {
        mode = select.value;
      });

        const line = [{
            "et": "md",
            "x": 109,
            "y": 94
        }, {
            "et": "mm",
            "x": 110,
            "y": 98
        }, {
            "et": "mm",
            "x": 110,
            "y": 103
        }, {
            "et": "mm",
            "x": 110,
            "y": 111
        }, {
            "et": "mm",
            "x": 110,
            "y": 116
        }, {
            "et": "mm",
            "x": 110,
            "y": 123
        }, {
            "et": "mm",
            "x": 110,
            "y": 129
        }, {
            "et": "mm",
            "x": 110,
            "y": 135
        }, {
            "et": "mm",
            "x": 110,
            "y": 141
        }, {
            "et": "mm",
            "x": 110,
            "y": 143
        }, {
            "et": "mm",
            "x": 110,
            "y": 147
        }, {
            "et": "mm",
            "x": 110,
            "y": 150
        }, {
            "et": "mm",
            "x": 111,
            "y": 152
        }, {
            "et": "mm",
            "x": 114,
            "y": 155
        }, {
            "et": "mm",
            "x": 112,
            "y": 154
        }, {
            "et": "mm",
            "x": 117,
            "y": 155
        }, {
            "et": "mm",
            "x": 120,
            "y": 155
        }, {
            "et": "mm",
            "x": 123,
            "y": 154
        }, {
            "et": "mm",
            "x": 127,
            "y": 151
        }, {
            "et": "mm",
            "x": 131,
            "y": 148
        }, {
            "et": "mm",
            "x": 135,
            "y": 145
        }, {
            "et": "mm",
            "x": 139,
            "y": 140
        }, {
            "et": "mm",
            "x": 142,
            "y": 137
        }, {
            "et": "mu"
        }, ];

        line.forEach(point => {
            if (point.et === 'mm') {
                stage.fire('mousemove', {
                    pos: {
                        x: point.x,
                        y: point.y
                    }
                });
            } else if (point.et == 'md') {
                stage.fire('mousedown', {
                    pos: {
                        x: point.x,
                        y: point.y
                    }
                });
            } else if (point.et === 'mu') {
                stage.fire('mouseup', {
                    pos: {
                        x: point.x,
                        y: point.y
                    }
                });
            }
        });      
    </script>
  </body>
</html>
{
        "et": "md",
        "x": 110,
        "y": 147
    }, {
        "et": "mm",
        "x": 110,
        "y": 150
    }, {
        "et": "mm",
        "x": 111,
        "y": 152
    }, {
        "et": "mm",
        "x": 114,
        "y": 155
    }, {
        "et": "mm",
        "x": 112,
        "y": 154
    }, {
        "et": "mm",
        "x": 117,
        "y": 155
    }, {
        "et": "mu"
    },