Greasy Fork is available in English.

PromtEx

Un prompteur pour exposés

// ==UserScript==
// @name         PromtEx
// @namespace    http://tampermonkey.net/
// @version      7.2
// @description  Un prompteur pour exposés
// @author       yglsan
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Vitesse de défilement
    let scrollSpeed = 10; // Valeur initiale de la vitesse
    let isPaused = true; // État du défilement (pause ou démarrer)
    let scrollInterval = null; // Intervalle pour contrôler la vitesse du défilement
    let isMirrored = false; // État du miroir (inversé ou normal)

    // bouton flottant
    const button = document.createElement('button');
    button.innerText = 'PromtEx'; // Nom de l'application
    button.style.position = 'fixed';
    button.style.bottom = '20px';
    button.style.right = '20px';
    button.style.zIndex = '1000';
    button.style.padding = '15px';
    button.style.background = '#4A5568'; // Couleur professionnelle pour le bouton
    button.style.color = '#fff';
    button.style.border = 'none';
    button.style.borderRadius = '8px';
    button.style.fontSize = '18px';
    button.style.cursor = 'pointer';
    document.body.appendChild(button);

    // Overlay (prompteur)
    const teleprompterOverlay = document.createElement('div');
    teleprompterOverlay.style.position = 'fixed';
    teleprompterOverlay.style.top = '20px';
    teleprompterOverlay.style.left = '50%';
    teleprompterOverlay.style.transform = 'translateX(-50%)';
    teleprompterOverlay.style.width = '80%';
    teleprompterOverlay.style.height = '80%';
    teleprompterOverlay.style.backgroundColor = 'rgba(0, 0, 0, 0.9)';
    teleprompterOverlay.style.color = 'white';
    teleprompterOverlay.style.display = 'none';
    teleprompterOverlay.style.zIndex = '999';
    teleprompterOverlay.style.padding = '20px';
    teleprompterOverlay.style.overflow = 'hidden';
    document.body.appendChild(teleprompterOverlay);

    // Zone de texte
    const textArea = document.createElement('textarea');
    textArea.style.width = '100%';
    textArea.style.height = '90%';
    textArea.style.fontSize = '24px';
    textArea.style.lineHeight = '2.2';
    textArea.style.background = 'transparent';
    textArea.style.color = 'white';
    textArea.style.border = 'none';
    textArea.style.resize = 'none';
    textArea.style.outline = 'none';
    textArea.style.zIndex = '2';
    textArea.style.position = 'relative';
    textArea.style.textShadow = 'none';
    textArea.style.paddingTop = '300px';
    textArea.value = "Exposé ici...\n";  // Message de texte par défaut
    teleprompterOverlay.appendChild(textArea);

    // Barre orange (statique) 
    const highlightBar = document.createElement('div');
    highlightBar.style.position = 'absolute';
    highlightBar.style.width = '100%';
    highlightBar.style.height = '30px';
    highlightBar.style.backgroundColor = 'rgba(255, 165, 0, 0.5)'; // Couleur orange
    highlightBar.style.top = '50%';
    highlightBar.style.left = '0';
    highlightBar.style.zIndex = '1'; // Important pour l’interaction avec le texte blanc
    highlightBar.style.pointerEvents = 'none'; // Important pour la même raison
    teleprompterOverlay.appendChild(highlightBar);

    // Boutons de contrôle (fonction)
    const controls = document.createElement('div');
    controls.style.display = 'flex';
    controls.style.flexDirection = 'row';
    controls.style.justifyContent = 'space-between';
    controls.style.marginTop = '10px';
    controls.style.alignItems = 'center';

    const startPauseButton = createButton('Démarrer', 'gray', toggleStartPause);
    const rewindButton = createButton('Rembobiner', '#6c757d', resetScroll);
    const mirrorButton = createButton('Miroir', '#4682b4', toggleMirror);
    controls.appendChild(startPauseButton);
    controls.appendChild(rewindButton);
    controls.appendChild(mirrorButton);

    const speedSlider = createSpeedSlider();
    controls.appendChild(speedSlider);

    teleprompterOverlay.appendChild(controls);

    // Action du bouton principal
    button.onclick = () => {
        teleprompterOverlay.style.display = 'block';
        textArea.scrollTop = 0; // Rembobiner au début lorsque le prompteur s'affiche
    };

    // commencer le défilement du texte
    function startScrolling() {
        if (scrollInterval) return; // Ne pas démarrer un nouveau défilement si un est déjà en cours
        scrollInterval = setInterval(() => {
            if (!isPaused) {
                const highlightBarHeight = highlightBar.getBoundingClientRect().height;
                // Si la barre orange n'a pas encore dépassé la zone de texte
                if (textArea.scrollTop + textArea.clientHeight < textArea.scrollHeight - highlightBarHeight) {
                    textArea.scrollTop += 1; // Faire défiler le texte
                } else {
                    stopScrolling(); // Arrêter le défilement lorsque tout le texte a défilé
                }
            }
        }, 200 / scrollSpeed); // Vitesse de défilement ajustée en fonction de scrollSpeed
    }

    // Arrêt du défilement
    function stopScrolling() {
        clearInterval(scrollInterval);
        scrollInterval = null;
    }

    // Interrupteur démarrer/pause
    function toggleStartPause() {
        if (isPaused) {
            isPaused = false;
            startScrolling();
            startPauseButton.innerText = 'Pause';
            startPauseButton.style.background = '#ff6600';  // Couleur pour "Pause"
        } else {
            isPaused = true;
            stopScrolling();
            startPauseButton.innerText = 'Démarrer';
            startPauseButton.style.background = 'gray'; // Couleur pour "Démarrer"
        }
    }

    // Rembobiner (fonction)
    function resetScroll() {
        stopScrolling();
        textArea.scrollTop = 0;
        isPaused = true;
        startPauseButton.innerText = 'Démarrer';
        startPauseButton.style.background = 'gray'; // Réinitialiser l'état du bouton
    }

    // les boutons
    function createButton(text, color, action) {
        const btn = document.createElement('button');
        btn.innerText = text;
        btn.style.padding = '10px 15px';
        btn.style.background = color;
        btn.style.color = 'white';
        btn.style.border = 'none';
        btn.style.borderRadius = '5px';
        btn.style.cursor = 'pointer';
        btn.style.fontSize = '14px';
        btn.onclick = action;
        return btn;
    }

    // barre de sélection de vitesse
    function createSpeedSlider() {
        const slider = document.createElement('input');
        slider.type = 'range';
        slider.min = 1;
        slider.max = 20;
        slider.value = scrollSpeed;
        slider.style.width = '150px';
        slider.oninput = function() {
            scrollSpeed = slider.value;
            if (!isPaused) {
                stopScrolling();
                startScrolling();
            }
        };
        return slider;
    }

    // Activation /désactivation du miroir
    function toggleMirror() {
        isMirrored = !isMirrored;
        textArea.style.transform = isMirrored ? 'scaleX(-1)' : 'scaleX(1)';
    }

    // Contrôle de la vitesse avec les flèches du clavier
    window.addEventListener('keydown', (e) => {
        if (e.key === 'ArrowUp') {
            // Flèche haut - augmenter la vitesse
            if (scrollSpeed < 20) {
                scrollSpeed++;
                if (!isPaused) {
                    stopScrolling();
                    startScrolling();
                }
            }
        } else if (e.key === 'ArrowDown') {
            // Flèche bas - diminuer la vitesse
            if (scrollSpeed > 1) {
                scrollSpeed--;
                if (!isPaused) {
                    stopScrolling();
                    startScrolling();
                }
            }
        }
    });

})();