缩放/平移后的画布坐标
Canvas Coordinate after scaling/Panning
我正在通过从 API 接收的一些数据构建画布,这一切都很好。无论如何,几天后我被以下代码'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 方法作为包装器,方式如下 ' 导出类定位 { static svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); 私有静态 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());
}
}'
我知道这在某种程度上与结垢有关,但我真的不知道如何获得缩放的帐户并进行适当的操作来获得比例。我还检查了这个答案 缩放画布到鼠标光标 这是非常准确的,但实际上他以某种方式得到了我无法识别的帐户。其他人是否遇到过同样的问题?
解决了这个问题,我忘记了一件重要的事情,跟踪我的转变。现在我将链接代码,以便对可能遇到我相同问题的人有用(如果您不使用 Typescript 可以避免键入 ofc)
基本上,我正在使用SVG矩阵方法来跟踪画布中发生的事情。
这是一个类,它通过自身存储由createSVGMatrix()创建的未转换画布(1,0,0,1,0,0)的基本矩阵并通过更新原始矩阵的本机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);
}
}
我正在使用画布方法的包装器将画布转换与我的代理矩阵同步,这些方法调用画布方法和相对定位方法来更新矩阵转换代理,如下所示
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();}
- EaseJS拖放;放下(动画CC)电影剪辑的鼠标坐标
- 如何在d3.js中返回路径的y坐标
- 在谷歌地图上获取事件的x,y坐标
- 通过ajax将坐标传递到php服务器端,并在处理后检索到javascript
- 当带有渲染器的DOM元素不在屏幕顶部时,移动了场景的坐标
- 如何在JS Leatflet绘图插件中获取圆的坐标
- 点击(右键点击)使用传单地图库获取图像覆盖的像素坐标
- 查找带有边框的HTML5 Canvas(点击)事件的坐标
- HTML5获取弧的坐标's结束
- 如何在OpenLayers中获取动态绘制的多边形的坐标
- 获取用户位置并将坐标保存在数据库中
- fabric js多边形集合坐标
- 使用D3.js和GeoJson在地图上的某些坐标上设置一个小图像
- 如何创建一个谷歌地图地理坐标数组
- AngularJS-如何在mousemove上存储鼠标坐标
- 使用地理坐标,对更靠近用户的对象进行排序'的位置
- 在坐标上模拟点击坐标js/jQuery
- ChartJS v2:点击坐标的比例值(时间比例)
- 通过鼠标点击获取X和Y坐标(javascript)
- 使用jQuery获取用户坐标