Сгенерированный рисунок дает неожиданный вывод - PullRequest
1 голос
/ 25 марта 2020

Я пытаюсь сгенерировать рисунок, основанный на событиях мыши, и замечаю интересное поведение рендеринга, которое не могу объяснить, почему так происходит. Вот jsbin, который показывает этот пример: https://jsbin.com/qiqetoy/edit?html, вывод

<!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>

Вот интересная часть этого рисунка:

enter image description here

Вы можете видеть выше, что есть несколько острых краев / линий, которые нарисованы на кривой. Я не могу объяснить, как это происходит. Вы также можете ясно видеть, что он не имеет ширину 5 пикселей (ширина обводки установлена ​​на 5 пикселей).

Может ли кто-нибудь, у кого больше опыта в рисовании холста / конвы js, помочь объяснить, что здесь происходит и что я должен сделать, чтобы избавиться от этого поведения?

Спасибо, K

1 Ответ

1 голос
/ 25 марта 2020

Думаю, я понял, в чем проблема. Данные, кажется, имеют проблему. Вот JSBin, который изолирует данные. https://jsbin.com/nayado/edit?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"
    },

Данные, кажется, не в порядке, что, вероятно, является причиной проблемы. Теперь мне нужно выяснить, как холст генерирует сенсорные события, которые кажутся не в порядке.

...