【问题标题】:KineticJS, Paint like program, brush gapsKineticJS,Paint like 程序,画笔间隙
【发布时间】:2016-08-04 22:35:10
【问题描述】:

我正在尝试使用 KineticJS 进行绘画之类的操作。我正在尝试使用源自鼠标位置的圆圈绘制颜色。但是鼠标位置的事件监听器似乎太慢了,当我移动鼠标太快时,绘制的圆圈彼此相距很远,导致:

我看到有人用点填充数组,在它们之间画线,但我认为这对优化非常不利,因为在复制屏幕过多后,画布开始滞后,因为它有太多线,每帧都会重绘。我决定取消图层的清理,并在当前鼠标位置添加新圆圈并删除旧圆圈以进行优化。但是,由于我没有在鼠标快速移动时画线,所以会留下巨大的空白。如果有人可以帮助我,我将不胜感激。

这是我的代码:

(function() {
  var stage = new Kinetic.Stage({
      container: 'main-drawing-window',
      width: 920,
      height: 750
    }),
    workplace = document.getElementById('main-drawing-window'),
    layer = new Kinetic.Layer({
      clearBeforeDraw: false
    }),
    border = new Kinetic.Rect({
      stroke: "black",
      strokeWidth: 2,
      x: 0,
      y: 0,
      width: stage.getWidth(),
      height: stage.getHeight()
    }),
    brush = new Kinetic.Circle({
      radius: 20,
      fill: 'red',
      strokeWidth: 2,
      x: 100,
      y: 300
    });

  Input = function() {
    this.mouseIsDown = false;
    this.mouseX = 0;
    this.mouseY = 0;
    this.offsetX = 0;
    this.offsetY = 0;
  };

  var input = new Input();

  document.documentElement.onmousedown = function(ev) {
    input.mouseIsDown = true;
  };

  document.documentElement.onmouseup = function(ev) {
    input.mouseIsDown = false;
  };

  document.documentElement.onmousemove = function(ev) {
    ev = ev || window.event;

    // input.mouseX = (ev.clientX - workplace.offsetLeft);
    // input.mouseY = (ev.clientY - workplace.offsetTop);
    input.mouseX = (ev.offsetX);
    input.mouseY = (ev.offsetY);
  };

  function DistanceBetweenPoints(x1, y1, x2, y2) {
    return Math.sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)));
  }

  var canvasDraw = setInterval(function() {
    // console.log(input);
    if (input.mouseIsDown) {
      workplace.style.cursor = "crosshair";
      var currentBrushPosition = brush.clone();
      currentBrushPosition.setX(input.mouseX);
      currentBrushPosition.setY(input.mouseY);
      // var distance = DistanceBetweenPoints(brush.getX(), brush.getY(), currentBrushPosition.getX(), currentBrushPosition.getY());
      // if (distance > brush.getRadius() * 2) {
      //     var fillingLine = new Kinetic.Line({
      //         points: [brush.getX(), brush.getY(), currentBrushPosition.getX(), currentBrushPosition.getY()],
      //         stroke: 'yellow',
      //         strokeWidth: brush.getRadius()*2,
      //         lineJoin: 'round'
      //     });
      //     // layer.add(fillingLine);
      // }

      layer.add(currentBrushPosition);
      brush.remove();
      brush = currentBrushPosition;
      layer.draw();
      // if (fillingLine) {
      //     fillingLine.remove();
      // }
    }
    if (!input.mouseIsDown) {
      workplace.style.cursor = 'default';
    }
  }, 16);

  layer.add(border);
  stage.add(layer);
})();
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>Coloring Game</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/kineticjs/5.2.0/kinetic.min.js"></script>

</head>

<body>
  <div id="main-drawing-window"></div>
  <script type="text/javascript" src="./JS files/canvas-draw.js"></script>
</body>

</html>

【问题讨论】:

    标签: javascript canvas kineticjs


    【解决方案1】:

    不要为每个鼠标移动使用单独的Kinetic.Circles。每个 Kinetic 对象都是一个“托管”对象,并且该管理占用了大量资源。 KineticJS 会随着每次鼠标移动而增加圈数。

    改为使用Kinetic.Shape 并使用

    在画布上绘制圆圈
    // This is Pseudo-code since I haven't worked with KineticJS in a while
    shapeContext.beginPath();
    shapeContext.arc(mouseX,mouseY,20,0,Math.PI*2);
    shapeContext.fillStrokeShape(this);
    

    这可能会解决您的问题,但是如果鼠标在一次 mousemove 中移动了很远,那么您可能必须在最后一个鼠标点和当前远处之间绘制一个 lineTo(而不是 arc)鼠标点。

    【讨论】:

      猜你喜欢
      • 2013-12-12
      • 2013-10-20
      • 2014-05-26
      • 1970-01-01
      • 2012-08-23
      • 1970-01-01
      • 1970-01-01
      • 2013-05-07
      • 1970-01-01
      相关资源
      最近更新 更多