【问题标题】:Show rectangle on canvas when mouse move鼠标移动时在画布上显示矩形
【发布时间】:2017-03-08 17:17:22
【问题描述】:



我想在画布上绘制矩形。下面的代码工作正常,除了当我绘制矩形时它在鼠标移动时不显示路径。当我离开鼠标时,矩形在画布上可见。

请帮忙,

谢谢

var canvas, ctx, flag = false,
        prevX = 0,
        currX = 0,
        prevY = 0,
        currY = 0,
        currShape = 'rectangle',
        mouseIsDown = 0,
        startX, endX, startY, endY,
        dot_flag = false;

    var x = "white",
        y = 2;
   
    function init() {
        canvas = document.getElementById('can');
        ctx = canvas.getContext("2d");
        var imageObj = new Image(); //Canvas image Obj

        imageObj.onload = function() {
            ctx.drawImage(imageObj, 69, 50);    //Load Image on canvas
        };
        imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg'; //Load Image 

        w = canvas.width;   // Canvas Width
        h = canvas.height;  // Canvas Height
        //Check Shape to be draw
        eventListener();

    }
    function eventListener(){
        if(currShape=='rectangle'){
            canvas.addEventListener("mousedown",function (e) { 
                mouseDown(e);
            }, false);
            canvas.addEventListener("mousemove",function (e){
                mouseXY(e);
            }, false);
            canvas.addEventListener("mouseup", function (e){ 
                mouseUp(e);
            }, false);
        }
    }

function mouseUp(eve) {
    if (mouseIsDown !== 0) {
        mouseIsDown = 0;
        var pos = getMousePos(canvas, eve);
        endX = pos.x;
        endY = pos.y;
        if(currShape=='rectangle')
        {
            drawSquare(); //update on mouse-up
        }
    }
}

function mouseDown(eve) {
    mouseIsDown = 1;
    var pos = getMousePos(canvas, eve);
    startX = endX = pos.x;
    startY = endY = pos.y;
    if(currShape=='rectangle')
    {
        drawSquare(); //update on mouse-up
    }
}

function mouseXY(eve) {
    if (mouseIsDown !== 0) {
        var pos = getMousePos(canvas, eve);
        endX = pos.x;
        endY = pos.y;
        //drawSquare();
    }
}

function drawSquare() {
    // creating a square
    var w = endX - startX;
    var h = endY - startY;
    var offsetX = (w < 0) ? w : 0;
    var offsetY = (h < 0) ? h : 0;
    var width = Math.abs(w);
    var height = Math.abs(h);

               
    ctx.beginPath();
    ctx.globalAlpha=0.7;
    ctx.rect(startX + offsetX, startY + offsetY, width, height);
    ctx.fillStyle = x;
    ctx.fill();
    ctx.lineWidth = y;
    ctx.strokeStyle = x;
    ctx.stroke();
}

function getMousePos(canvas, evt) {
    var rect = canvas.getBoundingClientRect();
    return {
        x: evt.clientX - rect.left,
        y: evt.clientY - rect.top
    };
}
.colortool div {
        width: 15px;
        height: 15px;
        float: left;
        margin-left: 2px;
    }
    .clear {
      clear: both;
    }
<!DOCTYPE HTML>
<html>
    <body onload="init()">
     <div class="canvasbody">
     <canvas id="can" width="400" height="400" style="border:1px dotted #eee;"></canvas>
     </div>
    </body>
    </html>

【问题讨论】:

  • 与您的问题无关,但不需要那些包装事件处理程序的匿名函数 - 只需执行 canvas.addEventListener(eventName, funcName, false)
  • @Alnitak 是的,你是对的。谢谢

标签: javascript jquery html canvas


【解决方案1】:

这是你的新 JavaScript

