公演配信時、開演前の画面に表示する時計をリファインして公開

Javascript

公演の配信時、開演前の間は画面の隅っこに日時を表示しています。これはHTMLとJavascriptで書いてひとつのhtmlファイルに収めたものをローカルに置き、OBS(配信ソフト)の「ブラウザ」ソースで読み込んで表示させています。
右は、3年前にYoutubeに乗せた開演前映像のサンプルです。いまはさらに進化しています。

この右下の日時表示部分をリファインしました。

公演に限らず、配信全般で使えると思います。


最初はhtmlファイルにCDNライブラリでReactやBabelなどを引っ張り込み、Reactが動くようにして書きました。その後、AI(Gemini)にCDNライブラリ関連のものを取っ払わせて、完全に単体で動くようにしました。この手順、はやい。ただ最初からJavascriptだけで書けばもっとすっきりしそう。今回はまぁいいか。

以下のコードをコピーし(右上にCopyボタンもあるはず)、OBSからアクセス可能などこかのフォルダにhtmlファイル(たとえばclock.html)を作ってペースト。あとはOBSのブラウザソースで読み込むだけです。

カスタマイズ手順はコードのあとに書きます。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Clock</title>

    <!-- Google Fonts -->
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=BIZ+UDPGothic:wght@400;700&family=Noto+Sans+JP:wght@700&family=Orbitron:wght@700&family=Share+Tech+Mono&display=swap" rel="stylesheet">

    <style>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }
        body {
            margin: 0;
            padding: 0;
            min-height: 100vh;
            background-color: transparent;
            user-select: none;
            overflow: hidden;
        }
        .container {
            width: 100%;
            display: flex;
            flex-direction: column;
            align-items: center;
        }
        .text-container {
            white-space: nowrap;
            display: inline-block;
            line-height: 0.9;
            margin: 0;
            padding: 0;
        }
    </style>
</head>
<body>

<div id="container" class="container">
    <div id="time" class="text-container"></div>
    <div id="date" class="text-container"></div>
    <div id="label" class="text-container"></div>
</div>

