проблема с холстом на холсте [дубликат]

Вот исполняемый плагин jar для Maven, который мы используем в Credit Karma. Он создает банку банок с загрузчиком классов, способным загружать классы из вложенных банок. Это позволяет вам иметь один и тот же путь к классам в dev и prod и все еще держать все классы в одном подписанном файле jar.

https://github.com/creditkarma/maven-exec-jar- plugin

И вот сообщение в блоге с подробностями о плагине и почему мы это сделали: https://engineering.creditkarma.com/general-engineering/new-executable-jar -plugin-имеющиеся в наличии апаша-Maven /

51
задан epistemex 17 April 2016 в 05:46
поделиться

4 ответа

Простой сценарий 1: 1

В ситуациях, когда элемент холста равен 1: 1 по сравнению с размером растрового изображения, вы можете получить позиции мыши с помощью этого фрагмента:

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

Просто вызовите его из вашего события с событием и холстом в качестве аргументов. Он возвращает объект с x и y для позиций мыши.

Поскольку позиция мыши, которую вы получаете, относится к окну клиента, вам нужно будет вычесть позицию элемента холста, чтобы преобразовать его относительно самого элемента.

Пример интеграции в ваш код:

//put this outside the event loop..
var canvas = document.getElementById("imgCanvas");
var context = canvas.getContext("2d");

function draw(evt) {
    var pos = getMousePos(canvas, evt);

    context.fillStyle = "#000000";
    context.fillRect (pos.x, pos.y, 4, 4);
}

Скрипт с изменениями

Примечание: границы и отступы будет влиять на позицию, если она применяется непосредственно к элементу canvas, поэтому их необходимо рассмотреть с помощью getComputedStyle() - или применить эти стили к родительскому div.

Когда элемент и растровые изображения имеют разные размеры

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

Пример:

function  getMousePos(canvas, evt) {
  var rect = canvas.getBoundingClientRect(), // abs. size of element
      scaleX = canvas.width / rect.width,    // relationship bitmap vs. element for X
      scaleY = canvas.height / rect.height;  // relationship bitmap vs. element for Y

  return {
    x: (evt.clientX - rect.left) * scaleX,   // scale mouse coordinates after they have
    y: (evt.clientY - rect.top) * scaleY     // been adjusted to be relative to element
  }
}

Скрипт с использованием шкалы

С преобразованиями, применяемыми к контексту (масштаб, вращение и т. д.)

Тогда существует более сложный случай, когда вы применили преобразование к контексту, такое как вращение, перекос / сдвиг, масштабирование, перевод и т. д. Чтобы справиться с этим, вы можете вычислить обратную матрицу текущей матрицы.

Новые браузеры позволяют читать текущую матрицу через свойство currentTransform и Firefox (текущая альфа) даже обеспечивают инвертированную матрицу через mozCurrentTransformInverted. Однако Firefox через mozCurrentTransform вернет массив, а не DOMMatrix, как следует. Ни Chrome, если он включен с помощью экспериментальных флагов, возвратит DOMMatrix, а SVGMatrix.

. В большинстве случаев вам придется реализовать собственное собственное собственное матричное решение (например, мое собственное решение здесь - бесплатный / проект MIT), пока это не получит полную поддержку.

Когда вы в конечном итоге получили матрицу независимо от пути, который вы берете, чтобы получить ее, вам нужно ее инвертировать и примените его к вашим координатам мыши. Затем координаты передаются на холст, который будет использовать свою матрицу, чтобы преобразовать ее назад, где бы она ни находилась.

Таким образом, точка будет в правильном положении относительно мыши. Также здесь вам нужно отрегулировать координаты (перед применением обратной матрицы к ним) относительно элемента.

Пример, показывающий шаги матрицы

function draw(evt) {
    var pos = getMousePos(canvas, evt);        // get adjusted coordinates as above
    var imatrix = matrix.inverse();            // get inverted matrix somehow
    pos = imatrix.applyToPoint(pos.x, pos.y);  // apply to adjusted coordinate

    context.fillStyle = "#000000";
    context.fillRect(pos.x-1, pos.y-1, 2, 2);
}