var canvas, cnvHid, cnvRender, ctx, flag = false,
        prevX = 0,
        currX = 0,
        prevY = 0,
        currY = 0,
        currShape = 'rectangle',
        mouseIsDown = 0,
        startX, endX, startY, endY,
        dot_flag = false;

    var x = "white",
        y = 2;

    function init() {
        canvas = document.getElementById('can');
        cnvHid = document.getElementById( "canHid" );
        cnvRender = document.getElementById( "canRend" );
        ctx = canvas.getContext("2d");
        var imageObj = new Image(); //Canvas image Obj

        imageObj.onload = function() {
            ctx.drawImage(imageObj, 69, 50);    //Load Image on canvas
            renderAllCanvas();
        };
        imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg'; //Load Image 

        w = canvas.width;   // Canvas Width
        h = canvas.height;  // Canvas Height
        //Check Shape to be draw
        eventListener();
    }
    function eventListener(){
        if(currShape=='rectangle'){
            cnvRender.addEventListener("mousedown",function (e) { 
                mouseDown(e);
                renderAllCanvas();
            }, false);
            cnvRender.addEventListener("mousemove",function (e){
                mouseXY(e);
                renderAllCanvas();
            }, false);
            cnvRender.addEventListener("mouseup", function (e){ 
                mouseUp(e);
                renderAllCanvas();
            }, false);
        }
    }
    function mouseUp(eve) {
    if (mouseIsDown !== 0) {
        mouseIsDown = 0;
        var pos = getMousePos(canvas, eve);
        endX = pos.x;
        endY = pos.y;
        if(currShape=='rectangle')
        {
            drawSquare( canvas ); //update on mouse-up
            cnvHid.getContext( "2d" ).clearRect( 0, 0, cnvHid.width, cnvHid.height );
        }
    }
}

function mouseDown(eve) {
    mouseIsDown = 1;
    var pos = getMousePos(canvas, eve);
    startX = endX = pos.x;
    startY = endY = pos.y;
    if(currShape=='rectangle')
    {
        drawSquare( canvas ); //update on mouse-up
    }
}

function mouseXY(eve) {
    if (mouseIsDown !== 0) {
        var pos = getMousePos(canvas, eve);
        endX = pos.x;
        endY = pos.y;
        drawSquare( cnvHid, true );
    }
}

function drawSquare( cnv, clear ) {
    var ctx = cnv.getContext( "2d" );
    if( clear && clear === true ){
        ctx.clearRect( 0, 0, cnv.width, cnv.height );
    }
    // creating a square
    var w = endX - startX;
    var h = endY - startY;
    var offsetX = (w < 0) ? w : 0;
    var offsetY = (h < 0) ? h : 0;
    var width = Math.abs(w);
    var height = Math.abs(h);

    ctx.beginPath();
    ctx.globalAlpha=0.7;
    ctx.rect(startX + offsetX, startY + offsetY, width, height);
    ctx.fillStyle = x;
    ctx.fill();
    ctx.lineWidth = y;
    ctx.strokeStyle = x;
    ctx.stroke();
    ctx.closePath();
}

function getMousePos(canvas, evt) {
    var rect = canvas.getBoundingClientRect();
    return {
        x: evt.clientX - rect.left,
        y: evt.clientY - rect.top
    };
}

function renderAllCanvas(){
    var cnxRender = cnvRender.getContext( "2d" );
    cnxRender.drawImage(
        canvas
        ,0,0
        ,cnvRender.width,cnvRender.height
    );
    cnxRender.drawImage(
        cnvHid
        ,0,0
        ,cnvRender.width,cnvRender.height
    );
}

这是你的新 HTML

<!DOCTYPE HTML>
<html>
    <body onload="init()">
        <div class="canvasbody">
        <canvas id="can" width="400" height="400" style="display: none;"></canvas>
        <canvas id="canHid" width="400" height="400" style="display: none;"></canvas>
        <canvas id="canRend" width="400" height="400" style="border:1px dotted #eee;"></canvas>
        </div>
    </body>
</html>

【讨论】:

  • 鼠标事件每秒触发多达 200 次以上。屏幕每秒更新 60 次。绝大多数drawSquare 电话将永远不会被看到。这样既浪费设备电量,又浪费客户端资源,拖拽时会造成剪切。对于任何类型的基于浏览器的动画(包括 UI 交互),您都应该使用 requestAnimationFrame 来最大限度地减少资源使用和不需要的动画伪影。请参阅stackoverflow.com/a/40126873/3877726,了解如何为 UI 交互设置动画。
【解决方案2】:

在某种程度上,您需要跟踪您对画布上绘制的形状所做的更改。在您的情况下,您将首先创建一个非常小的矩形,然后在拖动移动期间根据您的鼠标位置对其进行缩放。

目前,您只有一个绘制全新矩形的函数,但不考虑任何先前的“状态”。

