Edit in JSFiddle

//=============================================================================
// Sphinx-SpinnerScene.js
//=============================================================================

/*:
 * @plugindesc Scène de démonstration du plugin Sphinx-Chart2
 * @author Sphinx
 *
 * @help
 * //==========================================================================
 * // Plugin : Sphinx-SpinnerScene
 * // Date   : 9 janvier 2020
 * // Auteur : Sphinx
 * //==========================================================================
 * 
 * Dépendances :
 *     - Sphinx-Spinner
 * @param background
 * @text Image d'arrière plan de la scène
 * @type file
 * @dir img/titles1/
 * @require 1
 */
SPINNER_TYPES = [ "basique", "texte", "icones", "mixte" ]
CSS_COLORS = [ "AliceBlue", "AntiqueWhite", "Aqua", "Aquamarine", "Azure", "Beige", "Bisque", "Black", "BlanchedAlmond", "Blue", "BlueViolet", "Brown", "BurlyWood", "CadetBlue", "Chartreuse", "Chocolate", "Coral", "CornflowerBlue", "Cornsilk", "Crimson", "Cyan", "DarkBlue", "DarkCyan", "DarkGoldenRod", "DarkGray", "DarkGrey", "DarkGreen", "DarkKhaki", "DarkMagenta", "DarkOliveGreen", "DarkOrange", "DarkOrchid", "DarkRed", "DarkSalmon", "DarkSeaGreen", "DarkSlateBlue", "DarkSlateGray", "DarkSlateGrey", "DarkTurquoise", "DarkViolet", "DeepPink", "DeepSkyBlue", "DimGray", "DimGrey", "DodgerBlue", "FireBrick", "FloralWhite", "ForestGreen", "Fuchsia", "Gainsboro", "GhostWhite", "Gold", "GoldenRod", "Gray", "Grey", "Green", "GreenYellow", "HoneyDew", "HotPink", "IndianRed", "Indigo", "Ivory", "Khaki", "Lavender", "LavenderBlush", "LawnGreen", "LemonChiffon", "LightBlue", "LightCoral", "LightCyan", "LightGoldenRodYellow", "LightGray", "LightGrey", "LightGreen", "LightPink", "LightSalmon", "LightSeaGreen", "LightSkyBlue", "LightSlateGray", "LightSlateGrey", "LightSteelBlue", "LightYellow", "Lime", "LimeGreen", "Linen", "Magenta", "Maroon", "MediumAquaMarine", "MediumBlue", "MediumOrchid", "MediumPurple", "MediumSeaGreen", "MediumSlateBlue", "MediumSpringGreen", "MediumTurquoise", "MediumVioletRed", "MidnightBlue", "MintCream", "MistyRose", "Moccasin", "NavajoWhite", "Navy", "OldLace", "Olive", "OliveDrab", "Orange", "OrangeRed", "Orchid", "PaleGoldenRod", "PaleGreen", "PaleTurquoise", "PaleVioletRed", "PapayaWhip", "PeachPuff", "Peru", "Pink", "Plum", "PowderBlue", "Purple", "RebeccaPurple", "Red", "RosyBrown", "RoyalBlue", "SaddleBrown", "Salmon", "SandyBrown", "SeaGreen", "SeaShell", "Sienna", "Silver", "SkyBlue", "SlateBlue", "SlateGray", "SlateGrey", "Snow", "SpringGreen", "SteelBlue", "Tan", "Teal", "Thistle", "Tomato", "Turquoise", "Violet", "Wheat", "White", "WhiteSmoke", "Yellow", "YellowGreen" ];

//-----------------------------------------------------------------------------
// Game_Interpreter
//
// Commandes de plugin
Sphinx_Chart_Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
    Sphinx_Chart_Game_Interpreter_pluginCommand.call(this, command, args);
    if(command === "START_SPINNER_SCENE") {
        SceneManager.push(Scene_Spinner);
    }
};

