使用固定宽度的画布绘制矩形

时间:2018-07-05 12:13:41

标签: javascript html5 canvas mouseevent

我试图让用户使用mousemove事件在画布内的图像上绘制一个矩形。此代码可以正常工作:

HTML:

    <canvas id="canvas"></canvas>

JavaScript:

window.onload = drawCanvas('http://www.therebeldandy.com/wp-content/uploads/2016/09/Menswear-Dog-4.jpg');

var context = canvas.getContext('2d');

function drawCanvas(src) {

    var rect = {};
    var drag = false;
    var img = new Image();
    var canvas = document.getElementById('canvas');

    img.src = src;
    img.addEventListener('load', function () {
        canvas.width = img.naturalWidth;
        canvas.height = img.naturalHeight;
        context.drawImage(img, 0, 0);
    }, false);

    // Draw user selection
    canvas.addEventListener('mousedown', mouseDown, false);
    canvas.addEventListener('mouseup', mouseUp, false);
    canvas.addEventListener('mousemove', mouseMove, false);

    function mouseDown(e) {
        rect.startX = e.pageX - this.offsetLeft;
        rect.startY = e.pageY - this.offsetTop;
        drag = true;
    }

    function mouseUp() {
        drag = false;
    }

    function mouseMove(e) {
        if (drag) {
            context.clearRect(0, 0, 500, 500);
            context.drawImage(img, 0, 0);
            rect.w = (e.pageX - this.offsetLeft) - rect.startX;
            rect.h = (e.pageY - this.offsetTop) - rect.startY;
            context.lineWidth = 3;
            context.strokeStyle = '#df4b26';
            context.fillStyle = "rgba(255, 255, 255, .25)";
            context.strokeRect(rect.startX, rect.startY, rect.w, rect.h);
            context.fillRect(rect.startX, rect.startY, rect.w, rect.h);
            console.log(rect.startX, rect.startY, rect.w, rect.h);
        }
    }

}

问题是我需要确保图像具有固定的宽度,所以我改用此HTML:

<canvas id="canvas" style="max-width: 300px; height: auto;"></canvas>

仅添加这种样式会破坏整个内容:我无法再选择想要的图像部分。

这里有个小提琴,可以让您更好地了解我要完成的工作:JSFiddle

有没有办法使这项工作有效?我已经奋斗了几个小时,所以任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

不幸的是,正如您所发现的那样,CSS大小调整使画布图纸变形。如果我了解所要获得的结果,则需要可变高度和固定宽度,并缩放源图像以使其适合。改编自another answer的这段代码应该做到这一点:

let song = artists[indexPath.section].songs[indexPath.row]

请注意,我还更改了第二个 var width = 500; // specify your fixed width here var h; var w; var scale; img.src = src; img.addEventListener('load', function() { h = img.naturalHeight; w = img.naturalWidth; scale = Math.min(width / w, width / h); canvas.width = width; canvas.height = h * scale; context.drawImage(img, 0, 0, w, h, 0, 0, w * scale, h * scale); }, false); 调用以匹配您的代码中的上述调用。参见此JSFiddle

答案 1 :(得分:0)

问题在这里:

canvas.width = img.naturalWidth

将其更改为此:

img.addEventListener('load', function() {
  canvas.width = width;
  canvas.height = img.naturalHeight;
  context.drawImage(img, 0, 0, img.naturalWidth, img.naturalHeight, 0, 0, width, img.naturalHeight); 
}, false);`

并将宽度设置为变量

 var width = 500;

还可以将mouseMove函数中的drawImage更改为:

  context.drawImage(img, 0, 0, img.naturalWidth, img.naturalHeight, 0, 0, width, img.naturalHeight);

并保留画布原样:

  <canvas id="canvas" style="max-width: 100%; height: auto;"></canvas>

js fidle here