gpt4 book ai didi

javascript - 缩放/平移后的 Canvas 坐标

转载 作者:行者123 更新时间:2023-11-30 15:57:33 25 4
gpt4 key购买 nike

我正在根据从 api 接收到的一些数据构建 Canvas,这一切都很好。无论如何,有几天我坚持使用以下代码`canvas.addEventListener('wheel', (event: MouseWheelEvent) => { event.preventDefault();

    let coords = Positioning.transformedPoint(
event.pageX - canvas.offsetLeft,
event.pageY - canvas.offsetTop
);

canvasMethods.clear();
canvasMethods.translate(coords.x, coords.y);

if (event.wheelDeltaY > 0) {
canvasMethods.scale(ZoomDirection.ZOOM_IN);
} else if (event.wheelDeltaY < 0) {
canvasMethods.scale(ZoomDirection.ZOOM_OUT);
}

canvasMethods.translate(-coords.x, -coords.y);

this._renderFn();
}, false);

canvas.addEventListener('mousedown', (event: MouseEvent) => {
event.preventDefault();

this._dragging = true;
this._dragStart = Positioning.transformedPoint(
event.clientX - canvas.offsetLeft,
event.clientY - canvas.offsetTop
);
}, false);

canvas.addEventListener('dblclick', (event: MouseEvent) => {
let coords = Positioning.transformedPoint(
event.clientX - canvas.offsetLeft,
event.clientY - canvas.offsetTop
);
this._clickFn(coords);
});

canvas.addEventListener('mousemove', (event: MouseEvent) => {
if (this._dragging) {
event.preventDefault();

this._dragEnd = Positioning.transformedPoint(
event.pageX - canvas.offsetLeft,
event.pageY - canvas.offsetTop
);

let coords = Positioning.transformedPoint(
event.clientX - canvas.offsetLeft,
event.clientY - canvas.offsetTop
);

canvasMethods.translate(coords.x - this._dragStart.x, coords.y - this._dragStart.y);
canvasMethods.clear();

this._renderFn();
this._dragStart = this._dragEnd;
}
}, false);

canvas.addEventListener('mouseup', (event: MouseEvent) => {
event.preventDefault();

this._dragging = false;
this._dragStart = null;
this._dragEnd = null;
})
}`

当它处于正常比例时,我得到了正确的坐标,但是当我缩放时,我得到了一个增量错误(基本上实际点和鼠标光标之间的距离越来越大),我不知道为什么。为了计算矩阵中的坐标,我按以下方式使用 SVG 方法作为包装器`export class Positioning { static svg = document.createElementNS(' http://www.w3.org/2000/svg ', 'svg'); private static xform = Positioning.svg.createSVGMatrix();

static transformedPoint(x: number, y: number): SVGPoint {
let coords = Positioning.svg.createSVGPoint();

coords.x = x;
coords.y = y;

return coords.matrixTransform(Positioning.xform.inverse());
}

}`

我知道这在某种程度上与缩放有关,但我真的不知道如何计算缩放比例并进行适当的操作以获得比例。我也检查了这个答案 Zoom Canvas to Mouse Cursor这是相当准确的,但实际上他以某种我无法重新认识的方式得到了它。其他人遇到过同样的问题吗?

最佳答案

我已经解决了这个问题,我忘记了一个重要的东西来跟踪我的转变。现在我将链接代码以供可能遇到我同样问题的人使用(如果您不使用 Typescript 可以避免输入 ofc)

基本上我使用 SVG 矩阵方法来追踪 Canvas 中发生的事情。

这是一个通过在自身中存储由 createSVGMatrix() 创建的未转换 Canvas (1,0,0,1,0,0) 的基本矩阵并通过 native SVGMatrix 方法跟踪转换来获取 Canvas 转换的类正在更新原始矩阵。然后,当我需要时,我只需使用转换点方法来恢复鼠标的正确 x、y 坐标,按比例缩放到矩阵。

export class Positioning {
static svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
static MatrixTransformationProxy = Positioning.svg.createSVGMatrix();

static transformedPoint(x: number, y: number): SVGPoint {
let coords = Positioning.svg.createSVGPoint();

coords.x = x;
coords.y = y;

return coords.matrixTransform(Positioning.MatrixTransformationProxy.inverse());
}

static translateProxy(x: number, y: number) {
Positioning.MatrixTransformationProxy = Positioning.MatrixTransformationProxy.translate(x, y);
}

static scaleUniformProxy(scaleValue: number) {
Positioning.MatrixTransformationProxy = Positioning.MatrixTransformationProxy.scale(scaleValue);
}

我使用调用 Canvas 方法和相对 Positioning 方法的 Canvas 方法包装器使我的 Canvas 转换与我的 ProxyMatrix 保持同步,像这样更新 MatrixTransformationProxy

export class CanvasMethods {
static getSharedInstance(): CanvasMethods {
return sharedInstance;
}

private _canvas: HTMLCanvasElement;

getCanvas(): HTMLCanvasElement {
return this._canvas;
}

getContext(): CanvasRenderingContext2D {
return this._canvas.getContext('2d');
}

registerCanvas(canvas: HTMLCanvasElement): void {
this._canvas = canvas;
}

getCanvasBoundingRect(): BoundingRect {
return new BoundingRect(0, 0, this._canvas.width, this._canvas.height);
}

clear(): void {
this.getContext().save();
this.getContext().setTransform(1, 0, 0, 1, 0, 0);
this.getContext().clearRect(0, 0, this._canvas.width, this._canvas.height);
this.getContext().restore();
}

scale(direction: ZoomDirection): void {
let options = { //TODO get this from constructor options
scaleValueOut: 0.8,
scaleValueIn: 1.1
};

if (direction === ZoomDirection.ZOOM_OUT) {
Positioning.scaleUniformProxy(options.scaleValueOut);
this.getContext().scale(options.scaleValueOut, options.scaleValueOut);
} else if (direction === ZoomDirection.ZOOM_IN) {
Positioning.scaleUniformProxy(options.scaleValueIn);
this.getContext().scale(options.scaleValueIn, options.scaleValueIn);
}
}

translate(x: number, y: number): void {
Positioning.translateProxy(x, y);
this.getContext().translate(x, y);
}

const sharedInstance = new CanvasMethods();

关于javascript - 缩放/平移后的 Canvas 坐标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38269925/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com