JS がビデオ弾幕効果を実現

JS がビデオ弾幕効果を実現

これを実現するには、ES6 モジュール開発とオブザーバー モードを使用します。オブザーバー パターンにはさまざまな形式があります。ここでは、「register-notify-underegister」形式を使用します。 TimeManager クラスはシングルトンを返すことができます。各箇条書きコメントは、TimeManager クラスのシングルトンのセット テーブルにオブザーバーとして登録されます。シングルトンのセットにデータがある場合、オブザーバーの状態が変更され、アニメーションが実行され、すべてのオブザーバーに状態の更新が通知されます。弾丸画面がビデオ幅を超えて移動すると、TimeManager から登録解除されます。 TimeManager シングルトンの設定テーブル内のすべての監視コメントが登録解除されると、setInterval は実行を停止します。

1. Bullet.js:

オブザーバー: 弾丸スクリーン スタイルを実装し、update() メソッドを使用して独自のステータスを更新します。

2. タイムマネージャー

オブザーバブルとサブジェクト: オブザーバー オブジェクトを追加および削除したり、状態が変化したときにすべてのオブザーバーに通知したり、状態を更新したりできます。

3. プレイヤー

プレーヤー コンポーネント: シンプルなプレーヤー スタイル、コントロール ボタンなどはすべてデフォルトのスタイルです。 。 。

4. 達成効果:

5. 具体的な実施内容:

'./TimeManager.js' から TimeManager をインポートします。
 
デフォルトクラスBulletをエクスポートする{
    
    要素;
    バツ;
    速度X=2;
    幅;
 
    コンストラクタ(txt){
        this.elem = this.createElem(txt);
    }
    要素を作成します(txt){
        if(this.elem) 戻り値
        div = document.createElement("div"); とします。
        オブジェクト.assign(div.style,{
            位置:"絶対",
            空白: "nowrap",
            フォントサイズ:"16px",
            // 色:"#000",
            色:"#e00",
        })
        div.textContent = txt;
        divを返す
    }
    親に追加{
        if(typeof parent === "string") parent = document.querySelector(parent);
        親要素に子要素を追加します。
        rect = parent.getBoundingClientRect() とします。
        this.elem.style.top = Math.random()*rect.height/4 + "px";
        this.width = this.elem.offsetWidth;
        rectの幅をx軸に合わせる
        this.elem.style.left = this.x + "px";
        TimeManager.instance.add(これ);
    }
    アップデート(){
        if(!this.elem) 戻り値:
        this.x -= this.speedX;
        this.elem.style.left = this.x + "px";
        if(this.x<-this.width){
            this.elem.remove();
            TimeManager.instance.remove(これ);
            this.elem = null;
        }
    }
}
デフォルトクラスTimeManagerをエクスポートする{
    
    静的_instance;
    リスト = 新しい Set();
    id;
 
    コンストラクタ(){
 
    }
    静的インスタンス取得(){
        TimeManager._instance = TimeManager._instance? TimeManager._instance: 新しい TimeManager();
        TimeManager._instance を返します。
    }
    要素を追加{
        if(!elem) 戻り値
        if(elem.update) this.list.add(elem);
        if(!this.ids) this.ids = setInterval(()=>{
            これを更新します。
        },16);
    }
    削除(要素){
        if(!elem) 戻り値
        this.list.delete(要素);
        if(this.list.size===0 && this.ids){
            間隔をクリアします(this.ids);
            0 を返します。
        }
    }
    アップデート(){
        this.list.forEach(item=>{
            アイテムを更新します。
        })
    }
}
'./Bullet.js' から Bullet をインポートします。
 
エクスポートデフォルトクラスPlayerはEventTargetを拡張します{
 
    静的 WIDTH=638;
    静的高さ=493;
    要素;
    入力;
 
    コンストラクタ(パス){
        素晴らしい();
        this.elem = this.createElem(パス);
        document.addEventListener("keyup",e=>this.keyHandler(e));
    }
    キーハンドラ(e){
        if(e.keyCode !== 13) 戻り値:
        if(this.input.value.trim().length===0) 戻り値:
        b = new Bullet(this.input.value); とします。
        b.appendTo(this.elem);
        this.input.value = "";
    }
    親に追加{
        if(typeof parent==="string") 親 = document.querySelector(parent);
        親要素に子要素を追加します。
    }
    createElem(パス){
        // プレーヤーの最も外側のコンテナー let player = document.createElement("div");
        player.className = "プレイヤー";
        オブジェクト.assign(player.style,{
            幅:Player.WIDTH+"px",
            高さ:Player.HEIGHT+"px",
            ユーザー選択:"なし",
            オーバーフロー: "非表示",
            位置:"相対",
            verticalAlign:"ベースライン",
        })
        // プレーヤーのビデオ再生部分: 上部の作成者とフィードバック バー、ビデオ ステータス ボタン、およびビデオ表示部分を含める必要があります。 。 。 。
        videoWrap を document.createElement("div"); にします。
        オブジェクト.assign(videoWrap.style,{
            幅:"100%",
            高さ:"447px",
            背景色:"#000",
            位置:"相対",
            上:0,
            表示:"フレックス",
            flexDirection:"列",
        })
        // タイトル、作成者、フィードバック、レポートなどを含むプレーヤーの上位レイヤーを作成します。 。 。 。
        videoTop を document.createElement("div"); にします。
        オブジェクト.assign(videoTop.style,{
            幅:"100%",
            高さ:"42px",
            位置:"相対",
            上:"0px",
            左:"0px",
            不透明度:"0",
            色:"#fff",
            ポインタイベント:"なし",
            // 遷移: "すべて .2s イーズインアウト"、
            遷移: "すべて .2"、
        })
        // ビデオ再生ステータスの切り替え // let videoState = document.createElement("div");
        // ビデオ再生部分 let videoContent = document.createElement("div");
        オブジェクト.assign(videoContent.style,{
            幅:"100%",
            // 高さ:"100%",
            高さ:"361px",
            位置:"相対",
            ユーザー選択:"なし",
        })
        video = document.createElement("video"); を作成します。
        video.src = パス;
        video.controls = "コントロール";
        ビデオのプリロード = "自動";
        オブジェクト.assign(video.style,{
            // ビデオの中央配置: 進行状況バーは長くなりますが、ビデオは長くなりません。中央に直接配置されます。
            高さ:"100%",
            幅:"100%",
        })
        ビデオコンテンツに子要素を追加します。
 
        // ビデオ再生と箇条書き画面のスクロール コントロール バー: 明瞭度/速度/ループ/ミラー/ワイド スクリーン/フル スクリーン Web ページ/進行状況バーなど。
        videoControlWrap を document.createElement("div"); にします。
        オブジェクト.assign(videoControlWrap.style,{
            幅:"100%",
            高さ:"44px",
            不透明度:"0",
            位置:"相対",
            下:"0",
        })
 
        // 下部に箇条書き画面を送信し、箇条書き画面の送信スタイルを設定します: 箇条書き画面の色/フォント サイズ/スクロール/ホバー/速度/フォント/シールドなど。 。 。
        bottomArea = document.createElement("div"); とします。
        オブジェクト.assign(bottomArea.style,{
            幅:"100%",
            高さ:"46px",
        })
        this.input = document.createElement("input");
        オブジェクト.assign(this.input.style,{
            幅:"130ピクセル",
            高さ:"30px",
            色:"#212121",
            // 境界線:"0px",
            行の高さ:"30px",
            ボックスサイズ: "border-box",
            最小幅: "115px",
            パディング:"0 5px",
            フォントサイズ:"12px",
            border:"1px solid #e7e7e7", //フレームスタイル:
            背景色:"#f4f4f4",
        })
        bottomArea.appendChild(this.input);
 
        ビデオラップ。ビデオの先頭に子要素を追加します。
        ビデオコンテンツに子要素を追加します。
        ビデオコントロールラップの子要素を追加します。
 
        player.appendChild(ビデオラップ);
        player.appendChild(下部エリア);
        リターンプレーヤー;
    }
}
<!DOCTYPE html>
<html lang="ja">
<ヘッド>
    <メタ文字セット="UTF-8">
    <meta name="viewport" content="width=デバイス幅、初期スケール=1.0">
    <title>ドキュメント</title>
    <スタイル>
    </スタイル>
</head>
<本文>
    <スクリプトタイプ="モジュール">
        './js/Player.js' から Player をインポートします。
        './js/TimeManager.js' から TimeManager をインポートします。
        './js/Bullet.js' から Bullet をインポートします。
 
        //プレーヤーの使用 let player = new Player("./test3.mp4");
        player.appendTo("本文");
 
    </スクリプト>
</本文>
</html>

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • シンプルなビデオ連射機能を実装する JavaScript CSS3
  • ビデオの弾幕効果を実現する JavaScript (2 つのバージョン)
  • JS で実装したビデオ弾幕スクリーン効果の例

<<:  MySQL でのワイルドカードを使用したファジークエリの実装に関する簡単な説明

>>:  Linux コマンド sort、uniq、tr ツールの詳細な説明

推薦する

MySQL ステートメントの配置と概要の紹介

SQL (Structured Query Language) ステートメント、つまり構造化クエリ言...

LinuxにRocketMQインスタンスをインストールする手順

1. JDKをインストールする1.1 現在の仮想マシン環境にJDKがあるかどうかを確認する rpm ...

Vue v-for ループを書く 7 つの方法

目次1. v-forループでは常にキーを使用する2. 特定のスコープ内でv-forループを使用する3...

mysqldump を使用して MySQL データをバックアップする方法

1. mysqldump の紹介mysqldump は、MySQL に付属する論理バックアップ ツー...

Ubuntu 18.04 に vsftpd をインストールするための実装コード

vsftpdをインストールする $ sudo apt-get install vsftpd -y v...

Dockerfileを使用してDockerイメージを構築する手順

Dockerfile は、命令を含むテキスト ファイルです。各命令はレイヤーを構築するため、各命令の...

MYSQL サブクエリとネストされたクエリの最適化例の分析

ゲーム史上最高スコアトップ100をチェックSQLコード cdb_playsgame ps から ps...

React Native JSIはRNとネイティブ通信のサンプルコードを実装します

目次JSIとはJSIの違いiOS で JSI を使用するiOS 設定RN側の構成jsはパラメータ付き...

XHTML 入門チュートリアル: リストタグの使用

リストは、類似または関連する一連の項目をリストするために使用されます。順序なしリスト(箇条書きリスト...

一般的な HBase 運用および保守ツール 10 個の概要

概要: HBase には、ユーザーに管理、分析、修復、デバッグ機能を提供するための多くの操作および保...

CSS3で実装されたスライドメニュー

結果:実装コード: <!DOCTYPE html><html class=&quo...

スタックメニューを実装するためのjQueryプラグイン

jQueryプラグインの毎日の積み重ねメニュー、参考までに、具体的な内容は次のとおりです。スタックメ...

Linux xargsコマンドの使用

1. 機能: xargs は、stdin 内のスペースまたは改行で区切られたデータをスペースで区切ら...

Dockerのデフォルトネットワークセグメントの正しい変更手順

背景同僚がセキュリティ プロジェクトに取り組んでおり、AWS サーバーに秘密兵器を展開する必要があり...