当鼠标移动时在画布上显示矩形

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;
   
    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
@Alnitak 是的,你说得对。谢谢。 - Ajay Thakur
4个回答

0
你当前的代码在鼠标移动时注释了重绘,这将需要更新画布。然而,你的代码也破坏了矩形的绘制方式。如果你保留下面所示的图像,并在每个帧之前重新绘制它,可能会产生期望的效果。

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>


0

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

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

我找到了这个博客文章,它可能会有所帮助。它没有特别解释缩放,但它可以帮助理解基本概念,因此我认为这是您找到合适解决方案的好方法。


0

由于我们正在使用其ID在DOM中查找画布标记,然后将画布的绘图上下文设置为2D。这里有两件重要的事情是存储我们绘制矩形的信息和一个布尔值来检查用户是否正在绘制矩形。 您可以参考以下链接:使用单击、鼠标移动和单击绘制矩形 使用鼠标在HTML5画布上绘制 请在给定链接中检查js fiddle。 希望这可以帮助您。


感谢分享这些链接。我会检查这些链接。 - Ajay Thakur

0

这是你的新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>

1
鼠标事件每秒触发200多次。屏幕更新60次/秒。绝大多数drawSquare调用将永远不会被看到。这是一种浪费设备功率、客户资源的行为,并且在拖动时会导致剪切。对于任何类型的基于浏览器的动画(包括UI交互),您应该使用requestAnimationFrame来最小化资源使用和不需要的动画效果。请参见https://dev59.com/JJvga4cB1Zd3GeqP6b_z#40126873,了解如何动画UI交互的示例。 - Blindman67

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接