我发现这个blogpost 可能会有所帮助。它没有特别解释缩放,但它可以帮助理解背后的基本概念,所以我认为这将是您找到合适解决方案的好方法。

【讨论】:

    【解决方案3】:

    因为我们使用它的 id 在 DOM 中找到 canvas 标签,然后将 canvas 的绘图上下文设置为 2D。这里有两件重要的事情是在我们绘制 recatangle 时存储信息,以及一个用于检查用户是在绘制矩形还是不绘制矩形的布尔值。 您可以参考这些链接:Drawing a rectangle using click, mouse move, and click Draw on HTML5 Canvas using a mouse 检查给定链接中的 js fiddle。 希望这会对你有所帮助..

    【讨论】:

    • 感谢分享链接。我会检查这些链接。
    【解决方案4】:

    您当前的代码在鼠标移动时已将重绘注释掉,这是更新画布所必需的。但是,您的代码也会以绘制矩形的方式破坏图像。如果您保留如下所示的图像并在绘制矩形之前在每一帧上重新绘制它,它可能会达到预期的效果。

    var canvas, ctx, flag = false,
            prevX = 0,
            currX = 0,
            prevY = 0,
            currY = 0,
            currShape = 'rectangle',
            mouseIsDown = 0,
            startX, endX, startY, endY,
            dot_flag = false;
            var x = "white",
            y = 2, 
            image = null;
    
       
        function init() {
            canvas = document.getElementById('can');
            ctx = canvas.getContext("2d");
            var imageObj = new Image(); //Canvas image Obj
    
            imageObj.onload = function() {
                image = imageObj;
                ctx.drawImage(image, 69, 50);    //Load Image on canvas
            };
            imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg'; //Load Image 
    
            w = canvas.width;   // Canvas Width
            h = canvas.height;  // Canvas Height
            //Check Shape to be draw
            eventListener();
    
        }
        function eventListener(){
            if(currShape=='rectangle'){
                canvas.addEventListener("mousedown",function (e) { 
                    mouseDown(e);
                }, false);
                canvas.addEventListener("mousemove",function (e){
                    mouseXY(e);
                }, false);
                canvas.addEventListener("mouseup", function (e){ 
                    mouseUp(e);
                }, false);
            }
        }
    
    function mouseUp(eve) {
        if (mouseIsDown !== 0) {
            mouseIsDown = 0;
            var pos = getMousePos(canvas, eve);
            endX = pos.x;
            endY = pos.y;
            if(currShape=='rectangle')
            {
                drawSquare(); //update on mouse-up
            }
        }
    }
    
    function mouseDown(eve) {
        mouseIsDown = 1;
        var pos = getMousePos(canvas, eve);
        startX = endX = pos.x;
        startY = endY = pos.y;
        if(currShape=='rectangle')
        {
            drawSquare(); //update on mouse-up
        }
    }
    
    function mouseXY(eve) {
        if (mouseIsDown !== 0) {
            var pos = getMousePos(canvas, eve);
            endX = pos.x;
            endY = pos.y;
            drawSquare();
        }
    }
    
    function drawSquare() {
    
        // draw background image
        if(image) {
            ctx.drawImage(image, 69, 50);
        }
    
        // creating a square
        var w = endX - startX;
        var h = endY - startY;
        var offsetX = (w < 0) ? w : 0;
        var offsetY = (h < 0) ? h : 0;
        var width = Math.abs(w);
        var height = Math.abs(h);
                  
        ctx.beginPath();
        ctx.globalAlpha=0.7;
        ctx.rect(startX + offsetX, startY + offsetY, width, height);
        ctx.fillStyle = x;
        ctx.fill();
        ctx.lineWidth = y;
        ctx.strokeStyle = x;
        ctx.stroke();
    }
    
    function getMousePos(canvas, evt) {
        var rect = canvas.getBoundingClientRect();
        return {
            x: evt.clientX - rect.left,
            y: evt.clientY - rect.top
        };
    }
    .colortool div {
            width: 15px;
            height: 15px;
            float: left;
            margin-left: 2px;
        }
        .clear {
          clear: both;
        }
    <!DOCTYPE HTML>
    <html>
        <body onload="init()">
         <div class="canvasbody">
         <canvas id="can" width="400" height="400" style="border:1px dotted #eee;"></canvas>
         </div>
        </body>
        </html>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多