//-----------------------------------------------------------------------------
// Scene_Spinner
//
// Scène de démonstration du plugin Sphinx-Chart2
function Scene_Spinner() {
    this.initialize.apply(this, arguments);
};

Scene_Spinner.prototype = Object.create(Scene_Base.prototype);
Scene_Spinner.prototype.constructor = Scene_Spinner;

Scene_Spinner.prototype.initialize = function() {
    Scene_Base.prototype.initialize.call(this);
};

Scene_Spinner.prototype.create = function() {
    Scene_Base.prototype.create.call(this);
    this.spinners = [];
    this.valueSprites = [];
    this.intervals = [];
    this.createWindowLayer();
    this.createBackground();
    this.createWindows();
    this.createTexts();
};

Scene_Spinner.prototype.start = function() {
    Scene_Base.prototype.start.call(this);
    this.startFadeIn(this.fadeSpeed(), false);
    this._windowTypeSpinner.open();
};

Scene_Spinner.prototype.terminate = function() {
    Scene_Base.prototype.terminate.call(this);
    SceneManager.goto(Scene_Map);
    this.startFadeOut(this.fadeSpeed(), false);
};

Scene_Spinner.prototype.update = function() {
    Scene_Base.prototype.update.call(this);
    busy = false;
    for(spinner of this.spinners) {
        if(!spinner.isStopped()) busy = true;
    }
    for(valueSprite of this.valueSprites) {
        if(valueSprite instanceof Sprite_Base && valueSprite.scale.x > 0) busy = true;
    }
    if(busy) {
        if(this._windowTypeSpinner.active) this._windowTypeSpinner.deactivate();
    }
    else {
        if(!this._windowTypeSpinner.active && !this._windowChooseSpinnerType.active) this._windowTypeSpinner.activate();
    }
    if(Input.isTriggered("cancel")) {
        SoundManager.playCancel();
        this.terminate();
    }
};

Scene_Spinner.prototype.createBackground = function() {
    this._background = new Sprite_Base();
    background = PluginManager.parameters("Sphinx-SpinnerScene")["background"];
    this._background.bitmap = ImageManager.loadTitle1(background);
    this.addChildAt(this._background, 0);
};

Scene_Spinner.prototype.createWindows = function() {
    this._windowTypeSpinner = new Window_TypeSpinner();
    for(type of SPINNER_TYPES) {
        this._windowTypeSpinner.setHandler("spin_" + type, this.chooseType.bind(this, type));
    }
    this.addWindow(this._windowTypeSpinner);
    
    this._windowChooseSpinnerType = new Window_ChooseItemNumber();
    for(i = 2; i <= 20; ++i) {
        this._windowChooseSpinnerType.setHandler("choose_" + i, this.chooseItemsCount.bind(this, i));
    }
    this.addWindow(this._windowChooseSpinnerType);
};

Scene_Spinner.prototype.createTexts = function() {
    this._titleText = new Sprite_Base();
    this._titleText.x = 0;
    this._titleText.y = 0;
    this._titleText.width = Graphics.boxWidth;
    this._titleText.height = 64;
    this._titleText.bitmap = new Bitmap(Graphics.boxWidth, 64);
    this._titleText.bitmap.fontSize = 28;
    this._titleText.bitmap.drawText("Démonstration - Sphinx-Spinner", 0, 16, Graphics.boxWidth - 32, 64, "center");
    this.addChildAt(this._titleText, 1);
    
    this._explicationText1 = new Sprite_Base();
    this._explicationText1.x = 0;
    this._explicationText1.y = Graphics.boxHeight - ((Graphics.boxHeight - 480) / 2);
    this._explicationText1.width = Graphics.boxWidth;
    this._explicationText1.height = (Graphics.boxHeight - 480) / 4;
    this._explicationText1.bitmap = new Bitmap(Graphics.boxWidth, (Graphics.boxHeight - 480) / 4);
    this._explicationText1.bitmap.fontSize = 18;
    this._explicationText1.bitmap.drawText("Choisissez un type de spinner, puis le nombre d'items.", 0, 8, Graphics.boxWidth - 32, 20, "center");
    this.addChildAt(this._explicationText1, 2);
    
    this._explicationText2 = new Sprite_Base();
    this._explicationText2.x = 0;
    this._explicationText2.y = Graphics.boxHeight - ((Graphics.boxHeight - 480) / 4);
    this._explicationText2.width = Graphics.boxWidth;
    this._explicationText2.height = (Graphics.boxHeight - 480) / 4;
    this._explicationText2.bitmap = new Bitmap(Graphics.boxWidth, (Graphics.boxHeight - 480) / 4);
    this._explicationText2.bitmap.fontSize = 18;
    this._explicationText2.bitmap.drawText("Pour arrêter le spinner, cliquez dessus.", 0, 8, Graphics.boxWidth - 32, 20, "center");
    this.addChildAt(this._explicationText2, 3);
};