<script>
    //
    // 設定
    //
    const CONFIG = {
        // フォント設定
        FONT: {
            // 表示に使用するフォント
            // ※head内のGoogle Fontsの項で読み込みが必用
            FAMILY: {
                TIME: "'Orbitron', sans-serif",         // 時刻
                DATE: "'Noto Sans JP', sans-serif",     // 日付
                LABEL: "'BIZ UDPGothic', sans-serif"    // ラベル
            },
            // フォントの太さ
            // ※ロードしたフォント次第
            WEIGHT: {
                TIME: 700,  // 時刻
                DATE: 700,  // 日付
                LABEL: 400, // ラベル
            },
            // 表示サイズ
            // ※画面幅に対しての割合で計算する
            SCALE: {
                TIME: 0.98, // 時刻
                DATE: 0.7,  // 日付
                LABEL: 0.7, // ラベル
            },
        },
        // 色の設定
        COLOR: {
            BACKGROUND: "transparent",  // 背景
            TIME: "#F8F8F8",    // 時刻
            DATE: "#F0F0FF",    // 日付
            LABEL: "#E8E8F8",   // ラベル
            TIMESHADOW: '0 0 5px #fff, 0 0 10px #fff, 0 0 20px #00de00',    // ネオン効果:時刻。不要なら''と書く
            DATESHADOW: '0 0 5px #fff, 0 0 10px #fff, 0 0 20px #00de00',    // ネオン効果:日付。不要なら''
            LABELSHADOW: '0 0 5px #fff, 0 0 10px #fff, 0 0 20px #00de00',   // ネオン効果:ラベル。不要なら''
        },
        // 曜日の文字
        WEEKDAYS: ['日', '月', '火', '水', '木', '金', '土'],
        // ラベル start_at:いつからこのラベルにするか  label:ラベルの文字列
        SCHEDULE: [
            { start_at: '2026-08-26 10:00', label: '場当たり' },
            { start_at: '2026-08-26 21:00', label: 'ゲネ1' },
            { start_at: '2026-08-26 22:00', label: 'ゲネ2' },
            { start_at: '2026-08-26 23:00', label: '第1ステージ' },
            { start_at: '2026-08-27 00:00', label: '第2ステージ' },
            { start_at: '2026-08-28 01:00', label: '第3ステージ' },
            { start_at: '2026-08-28 02:00', label: '公演終了' },
        ],
        // 時計の更新間隔(1000分の1秒単位)
        CLOCK_INTERVAL: 200,
    };

    // DOM要素の取得
    const containerEl = document.getElementById('container');
    const timeEl = document.getElementById('time');
    const dateEl = document.getElementById('date');
    const labelEl = document.getElementById('label');

    // 初期スタイルの適用
    document.body.style.backgroundColor = CONFIG.COLOR.BACKGROUND;

    timeEl.style.fontFamily = CONFIG.FONT.FAMILY.TIME;
    timeEl.style.fontWeight = CONFIG.FONT.WEIGHT.TIME;
    timeEl.style.color = CONFIG.COLOR.TIME;
    timeEl.style.textShadow = CONFIG.COLOR.TIMESHADOW;

    dateEl.style.fontFamily = CONFIG.FONT.FAMILY.DATE;
    dateEl.style.fontWeight = CONFIG.FONT.WEIGHT.DATE;
    dateEl.style.color = CONFIG.COLOR.DATE;
    dateEl.style.textShadow = CONFIG.COLOR.DATESHADOW;
    dateEl.style.marginTop = '0.5rem'; // 時刻と日付の間隔

    labelEl.style.fontFamily = CONFIG.FONT.FAMILY.LABEL;
    labelEl.style.fontWeight = CONFIG.FONT.WEIGHT.LABEL;
    labelEl.style.color = CONFIG.COLOR.LABEL;
    labelEl.style.textShadow = CONFIG.COLOR.LABELSHADOW;
    labelEl.style.marginTop = '1.2rem'; // 日付とラベルの間隔

    // フォントサイズの動的調整機能
    function adjustFontSize(el, targetRatio) {
        if (!containerEl || !el) return;
        el.style.fontSize = '10px'; // 測定用初期値
        const textWidth = el.offsetWidth;
        const containerWidth = containerEl.offsetWidth;

        if (textWidth > 0 && containerWidth > 0) {
            const targetWidth = containerWidth * targetRatio;
            const newFontSize = (targetWidth / textWidth) * 10;
            el.style.fontSize = `${newFontSize}px`;
        }
    }

    // 文字サイズの更新
    function updateSizes() {
        adjustFontSize(timeEl, CONFIG.FONT.SCALE.TIME);
        adjustFontSize(dateEl, CONFIG.FONT.SCALE.DATE);
        adjustFontSize(labelEl, CONFIG.FONT.SCALE.LABEL);
    }

    // 時計の表示更新
    function updateClock() {
        const now = new Date();

        // 時刻
        const hours = String(now.getHours()).padStart(2, '0');
        const minutes = String(now.getMinutes()).padStart(2, '0');
        timeEl.textContent = `${hours}:${minutes}`;

        // 日付
        const month = now.getMonth() + 1;
        const date = now.getDate();
        const weekday = CONFIG.WEEKDAYS[now.getDay()];
        dateEl.textContent = `${month}月${date}日(${weekday})`;

        // ラベル判定
        const activeItems = CONFIG.SCHEDULE.filter(item => {
            return new Date(item.start_at.replace(/-/g, '/')) <= now;
        });

        if (activeItems.length === 0) {
            labelEl.textContent = 'n/a';
        } else {
            activeItems.sort((a, b) => new Date(b.start_at.replace(/-/g, '/')) - new Date(a.start_at.replace(/-/g, '/')));
            labelEl.textContent = activeItems[0].label;
        }
        updateSizes();

    }

    // 初回実行とタイマー設定
    updateClock();
    setInterval(updateClock, CONFIG.CLOCK_INTERVAL);

    // リサイズ時に再計算
    window.addEventListener('resize', updateSizes);
</script>
</body>
</html>

「// 設定」のCONFIG内をいじれば、文字の大きさや色、ネオン効果の有無や色などを変えられます。

ラベル部分については、start_atで「表示を開始する日時」を、labelで「ラベル本文」を適切なものに変えれば良いでしょう。ラベルが不要な場合は、body内のラベル表示部分 <div id="label" class="text-container"></div> を削除すればOKです。

以上です。

短編戯曲集 守りたい いろいろ | 長谷基弘 |本 | 通販 | Amazon
Amazonで長谷基弘の短編戯曲集 守りたい いろいろ。アマゾンならポイント還元本が多数。長谷基弘作品ほか、お急ぎ便対象商品は当日お届けも可能。また短編戯曲集 守りたい いろいろもアマゾン配送商品なら通常配送無料。
Amazon.co.jp: セイコー クロック 目覚まし時計 トラベラ 電波 デジタル カレンダー 温度 湿度 表示 白 パール SQ699W SEIKO : ホーム&キッチン
Amazon.co.jp: セイコー クロック 目覚まし時計 トラベラ 電波 デジタル カレンダー 温度 湿度 表示 白 パール SQ699W SEIKO : ホーム&キッチン

コメント

タイトルとURLをコピーしました