简体   繁体   中英

scale to a particular coordinate on HTML5 canvas (Fabric js)

i need to zoom to a particular coordinate(X,Y) on the canvas in fabrics js.

I know that there will be 2 functions being called 1. Scaled (x times) 2. Move the image to some x,y location so that the image appears to be at that coordinate.

Also i need that once zoomed in , i specify some other coordinate and it should zoom to that new coordinate. Any tips

You can define yourself a camera.

You have some absolute coordinate system and you want to project things from that system to the screen. That is done by the camera object. The camera has a position somewhere in your absolute coordinate system and it has a zoom factor and a rotation angle. The toScreen function takes absolute coordinates and translates them into coordinates on the screen. fromScreen does the opposite. moveBy is a relative move ie it moves in screen coordinates not absolute coordinates. That is useful for example if you have an image and you want it to follow your mouse pointer since the mouse pointer coordinates are screen coordinates. So you just calculate by how much the pointer moved and then call moveBy on the camera with the negative of those numbers. (negative because if a camera is moved left the image it produces moves right on the screen) Or lets say you click on a point on the screen and you then want the camera to zoom onto that point. Then you just say camera.moveBy(pointX, pointY) (where pointX/Y is the mouse position relative to the center of the screen ie the position of the camera since in screen coordinates the camera is always at position (0, 0)) and change the zoom factor if needed. btw. the "screen" here is of course your canvas. And pos (0,0) in screen coordinates should be the center of the canvas. So just to emphasize, the canvas is not your absolute coordinate system but the screen onto which the camera projects its image.

function Camera() {
  this.x = 0;
  this.y = 0;
  this.zoom = 1;
  this.angle = 0;
}

Camera.prototype.moveTo = function(x, y) {
  this.x = x; this.y = y;
};
Camera.prototype.moveBy = function(x, y) {
  var xy = this.fromScreen(x, y);
  this.moveTo(xy.x, xy.y);
};
Camera.prototype.rotateTo = function(angle) {
  while(angle < 0) angle += 360;
  angle %= 360;
  this.angle = angle;
};
Camera.prototype.rotateBy = function(angle) {
  this.rotateTo(this.angle + angle);
};
Camera.prototype.zoomTo = function(zoom) {
  this.zoom = zoom;
};
Camera.prototype.zoomBy = function(zoom) {
  this.zoom *= zoom;
};
Camera.prototype.toScreen = function(x, y) {
  x -= this.x; y -= this.y;
  if(this.angle !== 0) {
    var rad = Math.PI * this.angle / 180;
    rad = 2 * Math.PI - rad;
    var _x = x * Math.cos(rad) - y * Math.sin(rad),
        _y = x * Math.sin(rad) + y * Math.cos(rad);
    x = _x; y = _y;
  }
  return {x: x * this.zoom,
          y: y * this.zoom}
};
Camera.prototype.fromScreen = function(x, y) {
  x /= this.zoom;
  y /= this.zoom;
  if(this.angle !== 0) {
    var rad = Math.PI * this.angle / 180;
    var _x = x * Math.cos(rad) - y * Math.sin(rad),
        _y = x * Math.sin(rad) + y * Math.cos(rad);
    x = _x; y = _y;
  }
  x += this.x; y += this.y;
  return {x: x,
          y: y};
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM