Кусок кода из моего проекта на react. Там используется svg, но не суть. Вам помимо scale, нужно делать еще и скролл - translate
/**
* Зум холста, с центровкой в указанную точку
* @param {Number} zoom величина увеличения
* @param {Number} centerX x центра фокусировки увеличения
* @param {Number} centerY y центра фокусировки увеличения
*/
zoomTo(zoom, centerX, centerY) {
const oldZoom = this.state.zoom;
// находим, насколько изменится размер блока. this.state.canvas.width это ширина блока, а height высота.
const canvWidth = this.state.canvas.width;
const canvHeight = this.state.canvas.height;
const moreWidth = canvWidth * zoom - canvWidth * oldZoom;
const moreHeight = canvHeight * zoom -canvHeight * oldZoom;
// находим смещение translate
const newScrollX = -moreWidth / (canvWidth / centerX);
const newScrollY = -moreHeight / (canvHeight / centerY);
if (zoom > 0.05) {
this.setState({
scrollX: this.state.scrollX + newScrollX, // это translate x
scrollY: this.state.scrollY + newScrollY, // это translate y
zoom: Math.max(0.01, zoom) // это scale
});
}
}