【问题标题】:Drawing multiple rectangles on canvas without clearing the back image在画布上绘制多个矩形而不清除背面图像
【发布时间】:2019-12-16 13:13:21
【问题描述】:

我正在尝试在画布上绘制多个矩形。我能够做到这一点,除了它在鼠标移动时不清除矩形。 当我尝试使用clearRect 清除矩形时,画布上的背面图像也会被清除。所以我在下面的代码中注释掉了//ctx.clearRect(0, 0, canvas.width, canvas.height);

我已经通过几个SO posts 提出了类似的问题,但似乎没有用

$(function(){
				var canvas = document.getElementById('myCanvas');
        if (canvas.getContext){
          var ctx = canvas.getContext('2d');
          ctx.fillText("Sample String", 20, 50);
        }
        
        var ctx = canvas.getContext('2d');
    //Variables
    var canvasx = $(canvas).offset().left;
    var canvasy = $(canvas).offset().top;
    var last_mousex = last_mousey = 0;
    var mousex = mousey = 0;
    var mousedown = false;

    //Mousedown
    $(canvas).on('mousedown', function (e) {
        last_mousex = parseInt(e.clientX - canvasx);
        last_mousey = parseInt(e.clientY - canvasy);
        mousedown = true;        

    });

    //Mouseup
    $(canvas).on('mouseup', function (e) {
        mousedown = false;        
    });

    //Mousemove
    $(canvas).on('mousemove', function (e) {
        mousex = parseInt(e.clientX - canvasx);
        mousey = parseInt(e.clientY - canvasy);
        if (mousedown) {            
            //ctx.clearRect(0, 0, canvas.width, canvas.height); 
            var width = mousex - last_mousex;
            var height = mousey - last_mousey;
            ctx.beginPath();            
            ctx.rect(last_mousex, last_mousey, width, height);
            ctx.strokeStyle = 'black';
            ctx.lineWidth = 1;
            ctx.stroke();
        }
        //Output
        $('#results').html('current: ' + mousex + ', ' + mousey + '<br/>last: ' + last_mousex + ', ' + last_mousey + '<br/>mousedown: ' + mousedown);
    });
        
})
canvas { border: 1px solid black; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3>
 Use mouse to draw multiple rectangles with in the canvas
</h3>
<canvas id="myCanvas"></canvas>
<div id="results">

</div>

【问题讨论】:

    标签: javascript jquery html html5-canvas


    【解决方案1】:

    你的错误是你清除了所有的画布:

    ctx.clearRect(0, 0, canvas.width, canvas.height);
    

    而不是只清除您之前绘制的区域:

    ctx.clearRect(prev_x-1, prev_y-1, prev_w+2, prev_h+2);
    

    我在这里写了基本的想法,但是您需要添加一些代码来清除该区域,这取决于鼠标的方向和移动到的方向(尝试​​将鼠标移动到每个角落,看看会发生什么)。

    $("#clear").click(function(){
        var canvas = document.getElementById('myCanvas');
        var ctx = canvas.getContext('2d');
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.fillText("Sample String", 20, 50);
    });
    
    $(function(){
    				var canvas = document.getElementById('myCanvas');
            if (canvas.getContext){
              var ctx = canvas.getContext('2d');
              ctx.fillText("Sample String", 20, 50);
            }
            
            var ctx = canvas.getContext('2d');
        //Variables
        var canvasx = $(canvas).offset().left;
        var canvasy = $(canvas).offset().top;
        var last_mousex = last_mousey = w = h = 0;
        var prev_x = prev_y = prev_w = prev_h = 0;
        var mousex = mousey = 0;
        var mousedown = false;
    
        //Mousedown
        $(canvas).on('mousedown', function (e) {
            last_mousex = parseInt(e.clientX - canvasx);
            last_mousey = parseInt(e.clientY - canvasy);
            mousedown = true;        
    
        });
    
        //Mouseup
        $(canvas).on('mouseup', function (e) {
            w = h = 0;
            mousedown = false;        
        });
    
        //Mousemove
        $(canvas).on('mousemove', function (e) {
            mousex = parseInt(e.clientX - canvasx);
            mousey = parseInt(e.clientY - canvasy);
            if (mousedown) {   
                prev_x = last_mousex;
                prev_y = last_mousey;
                prev_w = w;
                prev_h = h;
                ctx.clearRect(prev_x-1, prev_y-1, prev_w+2, prev_h+2);
    
                w = mousex - last_mousex;
                h = mousey - last_mousey;
                ctx.beginPath();            
                ctx.rect(last_mousex, last_mousey, w, h);
                ctx.strokeStyle = 'black';
                ctx.lineWidth = 1;
                ctx.stroke();
            }
            //Output
            $('#results').html('current: ' + mousex + ', ' + mousey + '<br/>last: ' + last_mousex + ', ' + last_mousey + '<br/>mousedown: ' + mousedown);
        });
            
    })
    canvas { border: 1px solid black; }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <h3>
     Use mouse to draw multiple rectangles with in the canvas
    </h3>
    <button id="clear">clear</button>
    <br />
    <canvas id="myCanvas"></canvas>
    <div id="results">
    </div>

    【讨论】:

    • 我知道目前它仅在您从左向右移动时才有效。但感谢您解决原来的问题
    • 不客气。是的,您需要进行一些 if 检查以匹配不同方向的明确区号:ctx.clearRect(prev_x+&lt;deltaX&gt;, prev_y+&lt;deltaY&gt;, prev_w+&lt;deltaW&gt;, prev_h+&lt;deltaH);
    • 你为什么要减 1 加 2?我没听懂
    • 绘制的基本区域是:(prev_x, prev_y, prev_w, prev_h),但是因为1px的笔画需要“每个方向加1”,即(prev_x-1 , prev_y-1, prev_w+1, prev_h+1),但是因为我们实际上将矩形向上移动了 1px,向左移动了 1px,所以我们需要重新添加它的宽度和高度。
    【解决方案2】:

    我认为你可以采用另一种方法

    仅使用 mousedown 事件将所有矩形保存到数组变量中

    然后你可以用保存的变量清除和重绘整个画布

    var shapes = [];
    canva.addEventListener('mousedown', mouseDownListener);
    
    class Rectangle() { 
       public ctx, x, y, w, h;
    
       public Rectangle(ctx, x, y, w, h) {
          this.ctx = ctx;
          this.x = x;
          this.y = y;
          this.w = w;
          this.h = h;
       }
       public draw() {
          // draw using ctx here
       }
    }
    
    function mouseDownListener() { 
        // create rectable
        var rectangle = new Rectangle(ctx, x, y, width, height);
        // save rectangle to an array
        shapes.push(rectangle);
        // redraw canvas
        redraw();
    }
    
    function redraw() {
        ctx.clearRect(0, 0, canvas.width, canvas.height); 
        // draw all rectangle
        shapes.forEach(function(shape) {
            // draw shape
            shape.draw();
        })
    }
    

    【讨论】:

      猜你喜欢
      • 2017-01-19
      • 1970-01-01
      • 2015-10-25
      • 1970-01-01
      • 1970-01-01
      • 2016-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多