Source: js/plugins/ClampZoom.js

js/plugins/ClampZoom.js

import { Plugin } from './Plugin';
const DEFAULT_CLAMP_ZOOM_OPTIONS = {
    minWidth: null,
    minHeight: null,
    maxWidth: null,
    maxHeight: null,
    minScale: null,
    maxScale: null
};
/**
 * Plugin to clamp the viewport's zoom to a specific range.
 *
 * @public
 */
export class ClampZoom extends Plugin {
    /**
     * This is called by {@link Viewport.clampZoom}.
     */
    constructor(parent, options = {}) {
        super(parent);
        this.options = Object.assign({}, DEFAULT_CLAMP_ZOOM_OPTIONS, options);
        this.clamp();
    }
    resize() {
        this.clamp();
    }
    /** Clamp the viewport scale zoom) */
    clamp() {
        if (this.paused) {
            return;
        }
        if (this.options.minWidth || this.options.minHeight || this.options.maxWidth || this.options.maxHeight) {
            let width = this.parent.worldScreenWidth;
            let height = this.parent.worldScreenHeight;
            if (this.options.minWidth !== null && width < this.options.minWidth) {
                const original = this.parent.scale.x;
                this.parent.fitWidth(this.options.minWidth, false, false, true);
                this.parent.scale.y *= this.parent.scale.x / original;
                width = this.parent.worldScreenWidth;
                height = this.parent.worldScreenHeight;
                this.parent.emit('zoomed', { viewport: this.parent, type: 'clamp-zoom' });
            }
            if (this.options.maxWidth !== null && width > this.options.maxWidth) {
                const original = this.parent.scale.x;
                this.parent.fitWidth(this.options.maxWidth, false, false, true);
                this.parent.scale.y *= this.parent.scale.x / original;
                width = this.parent.worldScreenWidth;
                height = this.parent.worldScreenHeight;
                this.parent.emit('zoomed', { viewport: this.parent, type: 'clamp-zoom' });
            }
            if (this.options.minHeight !== null && height < this.options.minHeight) {
                const original = this.parent.scale.y;
                this.parent.fitHeight(this.options.minHeight, false, false, true);
                this.parent.scale.x *= this.parent.scale.y / original;
                width = this.parent.worldScreenWidth;
                height = this.parent.worldScreenHeight;
                this.parent.emit('zoomed', { viewport: this.parent, type: 'clamp-zoom' });
            }
            if (this.options.maxHeight !== null && height > this.options.maxHeight) {
                const original = this.parent.scale.y;
                this.parent.fitHeight(this.options.maxHeight, false, false, true);
                this.parent.scale.x *= this.parent.scale.y / original;
                this.parent.emit('zoomed', { viewport: this.parent, type: 'clamp-zoom' });
            }
        }
        else if (this.options.minScale || this.options.maxScale) {
            const minScale = { x: null, y: null };
            const maxScale = { x: null, y: null };
            if (typeof this.options.minScale === 'number') {
                minScale.x = this.options.minScale;
                minScale.y = this.options.minScale;
            }
            else if (this.options.minScale !== null) {
                const optsMinScale = this.options.minScale;
                minScale.x = typeof optsMinScale.x === 'undefined' ? null : optsMinScale.x;
                minScale.y = typeof optsMinScale.y === 'undefined' ? null : optsMinScale.y;
            }
            if (typeof this.options.maxScale === 'number') {
                maxScale.x = this.options.maxScale;
                maxScale.y = this.options.maxScale;
            }
            else if (this.options.maxScale !== null) {
                const optsMaxScale = this.options.maxScale;
                maxScale.x = typeof optsMaxScale.x === 'undefined' ? null : optsMaxScale.x;
                maxScale.y = typeof optsMaxScale.y === 'undefined' ? null : optsMaxScale.y;
            }
            let scaleX = this.parent.scale.x;
            let scaleY = this.parent.scale.y;
            if (minScale.x !== null && scaleX < minScale.x) {
                scaleX = minScale.x;
            }
            if (maxScale.x !== null && scaleX > maxScale.x) {
                scaleX = maxScale.x;
            }
            if (minScale.y !== null && scaleY < minScale.y) {
                scaleY = minScale.y;
            }
            if (maxScale.y !== null && scaleY > maxScale.y) {
                scaleY = maxScale.y;
            }
            if (scaleX !== this.parent.scale.x || scaleY !== this.parent.scale.y) {
                this.parent.scale.set(scaleX, scaleY);
                this.parent.emit('zoomed', { viewport: this.parent, type: 'clamp-zoom' });
            }
        }
    }
    reset() {
        this.clamp();
    }
}