Scene_Spinner.prototype.chooseType = function(type) {
    this.type = type;
    this._windowChooseSpinnerType.open();
    this._windowChooseSpinnerType.activate();
}

Scene_Spinner.prototype.chooseItemsCount = function(count) {
    this._windowChooseSpinnerType.close();
    if(this.spinners) {
        for(spinner of this.spinners) {
            spinner.destroy();
        }
    }
    this.spinners = [];
    if(this.valueSprites) {
        for(valueSprite of this.valueSprites) {
            if(valueSprite instanceof Sprite_Base) valueSprite.destroy();
        }
    }
    this.valueSprites = [];
    this.spinnerValues = [];
    this.intervals = [];
    spinnerCount = Math.randomIntBetween(1, 1);
    for(n = 1; n <= spinnerCount; ++n) {
        switch(spinnerCount) {
            case 1:
                width = 640;
                height = 480;
                coords = [
                    { x: 166 + width / 2, y: 64 + height / 2 }
                ];
                break;
            case 2:
                width = 304;
                height = 480;
                coords = [
                    { x: 166 + width / 2, y: 64 + height / 2 },
                    { x: 166 + width + 16 + width / 2, y: 64 + height / 2 }
                ];
                break;
            case 3:
                width = 304;
                height = 240;
                coords = [
                    { x: 166 + width / 2, y: 64 + height / 2 },
                    { x: 166 + width + 16 + width / 2, y: 64 + height / 2 },
                    { x: 166 + width / 2 + 8 + width / 2, y: 64 + height + height / 2 }
                ];
                break;
            case 4:
                width = 304;
                height = 240;
                coords = [
                    { x: 166 + width / 2, y: 64 + height / 2 },
                    { x: 166 + width + 16 + width / 2, y: 64 + height / 2 },
                    { x: 166 + width / 2, y: 64 + height + height / 2 },
                    { x: 166 + width + 16 + width / 2, y: 64 + height + height / 2 }
                ];
                break;
            case 5:
                width = 197.33333;
                height = 240;
                coords = [
                    { x: 166 + width / 2, y: 64 + height / 2 },
                    { x: 166 + width + 16 + width / 2, y: 64 + height / 2 },
                    { x: 166 + (width + 16) * 2 + width / 2, y: 64 + height / 2 },
                    { x: 166 + width / 2 + width / 2, y: 64 + height + height / 2 },
                    { x: 166 + width + 16 + width / 2 + width / 2, y: 64 + height + height / 2 },
                ];
                break;
            case 6:
                width = 197.33333;
                height = 240;
                coords = [
                    { x: 166 + width / 2, y: 64 + height / 2 },
                    { x: 166 + width + 16 + width / 2, y: 64 + height / 2 },
                    { x: 166 + (width + 16) * 2 + width / 2, y: 64 + height / 2 },
                    { x: 166 + width / 2, y: 64 + height + height / 2 },
                    { x: 166 + width + 16 + width / 2, y: 64 + height + height / 2 },
                    { x: 166 + (width + 16) * 2 + width / 2, y: 64 + height + height / 2 },
                ];
                break;
        }
        this.spinnerValues[n] = this.getValues(count);
        spinner = new SphinxSpinner({
            width: width,
            height: height,
            values: this.spinnerValues[n],
            colors: this.getColors(),
        });
        spinner.x = coords[n - 1].x,
        spinner.y = coords[n - 1].y;
        spinner.setStopHandler(((n, spinner) => {
            this.drawValue(n, spinner);
            this.intervals[n] = setInterval(() => {
                spinnerHidden = false;
                valueDisplayed = false;
                spinner.scale.x /= 1.075;
                spinner.scale.y /= 1.075;
                this.valueSprites[n].scale.x *= 1.2;
                this.valueSprites[n].scale.y *= 1.2;
                if(this.valueSprites[n].scale.x >= 0.95 && this.valueSprites[n].scale.y >= 0.95) {
                    valueDisplayed = true;
                    this.valueSprites[n].scale.x = 1;
                    this.valueSprites[n].scale.y = 1;
                }
                if(spinner.scale.x <= 0.01 || spinner.scale.y <= 0.01) {
                    spinner.scale.x = 0;
                    spinner.scale.y = 0;
                    spinnerHidden = true;
                }
                if(valueDisplayed && spinnerHidden) {
                    setTimeout(() => {
                        this.intervals[this.spinners.length + n] = setInterval(() => {
                            this.valueSprites[n].scale.x /= 1.2;
                            this.valueSprites[n].scale.y /= 1.2;
                            if(this.valueSprites[n].scale.x <= 0.01 && this.valueSprites[n].scale.y <= 0.01) {
                                this.valueSprites[n].scale.x = 0;
                                this.valueSprites[n].scale.y = 0;
                                clearInterval(this.intervals[this.spinners.length + n]);
                            }
                        }, 1000 / 60);
                    }, 2500);
                    clearInterval(this.intervals[n]);
                }
            }, 1000 / 60);
        }).bind(this, n, spinner));
        this.spinners.push(spinner);
    }
    for(i = 0; i < this.spinners.length; ++i) {
        this.addChildAt(this.spinners[i], 4 + i);
    }
};

