【问题标题】:how can I put multiple objects on the same canvas?如何将多个对象放在同一个画布上?
【发布时间】:2015-09-20 14:26:23
【问题描述】:

我正在创建一个网页,您可以在其中动态绘制多个矩形。我可以绘制单个对象,但是一旦我尝试绘制另一个对象,前一个对象就消失了。我尝试使用save()和restore()来保存状态,这里好像放不下了。将 save 方法放在 mouseup 中并在 mousedown 事件中调用 restore 方法是否合乎逻辑?任何帮助或建议将不胜感激。

<script>
  var canvas = document.getElementById('myCanvasCircle'),
      ctx = canvas.getContext('2d'),
      circle = {},
      drag = false,
      circleMade = false,
      mouseMoved = false;

  function draw() {
    ctx.beginPath();
    ctx.arc(circle.X, circle.Y, circle.radius, 0, 2.0 * Math.PI);
    ctx.stroke();

  }

  function mouseDown(e) {
    ctx.restore();
    circle.startX = e.pageX - this.offsetLeft;
    circle.startY = e.pageY - this.offsetTop;

    circle.X = circle.startX;
    circle.Y = circle.startY;

    if (!circleMade) {
      circle.radius = 0;
    }

    drag = true;
  }

  function mouseUp() {
    drag = false;
    circleMade = true;

    if (!mouseMoved) {
      circle = {};
      circleMade = false;
      ctx.clearRect(0, 0, canvas.width, canvas.height);
    }

    mouseMoved = false;
    ctx.save();
  }

  function mouseMove(e) {
    if (drag) {
      mouseMoved = true;
      circle.X = e.pageX - this.offsetLeft;
      circle.Y = e.pageY - this.offsetTop;
      if (!circleMade) {
        circle.radius = Math.sqrt(Math.pow((circle.X - circle.startX), 2) + Math.pow((circle.Y - circle.startY), 2));
      }
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      draw();


    }
  }

  function init() {
    canvas.addEventListener('mousedown', mouseDown, false);
    canvas.addEventListener('mouseup', mouseUp, false);
    canvas.addEventListener('mousemove', mouseMove, false);

  }

  init();

</script>

【问题讨论】:

    标签: javascript html canvas drawing


    【解决方案1】:

    您需要将有关您正在绘制的内容的信息保存在一个单独的对象中,每次在画布上绘制时,您都会擦除并重绘新对象。 因此,当您 clearRect 然后绘制时,您正在清除然后绘制一个新的,但旧的被抛在后面。一个很好的例子:

    var SavedCircles = [];
    var circleInfo = function()
    {
      this.x = 0;
      this.y = 0;
      this.startX = 0;
      this.startY = 0;
      this.radius = 0;
    }
    circle = {};
    
    function draw()
    {
       for(var x=0;x<SavedCircles.length;x++)
       {
           ctx.beginPath();
           ctx.arc(SavedCircles[x].X, SavedCircles[x].Y, SavedCircles[x].radius, 0, 2.0 * Math.PI);
           ctx.stroke();
       }
    }
    
    function mouseDown()
    {
      circle = new circleInfo();
    }
    
    function mouseUp()
    {
       SavedCircles.push(circle);
    }
    
    function mouseMove()
    {
       draw();
    }
    

    这样您就可以摆脱保存和恢复,只需通过以下方式即可更快地清除画布: canvas.width = canvas.width;

    这应该可以帮助您保持所有圆圈的绘制。用您的代码填写其余部分。

    【讨论】:

    • using canvas.width = canvas.width; 清除画布是一种不好的做法,因为它不仅会从您绘制的内容中清除画布,还会重置 lineWidth、strokeStyles、fillStyles 和转换等属性。它也是比替代 ctx.clearRect(0,0,canvas.width,canvas.height); 慢,这是清除画布的首选方式。
    • 老实说,您不应该依赖画布来存储这些属性,而应该将它们存储在对象的其他位置。但是参考canvas.width你是正确的,参考这篇文章stackoverflow.com/questions/2142535/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-23
    • 1970-01-01
    • 2013-12-17
    • 1970-01-01
    • 2014-02-16
    • 1970-01-01
    相关资源
    最近更新 更多