Html getImageData элемента холста не соответствует содержимому Fabri cjs холста - PullRequest
0 голосов
/ 09 июля 2020

Я добавил fabri c Rect в (80, 80), а затем вызвал getImageData в этом месте. Однако данные, которые я получаю из этого места, не соответствуют Rect, который я там разместил. Вместо этого я нахожу данные в районе (60, 60).

var canvas = new fabric.Canvas('fabric-canvas');
canvas.setHeight(800);
canvas.setWidth(800);

var rect = new fabric.Rect({
  left: 80,
  top: 80,
  fill: 'red',
  width: 20,
  height: 20
});
canvas.add(rect);

// This doesn't work
let data = canvas.getContext('2d').getImageData(80, 80, 20, 20);
canvas.getContext('2d').putImageData(data, 0, 0);

// This "works"
data = canvas.getContext('2d').getImageData(60, 60, 20, 20);
canvas.getContext('2d').putImageData(data, 100, 0);

Вот демонстрация скрипки: https://jsfiddle.net/2wxdb8ua/13/

Как это возможно?

1 Ответ

0 голосов
/ 09 июля 2020

Проблема, безусловно, вызвана некоторым увеличением, либо из-за того, что ваш монитор является монитором с высоким разрешением (он же сетчатка), либо из-за того, что на странице применяется масштабирование браузера / ОС.

Вы можете либо сделать расчет самостоятельно world_coord * window.devicePixelRatio:

var canvas = new fabric.Canvas('fabric-canvas');
canvas.setHeight(800);
canvas.setWidth(800);

var rect = new fabric.Rect({
  left: 80,
  top: 80,
  fill: 'red',
  width: 20,
  height: 20
});

canvas.add(rect);

let ctx = canvas.getContext('2d').getImageData(...[80, 80, 20, 20].map(fixCoords));
canvas.getContext('2d').putImageData(ctx, ...[0, 0].map(fixCoords));

function fixCoords( coord ) {
  return coord * window.devicePixelRatio;
}
canvas#fabric-canvas {
  background: white;
  border: 2px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.1/fabric.min.js"></script>
<canvas id='fabric-canvas'></canvas>

Или отключите автоматическое масштабирование fabri c с помощью параметра enableRetinaScaling объекта initOptionObject :

var canvas = new fabric.Canvas('fabric-canvas', {
  enableRetinaScaling: false
});
canvas.setHeight(800);
canvas.setWidth(800);

var rect = new fabric.Rect({
  left: 80,
  top: 80,
  fill: 'red',
  width: 20,
  height: 20
});

canvas.add(rect);

let ctx = canvas.getContext('2d').getImageData(80, 80, 20, 20);
canvas.getContext('2d').putImageData(ctx, 0, 0);
canvas#fabric-canvas {
  background: white;
  border: 2px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.1/fabric.min.js"></script>
<canvas id='fabric-canvas'></canvas>

Но учтите, что с последним решением ваш холст наверняка станет размытым на мониторах с высоким разрешением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...