Javascript 缩放/平移后的画布坐标

Javascript 缩放/平移后的画布坐标,javascript,html,canvas,Javascript,Html,Canvas,我正在通过从api接收的一些数据构建画布,这一切都很好。有几天我被以下代码“canvas.addEventListener('wheel',(event:mouseweelEvent)=>{ event.preventDefault() }` 我知道这与缩放有关,但我真的不知道如何计算缩放比例,如何进行适当的操作以获得比例。我也检查了这个答案,答案非常准确,但实际上他以某种方式得到了解释,我无法再确认。是否有其他人也面临同样的问题?我已经解决了问题问题,我忘记了一个重要的东西,跟踪我的转换。现在

我正在通过从api接收的一些数据构建画布,这一切都很好。有几天我被以下代码“canvas.addEventListener('wheel',(event:mouseweelEvent)=>{ event.preventDefault()

}`


我知道这与缩放有关,但我真的不知道如何计算缩放比例,如何进行适当的操作以获得比例。我也检查了这个答案,答案非常准确,但实际上他以某种方式得到了解释,我无法再确认。是否有其他人也面临同样的问题?

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

基本上,我使用SVG矩阵方法来跟踪画布中发生的事情

这是一个类,该类通过将createSVGMatrix()创建的未转换画布(1,0,0,1,0,0)的基本矩阵存储在其自身中来获得画布转换的说明并通过更新原始矩阵的本机SVGMatrix方法跟踪变换。然后,当我需要时,我只需使用变换点方法,使鼠标的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);
}
}

我使用画布包装器方法将画布转换与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=新的CanvasMethods();
}

你的想法是正确的:将所有变换通过a进行路由,然后使用矩阵在变换坐标和未变换坐标之间进行转换。是的,我离得很近,但我无法理解谜题的最后一部分,你所说的将矩阵反转以在变换坐标和未变换坐标之间进行转换是什么意思?因为你可以看到我的服务e已经反转了矩阵。
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);
}