Точность шкалы SVG Matrix - PullRequest
0 голосов
/ 02 ноября 2018

Здравствуйте, я использую SVGMatrix для одного проекта, который включает scalling.

Проблема в том, что матрица теряет разрешение.

Предполагая, что мы находимся в 100% и уменьшаем 5 раз (независимо от значения увеличения) и увеличиваем 5 раз, компоненты a и d матрицы не будут равны 1.

Это реальная проблема или я делаю что-то не так. Пожалуйста, смотрите код внутри. Я использую 0,01 в качестве коэффициента масштабирования, чтобы минимизировать потерю точности.

Также, как вы можете видеть, я также рассмотрел DOMMatrix на примере. Делать то же самое.

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

var plusBtn = document.getElementById("plus");
var minusBtn = document.getElementById("minus");
var infoP = document.getElementById("info");

var zoom;
var scale = 1;
const scaleFactor = 0.01;

function draw() {
	ctx.clearRect(0, 0, canvas.width, canvas.height);
	ctx.setTransform(currMatrix)
	ctx.fillStyle = "blue";
	ctx.fillRect(50, 50, 100, 100);
  console.log(currMatrix)
}
draw()

function getDomPoint(event) {
	const offSetCanvasLeft = canvas.getBoundingClientRect().left;
  const offSetCanvasTop = canvas.getBoundingClientRect().top;

	return {
    x: event.pageX - offSetCanvasLeft,
    y: event.pageY - offSetCanvasTop,
  }
}

function domToCanvasPoint(point) {
	const domPoint = new window.DOMPoint(point.x, point.y);
	return domPoint.matrixTransform(currMatrix);
}

function domToCanvasPointSVG(point) {
	var svg = document.createElementNS("http://www.w3.org/2000/svg",'svg');
  var pt  = svg.createSVGPoint();
  pt.x = point.x;
  pt.y = point.y;
	var matrice = svg.createSVGMatrix();
  matrice.a = currMatrix.a;
  matrice.b = currMatrix.b;
  matrice.c = currMatrix.c;
  matrice.d = currMatrix.d;
  matrice.e = currMatrix.e;
  matrice.f = currMatrix.f;
	return pt.matrixTransform(matrice.inverse());
}

function updateScale() {
  scale = zoom === 'in' ? 1 + scaleFactor : 1 - scaleFactor ;
  setDebugInfo(scale)
}

function zoomMatrixIntoPoint(point) {
	currMatrix = currMatrix
    .translateSelf(point.x, point.y)
    .scaleSelf(scale, scale)
    .translateSelf(-point.x, -point.y);
}

function zoomMatrixIntoPointSVG(point) {
	var svg = document.createElementNS("http://www.w3.org/2000/svg",'svg');
  var pt  = svg.createSVGPoint();
	var matrice = svg.createSVGMatrix();
  matrice.a = currMatrix.a;
  matrice.b = currMatrix.b;
  matrice.c = currMatrix.c;
  matrice.d = currMatrix.d;
  matrice.e = currMatrix.e;
  matrice.f = currMatrix.f;
	currMatrix = matrice
    .translate(point.x, point.y)
    .scale(scale, scale)
    .translate(-point.x, -point.y);
}

function setDebugInfo(msg) {
	infoP.innerHTML = msg;
}

function drawUsingDomMatrix(domPoint) {
  const canvasPoint = domToCanvasPoint(domPoint);
  updateScale();
  zoomMatrixIntoPoint(canvasPoint);
}

function drawUsingSvgMatrix(domPoint) {
  const canvasPoint = domToCanvasPointSVG(domPoint);
  updateScale();
  zoomMatrixIntoPointSVG(canvasPoint);
}

canvas.addEventListener('mousedown', function(event) {  
	const domPoint = getDomPoint(event);
	//drawUsingDomMatrix(domPoint)
	drawUsingSvgMatrix(domPoint)
  draw()
}, false);

plusBtn.addEventListener('click', function(event) {    
	zoom = 'in'
  setDebugInfo(`ZOOM IN with scale ${scale}`)
}, false);

minusBtn.addEventListener('click', function(event) {    
	zoom = 'out'
  setDebugInfo(`ZOOM OUT with scale ${scale}`)
}, false);
<canvas id="myCanvas" width="300" height="300" style="border:1px solid black"></canvas>
<button id="plus">+</button>
<button id="minus">-</button>
<p id="info">info here!</p>

Большое спасибо.

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