Нарисуйте прямоугольник, используя холст с фиксированной шириной - PullRequest
0 голосов
/ 05 июля 2018

Я пытаюсь позволить пользователю нарисовать прямоугольник на изображении, которое находится внутри холста, используя событие 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 голосов
/ 06 июля 2018

Проблема здесь:

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;

Также измените drawImage в функции mouseMove на:

  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 здесь

0 голосов
/ 06 июля 2018

К сожалению, как вы обнаружили, размер CSS искажает рисунки холста. Если я понимаю результат, к которому вы стремитесь, вы хотите, чтобы переменная высота и фиксированная ширина соответствовали исходному изображению. Этот код, адаптированный из другого ответа , должен сделать это:

  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);

Обратите внимание, что я также изменил второй вызов contex.drawImage(), чтобы он соответствовал приведенному выше в вашем коде. Смотрите это JSFiddle .

...