zoomTo(ratio, showTooltip = false, pivot = null, _originalEvent = null, _zoomable = false) {
    const {
      element,
      options,
      pointers,
      imageData,
    } = this;
    const {
      x,
      y,
      width,
      height,
      naturalWidth,
      naturalHeight,
    } = imageData;

    ratio = Math.max(0, ratio);

    if (isNumber(ratio) && this.viewed && !this.played && (_zoomable || options.zoomable)) {
      if (!_zoomable) {
        const minZoomRatio = Math.max(0.01, options.minZoomRatio);
        const maxZoomRatio = Math.min(100, options.maxZoomRatio);

        ratio = Math.min(Math.max(ratio, minZoomRatio), maxZoomRatio);
      }

      if (_originalEvent) {
        switch (_originalEvent.type) {
          case 'wheel':
            if (options.zoomRatio >= 0.055 && ratio > 0.95 && ratio < 1.05) {
              ratio = 1;
            }
            break;

          case 'pointermove':
          case 'touchmove':
          case 'mousemove':
            if (ratio > 0.99 && ratio < 1.01) {
              ratio = 1;
            }
            break;

          default:
        }
      }

      const newWidth = naturalWidth * ratio;
      const newHeight = naturalHeight * ratio;
      const offsetWidth = newWidth - width;
      const offsetHeight = newHeight - height;
      const oldRatio = imageData.ratio;

      if (isFunction(options.zoom)) {
        addListener(element, EVENT_ZOOM, options.zoom, {
          once: true,
        });
      }

      if (dispatchEvent(element, EVENT_ZOOM, {
        ratio,
        oldRatio,
        originalEvent: _originalEvent,
      }) === false) {
        return this;
      }

      this.zooming = true;

      if (_originalEvent) {
        const offset = getOffset(this.viewer);
        const center = pointers && Object.keys(pointers).length > 0
          ? getPointersCenter(pointers)
          : {
            pageX: _originalEvent.pageX,
            pageY: _originalEvent.pageY,
          };

        // Zoom from the triggering point of the event
        imageData.x -= offsetWidth * (((center.pageX - offset.left) - x) / width);
        imageData.y -= offsetHeight * (((center.pageY - offset.top) - y) / height);
      } else if (isPlainObject(pivot) && isNumber(pivot.x) && isNumber(pivot.y)) {
        imageData.x -= offsetWidth * ((pivot.x - x) / width);
        imageData.y -= offsetHeight * ((pivot.y - y) / height);
      } else {
        // Zoom from the center of the image
        imageData.x -= offsetWidth / 2;
        imageData.y -= offsetHeight / 2;
      }

      imageData.left = imageData.x;
      imageData.top = imageData.y;
      imageData.width = newWidth;
      imageData.height = newHeight;
      imageData.oldRatio = oldRatio;
      imageData.ratio = ratio;
      this.renderImage(() => {
        this.zooming = false;

        if (isFunction(options.zoomed)) {
          addListener(element, EVENT_ZOOMED, options.zoomed, {
            once: true,
          });
        }

        dispatchEvent(element, EVENT_ZOOMED, {
          ratio,
          oldRatio,
          originalEvent: _originalEvent,
        }, {
          cancelable: false,
        });
      });

      if (showTooltip) {
        this.tooltip();
      }
    }

    return this;
  }
Zoom the image to an absolute ratio.
@param {number} ratio - The target ratio.
@param {boolean} [showTooltip] - Indicates whether to show the tooltip.
@param {Object} [pivot] - The pivot point coordinate for zooming.
@param {Event} [_originalEvent=null] - The original event if any.
@param {Event} [_zoomable=false] - Indicates if the current zoom is available or not.
@returns {Viewer} this