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 ツールの詳細な説明

推薦する

Linux 環境変数とプロセス アドレス空間の概要

目次Linux 環境変数とプロセスアドレス空間コードを通じて環境変数を取得するプロセスアドレス空間な...

一般的なブラウザ互換性の問題(概要)

ブラウザの互換性とは、スタイルの互換性 (CSS)、インタラクションの互換性 (JavaScript...

Linux CRM デプロイメント コードの詳細な説明

Linuxの基本設定 Linux環境でpython3をコンパイルしてインストールする 1. Linu...

プロジェクトにおけるVue3のロジック抽出とフィールド表示についての簡単な説明

目次論理階層化異なる地域から事業を分離するこれを実行する利点このようなシナリオにどう対処するか最適化...

DockerはPruneコマンドを使用してnoneイメージをクリーンアップします

目次無イメージの創造と混乱Noneオブジェクトをクリーンアップする方法トリムミラーコンテナで使用され...

MySQL 自動インクリメント ID のオーバーサイズ問題のトラブルシューティングと解決策

導入Xiao A がコードを書いていたところ、DBA Xiao B が突然、「急いでユーザー固有情報...

メンテナンスしやすい CSS コードを書くための 5 つのガイドライン

1. スタイルシートの先頭にコメント ブロックを追加して、スタイルシートの作成日、作成者、タグ、その...

Vue でログインと登録テンプレートを実装するためのサンプルコード

テンプレート 1: ログイン.vue <テンプレート> <p class=&quo...

Nginx ロケーションマッチングルールの例

1. 文法 場所 [=|~|~*|^~|@] /uri/ { ... } 2. 説明上記の構文から、...

Typescriptを使用してWeChatミニプログラムを開発するための詳細な手順

Typescript の利点については詳しく説明する必要はありません。ご興味があれば、(https:...

閲覧時に作成されたWebページの下部にある余分な空白スペースを削除する方法

Dreamweaver または FrontPage を使用して HTML Web ページを作成する場...

Linux ファイル記述子、ファイルポインタ、および inode の詳細

目次Linux - ファイル記述子、ファイルポインタ、インデックスノード1. Linux - ファイ...

Linux での MongoDB のインストールに関するチュートリアル

MongoDB はクロスプラットフォームであり、Windows と Linux の両方にインストール...

js は、Element の入力コンポーネントのいくつかの機能を実装し、それをコンポーネントにカプセル化します (サンプルコード)

現在実装されているのは、基本的な使用方法、クリア可能なボックス、パスワードボックスです。参考リンク:...

mysql5.7.21 の異常起動を修正する方法

同僚から、停電のため MySQL インスタンスを起動できないという報告がありました。 innodb_...