Scene_Spinner.prototype.getValues = function(count) {
    values = [];
    iconIds = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 ];
    for(c = 1; c <= count; ++c) {
        switch(this.type) {
            case "basique":
                values.push(c);
                break;
            case "texte":
                values.push(CSS_COLORS[Math.randomIntBetween(0, CSS_COLORS.length)]);
                break;
            case "icones":
                i = Math.randomIntBetween(0, iconIds.length);
                bitmap = SphinxSpinner.getIcon(iconIds.splice(i, 1));
                values.push(bitmap);
                break;
            case "mixte":
                switch(Math.randomIntBetween(1, 4)) {
                    case 1:
                        values.push(c);
                        break;
                    case 2:
                        values.push(CSS_COLORS[Math.randomIntBetween(0, CSS_COLORS.length)]);
                        break;
                    case 3:
                        i = Math.randomIntBetween(0, iconIds.length);
                        bitmap = SphinxSpinner.getIcon(iconIds.splice(i, 1));
                        values.push(bitmap);
                        break;
                }
                break;
        }
    }
    return values;
};

Scene_Spinner.prototype.getColors = function() {
    colors = [];
    for(c = 1; c <= Math.randomIntBetween(2, 10); ++c) {
        do {
            color = CSS_COLORS[Math.randomIntBetween(0, CSS_COLORS.length)];
        } while(colors.includes(color));
        colors.push(color);
    }
    return colors;
};