Пример с использованием решения, связанного выше (замените его с помощью встроенного браузера при более широком использовании).

Пример использования currentTransform при реализации:

    var pos = getMousePos(canvas, e);          // get adjusted coordinates as above
    var matrix = ctx.currentTransform;         // W3C (future)
    var imatrix = matrix.invertSelf();         // invert

    // apply to point:
    var x = pos.x * imatrix.a + pos.y * imatrix.c + imatrix.e;
    var y = pos.x * imatrix.b + pos.y * imatrix.d + imatrix.f;

Обновление. Я сделал бесплатное решение (MIT), чтобы вставить все эти шаги в один простой в использовании объект, который можно найти здесь здесь , а также позаботится о нескольких других мелочах игнорировать.

128
ответ дан epistemex 3 September 2018 в 17:18
поделиться

Обратите внимание на этот вопрос: mouseEvent.offsetX Я получаю намного больше фактического размера холста . Я дал функцию там, которая будет точно соответствовать вашей ситуации

16
ответ дан Community 3 September 2018 в 17:18
поделиться

Вам нужно получить положение мыши относительно холста

. Для этого вам нужно знать положение X / Y холста на странице.

Это называется «смещением» холста, и вот как получить смещение. (Я использую jQuery, чтобы упростить кросс-браузерную совместимость, но если вы хотите использовать сырой javascript, то быстрый Google тоже получит это.)

    var canvasOffset=$("#canvas").offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;

Затем в обработчике мыши вы можете получим мышь X / Y следующим образом:

  function handleMouseDown(e){
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
}

Вот иллюстрирующий код и скрипка, который показывает, как успешно отслеживать события мыши на холсте:

http: //jsfiddle.net/m1erickson/WB7Zu/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    var canvasOffset=$("#canvas").offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;

    function handleMouseDown(e){
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
      $("#downlog").html("Down: "+ mouseX + " / " + mouseY);

      // Put your mousedown stuff here

    }

    function handleMouseUp(e){
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
      $("#uplog").html("Up: "+ mouseX + " / " + mouseY);

      // Put your mouseup stuff here
    }

    function handleMouseOut(e){
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
      $("#outlog").html("Out: "+ mouseX + " / " + mouseY);

      // Put your mouseOut stuff here
    }

    function handleMouseMove(e){
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
      $("#movelog").html("Move: "+ mouseX + " / " + mouseY);

      // Put your mousemove stuff here

    }

    $("#canvas").mousedown(function(e){handleMouseDown(e);});
    $("#canvas").mousemove(function(e){handleMouseMove(e);});
    $("#canvas").mouseup(function(e){handleMouseUp(e);});
    $("#canvas").mouseout(function(e){handleMouseOut(e);});

}); // end $(function(){});
</script>

</head>

<body>
    <p>Move, press and release the mouse</p>
    <p id="downlog">Down</p>
    <p id="movelog">Move</p>
    <p id="uplog">Up</p>
    <p id="outlog">Out</p>
    <canvas id="canvas" width=300 height=300></canvas>

</body>
</html>
3
ответ дан markE 3 September 2018 в 17:18
поделиться

Самый простой способ вычислить правильное перемещение мыши или позицию перемещения мыши на событии холста - использовать это небольшое уравнение:

canvas.addEventListener('click', event =>
{
    let bound = canvas.getBoundingClientRect();

    let x = event.clientX - bound.left - canvas.clientLeft;
    let y = event.clientY - bound.top - canvas.clientTop;

    context.fillRect(x, y, 16, 16);
});

Если холст имеет padding-left или padding-top, вычесть x и y через:

x -= parseFloat(style['padding-left'].replace('px')); y -= parseFloat(style['padding-top'].replace('px'));

1
ответ дан Martin Wantke 3 September 2018 в 17:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: