Здравствуйте, я использую 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>
Большое спасибо.