Scene_Spinner.prototype.drawValue = function(n, spinner) {
    valueSprite = new Sprite_Base();
    valueSprite.y = spinner.y;
    valueSprite.x = spinner.x;
    valueSprite.anchor.x = 0.5;
    valueSprite.anchor.y = 0.5;
    valueSprite.scale.x = 0.01;
    valueSprite.scale.y = 0.01;
    if(this.spinnerValues[n][spinner.value] instanceof Bitmap) {
        valueSprite.bitmap = new Bitmap(256, 256);
        valueSprite.bitmap.blt(this.spinnerValues[n][spinner.value], 0, 0, this.spinnerValues[n][spinner.value].width, this.spinnerValues[n][spinner.value].height, 0, 0, valueSprite.width, valueSprite. height);
    } else {
        fontSize = 112;
        valueSprite.bitmap = new Bitmap(spinner.width, 256);
        valueSprite.bitmap.fontSize = fontSize;
        while(valueSprite.bitmap.measureTextWidth(this.spinnerValues[n][spinner.value].toString()) > spinner.width) {
            fontSize--;
            valueSprite.bitmap.fontSize = fontSize;
        }
        valueSprite.bitmap.drawText(this.spinnerValues[n][spinner.value], 0, 0, spinner.width, 256, "center");
    }
    this.addChildAt(valueSprite, this.children.length);
    this.valueSprites[n] = valueSprite;
};

Scene_Spinner.prototype.fastForwardRate = function() {
    return 3;
};

Scene_Spinner.prototype.isFastForward = function() {
    return (Input.isPressed('ok') || Input.isPressed('shift') || TouchInput.isPressed());
};

Scene_Spinner.prototype.updateFade = function() {
    if(this._fadeDuration > 0) {
        var d = this._fadeDuration;
        if(this.isFastForward()) {
            d -= this.fastForwardRate() - 1;
            this._fadeDuration -= this.fastForwardRate();
        } else {
            this._fadeDuration--;
        }
        if(this._fadeSign > 0) {
            this._fadeSprite.opacity -= this._fadeSprite.opacity / d;
        } else {
            this._fadeSprite.opacity += (255 - this._fadeSprite.opacity) / d;
        }
    }
};

Scene_Spinner.prototype.fadeSpeed = function(ignoreFast) {
    return 30;
};

//-----------------------------------------------------------------------------
// Window_TypeSpinner
//
// Fenêtre de sélection du type du graphique

function Window_TypeSpinner() {
    this.initialize.apply(this, arguments);
};

Window_TypeSpinner.prototype = Object.create(Window_Command.prototype);
Window_TypeSpinner.prototype.constructor = Window_TypeSpinner;

Window_TypeSpinner.prototype.initialize = function() {
    Window_Command.prototype.initialize.call(this, 0, 0);
    this.updatePlacement();
};

Window_TypeSpinner.prototype.windowWidth = function() {
    return 150;
};

Window_TypeSpinner.prototype.updatePlacement = function() {
    this.x = 8;
    this.y = (Graphics.boxHeight - this.height) / 2;
};

Window_TypeSpinner.prototype.makeCommandList = function() {
    for(type of SPINNER_TYPES) {
        this.addCommand(type.capitalize(), "spin_" + type);
    }
};

Window_TypeSpinner.prototype.isContinueEnabled = function() {
    return DataManager.isAnySavefileExists();
};

//-----------------------------------------------------------------------------
// Window_ChooseItemNumber
//
// Fenêtre de sélection du type d'accélération

function Window_ChooseItemNumber() {
    this.initialize.apply(this, arguments);
};

Window_ChooseItemNumber.prototype = Object.create(Window_Command.prototype);
Window_ChooseItemNumber.prototype.constructor = Window_ChooseItemNumber;

Window_ChooseItemNumber.prototype.initialize = function() {
    Window_Command.prototype.initialize.call(this, 0, 0);
    this.close();
    this.updatePlacement();
};

Window_ChooseItemNumber.prototype.maxCols = function() {
    return 5;
};

Window_ChooseItemNumber.prototype.windowWidth = function() {
    return Graphics.boxWidth - 64;
};

Window_ChooseItemNumber.prototype.updatePlacement = function() {
    this.x = (Graphics.boxWidth - this.width) / 2;
    this.y = (Graphics.boxHeight - this.height) / 2;
};

Window_ChooseItemNumber.prototype.makeCommandList = function() {
    for(i = 2; i <= 20; ++i) {
        this.addCommand(i.toString(), "choose_" + i);
    }
};