WeChat 8.0の爆発的な特殊効果を実現するために300行以上のCSSコードが必要

WeChat 8.0の爆発的な特殊効果を実現するために300行以上のCSSコードが必要

WeChat 8.0 アップデートの主な特徴は、アニメーション絵文字のサポートです。送信するメッセージに絵文字アイコンが 1 つしか組み込まれていない場合、この絵文字には簡単なアニメーションが表示されます。一部の特別な絵文字には、全画面の特殊効果もあります。たとえば、花火の絵文字には全画面の花火の特殊効果があり、爆弾の絵文字には爆発アニメーションがあり、メッセージとアバターがそれに応じて振動します。

フロントエンドエンジニアとしてのプロ精神で、同様の特殊効果を実現できるかどうか試してみたかったのです。長い苦労の末、結果は以下のようになりました。

このプロジェクトの中核は、lottie アニメーション ライブラリの使用です。 lottieはAirbnbが制作した、あらゆるプラットフォーム(Web、Android、IOS、React Native)向けのアニメーションライブラリです。Adobe After Effectsで作成したアニメーションを直接再生できるのが特徴です。デザイナーが After Effects の Bodymovin プラグインを使用してアニメーションを JSON 形式でエクスポートすると、開発者は対応するプラットフォームの SDK を通じてアニメーションを再生できるようになります。 (プロジェクトのアドレスとサンプルのデモンストレーションは記事の最後にあります)

このプロジェクトを完了した後、フロントエンドの知識が豊かになり、将来複雑な特殊効果に対処するための新しいアイデアが生まれたと感じています。フロントエンドの開発スキルをさらに向上させたい場合は、この記事に従って練習してください。 Lottie ライブラリを使用しているほか、この記事はすべてネイティブ HTML/CSS/JavaScript を使用して実装されているため、React、Vue、その他のエンジニアであればすぐに習得できます。

書き込みインターフェース

当初は HTML/CSS の部分は飛ばそうと思っていましたが、CSS はほとんどの人にとって弱点かもしれないと思ったので、インターフェースを実装するためのアイデアを書き留めることにしました。コア部分を見たい場合は、直接「 2. 通常のメッセージの送信」にジャンプできます。

1. HTML部分

まずはHTML部分を見てみましょう。効果図から:

  • 上部に「XXX とチャット」というタイトル バーがあります。
  • 中央にはチャット情報パネルがあり、双方が送信したメッセージが表示されています。各メッセージは送信者のアバターとメッセージの内容で構成されています。自分が送信したものは右側、相手が送信したものは左側に表示されます。
  • 以下は下部の情報で、絵文字選択ボタン、メッセージ編集テキスト ボックス、送信ボタンがあります。

この構造に従って記述された HTML コードは次のようになります。

<メイン>
  <div class="チャット">
    <div class="titleBar">XXX とチャット</div>
    <div class="パネル">
      <div class="メッセージ私">
        <img src="./me.png" alt="" />
        <p><span>こんにちは</span></p>
      </div>
      <div class="あなたのメッセージ">
        <img class="アバター" src="./you.png" alt="" />
        <p><span>こんにちは</span></p>
      </div>
      <!-- 他のメッセージを省略 -->
    </div>
    <フッター>
      <button class="chooseSticker">
        <img src="./emoji.svg" alt="" />
        <div class="ステッカー"></div>
      </ボタン>
      <入力
             クラス="メッセージ入力"
             タイプ="テキスト"
             名前=""
             id=""
             placeholder="チャット情報を入力してください"
             />
      <button class="send">送信</button>
    </フッター>
  </div>
</メイン>

各要素に対応するインターフェース部分は次のとおりです。

  • <main />要素は、チャット ウィンドウを中央に配置するために使用される全体的なコンテナーです。
  • <div class="chat">はチャット アプリケーションのコンテナーであり、タイトル バー、チャット パネル、下部の送信ボックスのレイアウトに使用されます。
  • <div class="titleBar">タイトルバーを表示するために使用されます。
  • <div class="panel">は、メッセージをレイアウトするために使用されるメッセージ パネルです。
  • <div class="message">はメッセージ コンテナーです。送信者を区別するために、異なるクラスが使用されます。Mine mine自分が送信したことを意味し、 yours相手が送信したことを意味します。各メッセージでは、アバターを表示するために<img class="avatar" >が使用され、テキストを表示するために<p>要素が使用されます。 <p>要素内の<span>要素は、絵文字アニメーションを再生するためのロッティー コンテナーとして機能します。
  • <footer>は、下部の操作ボタンやメッセージ送信ボックスのレイアウトに使用されます。で:
  • <button class="chooseSticker">は表情選択ボタンで、スマイリー フェイスの SVG 画像で表されます。内部の<div class="stickers">は表情選択ボックスのポップアップ レイヤーです。アニメーション プレビューを実現するために、内部の表情は JS で動的に読み込まれます。
  • <input class="messageInput" />はチャット メッセージ入力ボックスであり、特別なものではありません。
  • <button class="send">

これがHTMLの基本構造です。次にCSSスタイルを見てみましょう。

2. CSS部分

プロジェクトのルート ディレクトリに style.css ファイルを作成し、index.html の <head> タグにインポートします。

<link rel="スタイルシート" href="style.css" />

2.1 グローバルスタイル

まず、CSS 変数をいくつか定義します。CSS 変数は、同じ属性値を参照しやすくするために使用されます。後でスタイルを更新する場合、複数の変更を回避できます。

:根 {
  --プライマリカラー: hsl(200, 100%, 48%);
  --inverse-color: hsl(310, 90%, 60%);
  --shadow-large: 0 0px 24px hsl(0, 0%, 0%, 0.2);
  --shadow-medium: 0 0 12px hsl(0, 0%, 0%, 0.1);
}

これらの変数の意味は次のとおりです。

  • --primary-color: hsl(200, 100%, 48%) 、送信したメッセージの青い背景などの基本色。
  • --inverse-color: hsl(310, 90%, 60%) 、送信ボタンの背景色など、基本色と対照的な反転色またはアクセントカラー。
  • --shadow-large: 0 0px 24px hsl(0, 0%, 0%, 0.2) 、タイトルバーや下部バーの影などの大きな影。
  • --shadow-medium: 0 0 12px hsl(0, 0%, 0%, 0.1) 、入力ボックスや絵文字選択ポップアップレイヤーなどの小さな影。

次に、いくつかのリセット スタイルを示します。

* {
  ボックスのサイズ: 境界線ボックス;
  パディング: 0;
  マージン: 0;
  フォントファミリ: Helvetica、「PingFang SC」、「Microsoft Yahei」、サンセリフ;
}

これらのスタイルはすべての要素に有効です。ボックス モデルをborder-boxに設定して、内側の余白と境界線が幅と高さの範囲内で計算されるようにし、内側と外側の間隔を 0 に設定し、最後にデフォルトのフォントを設定します。

2.2 メインコンテナ

メイン コンテナーは、チャット アプリケーション コンテナーをブラウザーの中央に配置するために使用されます。グリッド レイアウトを使用し、幅と高さをブラウザーの表示領域の 100% に設定し、背景色をダーク グレーに設定します。

主要 {
  表示: グリッド;
  アイテムを配置: 中央;
  幅:100vw;
  高さ:100vh;
  背景色: hsl(0, 0%, 10%);
}

2.3 チャットアプリケーションコンテナ

チャット アプリケーション コンテナーは、携帯電話の画面をシミュレートするために固定の幅と高さを設定し、グリッド レイアウトを使用してタイトル バー、チャット パネル、下部の操作バーの位置を制御します。

。チャット {
  幅: 375ピクセル;
  高さ: 700ピクセル;
  背景: hsl(0, 0%, 100%);
  境界線の半径: 8px;
  表示: グリッド;
  グリッドテンプレート行: 最大コンテンツ 1fr 最大コンテンツ;
}

ここでは、 grid-template-rowsを使用して、チャット アプリケーションを 3 行に分割しています。最初の行のタイトル バーと最後の行の下部操作バーの高さはコンテンツの最大の高さであり、中央のチャット パネルはフローティングの高さです。

2.4 タイトルバー

タイトル バーでは、パディング、テキストの中央揃え、影を設定するだけです。

.titleBar {
  パディング: 24px 0;
  テキスト配置: 中央;
  ボックスシャドウ: var(--shadow-large);
}

インターフェースの最適化のヒント: 内側のスペースは、空白を増やして視覚的なリラックス感を生み出すために使用され、影は下のチャット パネルと区別するために使用されます。

2.5 チャットパネル

チャット パネルでは、フレックス レイアウトを使用してメッセージを配置し、列に配置する方向を設定し、オーバーフローを自動に設定します。メッセージの全体的な高さがパネルの高さを超えると、スクロール バーが表示されます。

.パネル{
  ディスプレイ: フレックス;
  flex-direction: 列;
  パディング: 24px 12px;
  オーバーフロー:自動;
}

インターフェースの最適化のヒント: ここでのパディングは、混雑感を避けるために、他の要素から分離するのに十分なスペースを残すためのものです。

2.6 メッセージ

メッセージは、メッセージ コンテナー、アバター、メッセージ本文の 3 つの部分に分かれています。メッセージ本文とアバターはメッセージコンテナに含まれています。まずはメッセージコンテナのスタイルを見てみましょう。メッセージ コンテナーは、フレックス レイアウトを使用して、メッセージ本文とアバターを 1 行に配置し、最大幅をパネル幅の 80% にして、フォントと余白を設定します。

。メッセージ {
  ディスプレイ: フレックス;
  最大幅: 80%;
  フォントサイズ: 14px;
  マージン: 8px 0;
  位置: 相対的;
}

ここでのpositionフルスクリーンの特殊効果アニメーションをその背後に配置するために相対的に設定されています。

アバターは、幅、高さ、丸い角、メッセージ本文からの距離を設定するだけです。

.メッセージ画像{
  幅: 40px;
  高さ: 40px;
  境界線の半径: 12px;
  右マージン: 12px;
}

インターフェースの最適化のヒント: ここで、間隔の重要性について言及する必要があります。要素をあまりコンパクトに配置しないでください。そうしないと、視覚効果に大きな影響を与えます。最も直接的な影響は、視覚的な混雑と視覚疲労を引き起こすことです。

メッセージ本文にも間隔と丸い角があり、ここでの丸い角はアバターと一致しているため、調和感が増しています。また、影を設定し、フレックス レイアウトを使用してテキストまたは絵文字メッセージを中央に配置します。

.メッセージ p {
  パディング: 8px 12px;
  境界線の半径: 12px;
  ボックスシャドウ: var(--shadow-large);
  ディスプレイ: フレックス;
  アイテムの位置を中央揃えにします。
}

デフォルトでは、これらのスタイルは相手のメッセージに基づいています。自分が送信したメッセージの場合は、右側に配置する必要があり、いくつかの調整を行う必要があります。まず、送信したメッセージでは、flex-flow を row-reverse に変更してアバターとメッセージ本文の位置を入れ替え、align-self を使用してパネルの右側に揃えました。

.message.mine {
  flex-flow: 行を逆にします。
  align-self:flex-end;
}

アバターの外側の余白を調整します。これで、左側のメッセージ本文からの余白になります。

.message.mine 画像 {
  右マージン: 0;
  左マージン: 12px;
}

メッセージ本文の背景色を青、テキストを白に設定します。

.message.mine p {
  背景色: var(--primary-color);
  色: 白;
}

2.7 下部操作バー

まず、下部のアクション バー コンテナーの全体的なレイアウトを見てみましょう。グリッド レイアウトを使用して、絵文字選択ボタン、メッセージ送信ボックス、送信ボタンを 3 つの列に分割します。フローティング幅のメッセージ送信ボックスを除き、他の 2 つのボタンは固定幅で、デフォルトで中央に配置されます。最後に、影と間隔を設定します。

フッター {
  表示: グリッド;
  グリッドテンプレート列: 48px 1fr 75px;
  項目の位置揃え: 中央;
  パディング: 12px;
  ボックスシャドウ: var(--shadow-large);
}

絵文字選択ボタンは左揃えになり、絵文字選択ポップアップ レイヤーを配置するための相対的な位置を設定してから、ボタン アイコンのサイズを設定します。

.ステッカーを選択する{
  正当化-自己: 開始;
  位置: 相対的;
}
.chooseSticker画像{
  幅: 36ピクセル;
  高さ: 36px;
}

絵文字選択ポップアップ レイヤーの CSS コードはかなり長いですが、非常にシンプルです。まずはコードを見てみましょう。

.ステッカー{
  表示: グリッド;
  グリッドテンプレート列: repeat(自動入力、24px);
  列間隔: 18px;

  境界線の半径: 8px;
  背景色: 白;
  ボックスシャドウ: var(--shadow-medium);
  パディング: 6px 12px;
  フォントサイズ: 24px;

  位置: 絶対;
  上: calc(-100% - 18px);
  幅: 300ピクセル;
  不透明度: 0;
}

このコードの意味は次のとおりです。

  • ポップアップ レイヤーはグリッド レイアウトを使用します。繰り返し (自動入力、24 ピクセル) は、幅が許す限り、できるだけ多くの列要素を 1 行に配置することを意味します。各列の幅は 24 ピクセルに固定されています。次に、列間隔を 18 ピクセルに設定します。
  • 角の半径、背景色、影、パディング、フォント サイズを設定します。
  • 配置を絶対に設定し、包含要素の高さ (つまり、.chooseSticker の高さ) の 100% から 18 px を引いた値まで移動し、適切な位置に調整します。非表示にするには、幅を 300 ピクセル、不透明度を 0 に設定します。

メッセージ入力ボックスとボタンのスタイルは比較的シンプルです。メッセージ入力ボックスの幅は列全体を埋め、送信ボタンはjustify-self: endを使用して右揃えになっています。すぐに投稿されたコードは次のとおりです。

.メッセージ入力{
  ボックスシャドウ: var(--shadow-medium);
  パディング: 0px 12px;
  境界線の半径: 8px;
  幅: 100%;
}
。送信 {
  高さ: 100%;
  幅: 90%;
  境界線の半径: 8px;
  正当化-自己: 終了;
  色: 白;
  背景色: var(--inverse-color);
}

最後に、 .showスタイルを追加して、このスタイルを絵文字ポップアップ レイヤーに追加し、絵文字の送信ボタンがクリックされたときに表示されるようにします。

。見せる {
  不透明度: 1;
}

3. JS部分

チャット インターフェイスに機能を追加する前に、基本的な JS コードをいくつか記述します。プロジェクトのルート ディレクトリに index.js ファイルを作成し、index.html で参照します。要素が見つからないように、js 内のコードは HTML DOM が読み込まれた後にのみ実行されるように、</body> の終了タグの上に配置する必要があることに注意してください。

<本文>
   <!-- その他のコードは省略-->
   <script src="index.js"></script>
 </本文>

index.js では、まず操作する DOM 要素を取得します。

const panelEle = document.querySelector(".panel");
const chooseStickerBtn = document.querySelector(".chooseSticker");
const ステッカーエレメント = document.querySelector(".ステッカー");
const msgInputEle = document.querySelector(".messageInput");
const sendBtn = document.querySelector(".send");

で:

  • panelEle 、新しいメッセージを追加するために使用されるメッセージ パネル要素です。
  • chooseStickerBtnは絵文字選択ボタンです。これをクリックすると、絵文字選択ボックスがポップアップ表示されます。
  • stickersEleはポップアップ表示される絵文字選択ボックスです。
  • msgInputEleはメッセージ入力ボックスです。
  • sendBtnは送信ボタンです。

次に、Lottie の js ライブラリをインポートします。サンプル コード リポジトリからダウンロードするか、https://cdnjs.com/libraries/bodymovin から lottie.min.js をダウンロードできます。ダウンロードしたら、プロジェクトのルート ディレクトリに配置し、index.html の index.js のインポートの上にインポートします。

<script src="lottie.min.js"></script>

式アニメーション リソース ファイルをダウンロードします。これらはすべて json 形式です。ダウンロードしたら、プロジェクトのルート ディレクトリに配置します。

  • カボチャの絵文字: https://lottiefiles.com/43215-pumpkins-sticker-4
  • 爆弾の絵文字: https://lottiefiles.com/3145-bomb
  • 爆発アニメーション: https://lottiefiles.com/9990-explosion

次に、各機能がどのように実装されているかを見てみましょう。

通常のメッセージを送信する

通常のメッセージを送信する場合、ユーザーが入力ボックスにメッセージを入力して「送信」をクリックすると、メッセージはメッセージ リストに追加され、入力ボックスの内容はクリアされます。次に、送信ボタンにクリック イベントを追加します。

sendBtn.addEventListener("クリック", () => {
  定数msg = msgInputEle.value;
  if (メッセージ) {
    メッセージを追加します。
  }
});

イベント処理関数内:

  • ユーザーがメッセージを入力したかどうかを判断します。
  • 入力すると、メッセージ リストに追加されます。

appendMsg()関数のコードを見てみましょう。

関数 appendMsg(メッセージ, タイプ) {
  // メッセージ要素を作成します。const msgEle = panelEle.appendChild(document.createElement("div"));
  msgEle.classList.add("message", "mine"); // 「me」が送信したスタイルに設定します msgEle.innerHTML = `
    <img class="アバター" src="./me.png" alt="" />
    <p><span>${メッセージ}</span></p>
  `;
  // 最新のメッセージまでスクロールします。panelEle.scrollTop = panelEle.scrollHeight;
  msgInputEle.value = "";
}

この関数は、追加するメッセージの内容とタイプである msg と type の 2 つのパラメータを受け取ります。type はオプションです。渡されない場合は、通常のテキスト メッセージと見なされます。"stickers" が渡された場合は、絵文字メッセージであり、今は必要ありません。この機能では主に以下のことが行われます。

  • メッセージの HTML 構造に従って新しいメッセージ要素 msgEle を作成し、それをメッセージ リストに追加します。
  • メッセージのスタイルを「自分から送信」に設定します。
  • 内部要素は、アバターとテキストメッセージであり、テンプレート文字列の形式で msgEle の innerHTML 属性に割り当てられ、 msg 変数の値が<p>で使用されます。
  • 最後に、スクロール バーを最新のメッセージまでスクロールし、入力ボックス内のメッセージをクリアします。

これにより、通常のテキスト メッセージを送信できるようになります。

アニメーション絵文字を送信する

アニメーション絵文字を送信する前に、まずそれらを読み込む必要があります。 index.js の先頭で、式名と式アニメーション ファイル パスのキーと値のペア情報を定義します。

const ステッカー = {
  爆弾:
    パス: "./3145-bomb.json",
  },
  パンプキン:
    パス: "./43215-pumpkins-sticker-4.json",
  },
};

bombpumkinなどのキーに基づいて、対応するアニメーション パスを検索します。次に、ユーザーが選択できるようにポップアップ レイヤー内の式を初期化します。

// 式パネルを初期化します。式選択ウィンドウがポップアップしたときに初期化することもできます。Object.keys(stickers).forEach((key) => {
  const lottieEle = sticksEle.appendChild(document.createElement("span"));
  // 各式に対してlottieプレイヤーを作成する const player = lottie.loadAnimation({
    コンテナ: lottieEle、
    レンダラー: "svg",
    ループ: 真、
    自動再生: false、
    パス: ステッカー[キー].パス、
  });
  // 絵文字が選択されたら、メッセージを送信し、タイプをステッカー絵文字メッセージに設定します lottieEle.addEventListener("click", () => {
    appendMsg(キー、「ステッカー」);
  });
  // マウスが移動すると、アニメーションプレビューを再生します lottieEle.addEventListener("mouseover", () => {
    プレイヤーを再生します。
  });
  // マウスが移動するとアニメーションのプレビューを停止します lottieEle.addEventListener("mouseleave", () => {
    プレーヤーを停止します。
  });
});

ここでのコードは次の操作を実行します。

  • 式情報を格納するオブジェクトを走査します。
  • lottie アニメーション プレーヤーは特定の HTML 要素にマウントする必要があるため、lottie コンテナーを作成し、span 要素を使用します。
  • アニメーションをロードするには、lottie の loadAnimation() を呼び出します。次のパラメータを渡す必要があります。
  • コンテナ: プレイヤーがマウントされるコンテナ。
  • レンダラー: アニメーションをレンダリングするために svg を使用するかキャンバスを使用するかを選択できます。
  • loop: ループ再生するかどうか。アニメーションは式選択ポップアップレイヤーでプレビューされるため、ループ再生がサポートされています。
  • autoplay: 自動的に再生するかどうか。ここで no に設定すると、マウスがその上に移動したときにアニメーションが再生されます。
  • path: オブジェクトから直接取得されたアニメーション json ファイル パス。
  • loadAnimation() は lottie のインスタンスを返し、それをプレーヤーに保存します。

その後、いくつかのイベントが登録されます。

  • 絵文字lottieEleをクリックすると、絵文字メッセージが送信され、appendMsg()のmsgパラメータが絵文字のキーに設定され、typeパラメータが「sticker」に設定されます。
  • マウスを式の上に移動すると、アニメーションの再生が始まります。
  • マウスが式から外れると、アニメーションを停止します。

次に、「絵文字を送信」ボタンにイベントを追加します。クリックすると、絵文字ポップアップ レイヤーの表示状態が切り替わります。

chooseStickerBtn.addEventListener("クリック", () => {
  ステッカーEle.classList.toggle("表示");
});

このとき、「絵文字を送信」ボタンをクリックすると、絵文字選択ポップアップ レイヤーが表示されます。絵文字はまだ appendMsg() 関数で処理されていないため、送信できません。ここで、そのコードを変更してみましょう。まず、次の点を決定します。絵文字メッセージの場合は、メッセージ内の<p>要素に情報を追加しないでください。

関数 appendMsg(メッセージ, タイプ) {
 // ... 
  msgEle.innerHTML = `
    <img class="アバター" src="./me.png" alt="" />
    <p><span>${type === "ステッカー" ? "" : msg}</span></p>
  `;
}

次に、その下で、playSticker() 関数を呼び出してアニメーションを再生します。

// 絵文字メッセージを処理し、関連するアニメーションを再生します if (type === "sticker") {
  ステッカーを再生します(msg、msgEle);
}

playSticker() 関数は 2 つのパラメータを受け取ります。1 つは絵文字キー、もう 1 つはメッセージ要素です。このときのmsg変数の内容はlottieEleクリックイベントで渡された式キーです。関数内のコードは次のとおりです。

関数playSticker(キー, msgEle) {
  // 式メッセージ、lottie アニメーションを作成 const lottieEle = msgEle.querySelector("span");
  lottieEle.style.width = "40px";
  lottieEle.style.height = "40px";
  lottie.loadAnimation({
    コンテナ: lottieEle、
    レンダラー: "svg",
    ループ: false、
    自動再生: 有効、
    パス: ステッカー[キー].パス、
  });
}

この機能では主に以下の操作が実行されます。

  • メッセージ内の span 要素を取得します。これは lottie のアニメーション コンテナーとして機能します。
  • 表情アニメーションの幅と高さを40pxに設定します。
  • lottie を使用してアニメーションを読み込み、ループ再生を false に、自動再生を true に設定すると、絵文字が送信されたときにアニメーションが自動的に再生され、1 回だけ再生されます。

これで絵文字メッセージを送信でき、関連するアニメーションが自動的に再生されます。次に、爆弾の全画面アニメーションとメッセージ要素の揺れ効果を実装する方法を見てみましょう。

フルスクリーンエフェクト付きの絵文字を送信する

このタイプの全画面特殊効果付き絵文字については、個別に判断することも、絵文字を保存するオブジェクト内に関連する操作を定義することもできます。ここでは、簡単にするために、ユーザーが爆弾絵文字を送信したかどうかを個別に判断し、対応する特殊効果を適用します。

まず、appendMsg() 関数で判定が行われます。送信されたメッセージが絵文字メッセージであり、絵文字が爆弾である場合、全画面アニメーションが再生され、メッセージが揺れます。

関数 appendMsg(メッセージ, タイプ) {
  if (type === "ステッカー") {
    ステッカーを再生します(msg、msgEle);
    if (msg === "爆弾") {
      // 爆発アニメーションを再生する setTimeout(() => {
        爆発を再生します(msgEle);
      }, 800);
      // シェイクメッセージリスト shakeMessages();
    }
  }
}

ここでは、フルスクリーンの爆発アニメーションが実行前に 800 ミリ秒遅延されます。目的は、爆弾表現が適切な時間まで再生されたときにフルスクリーン アニメーションを再生することです。アニメーションを再生するには playExplosion() 関数を使用し、メッセージ要素がそれに渡されます。爆発のフルスクリーンアニメーションが終了したら、shakeMessages() を呼び出してメッセージを振ってください。 playExplosion() 関数のコードは次のとおりです。

関数playExplosion(アンカー) {
  const 爆発アニメエレメント = アンカー.appendChild(document.createElement("div"));
  爆発AnimeEle.style.position = "絶対";
  爆発アニメEle.style.width = "200px";
  爆発アニメEle.style.height = "100px";
  爆発アニメEle.style.right = 0;
  爆発AnimeEle.style.bottom = 0;
  const 爆発プレイヤー = lottie.loadAnimation({
    コンテナ: 爆発アニメエレ、
    レンダラー: "svg",
    ループ: false、
    自動再生: 有効、
    パス: "./9990-explosion.json",
  });
  爆発プレイヤー.setSpeed(0.3);
  // 再生が完了したら、爆発関連のアニメーションと要素を破棄します。explosionPlayer.addEventListener("complete", () => {
    爆発プレイヤーを破壊します。
    爆発アニメEle.remove();
  });
}

playExplosion() 関数は、全画面アニメーションが開始される位置であるアンカーを受け取ります。この例のアニメーションは比較的小さいため、最後に送信されたメッセージの下に固定されます。ここでは、爆発アニメーションのアンカーはメッセージ要素です。次に、関数は次の操作を実行します。

  • フルスクリーンアニメーション要素を追加し、絶対位置、幅 200 ピクセル、高さ 100 ピクセルに設定して、最新ニュース要素の右下隅に配置します。
  • lottie アニメーションをロードします。ループなし、自動再生です。
  • 元のアニメーション速度が速すぎるため、ここでlottieインスタンスのsetSpeed()メソッドを呼び出して速度を0.3倍に設定します。
  • 次に、Lottie インスタンスのイベント リスナー「complete」を設定します。これは、アニメーションが完了するとトリガーされ、Lottie インスタンスと全画面アニメーション要素が破棄されます。

このようにして、フルスクリーンアニメーション効果が実現されます。次に、メッセージ シェイクのコードを見てみましょう。

関数shakeMessages() {
  [...パネル要素.children]
    。逆行する()
    .スライス(0, 5)
    .forEach((メッセージ要素) => {
      定数 avatarEle = messageEle.querySelector("img");
      定数msgContentEle = messageEle.querySelector("p");
      avatarEle.classList.remove("shake");
      msgContentEle.classList.remove("shake");
      タイムアウトを設定する(() => {
        avatarEle.classList.add("shake");
        msgContentEle.classList.add("shake");
      }, 700);
    });
}

この機能の動作は次のとおりです。

  • 最新の 5 つのメッセージをシャッフルするには、reverse() と slice() を使用します。5 を大きくして、より多くのメッセージをシャッフルすることもできます。
  • そしてループ内で、アバターとメッセージにshakeクラスを追加して、揺れるアニメーションを実行します。このクラスの内容については後ほど紹介します。
  • アニメーションを実行するためにシェイク クラスを追加する前に、まずシェイクを削除する必要があることに注意してください。これは、複数の爆弾絵文字が連続して送信された場合など、一部のメッセージが以前にシェイクされている可能性があるためです。後からシェイククラスを追加した際に、setTimeout() を使って 700 ミリ秒遅延させました。フルスクリーンアニメーションがある程度実行されたときにメッセージをシェイクさせるのが目的です。

次に、shake クラスの定義を確認し、style.css に次のコードを追加します。

.シェイク{
  アニメーション: 0.8 秒のシェイク、イーズインアウト。
}
@keyframes シェイク {
  から {
    変換: translate3d(0, 0px, 0px);
  }
  10% {
    変換: translate3d(6px, -6px, 0px);
  }
  20% {
    変換: translate3d(-5px, 5px, 0px);
  }
  30% {
    変換: translate3d(4px, -4px, 0px);
  }
  35% {
    変換: translate3d(-3px, 3px, 0px);
  }
  39% {
    変換: translate3d(2px, -2px, 0px);
  }
  41% {
    変換: translate3d(-1px, 1px, 0px);
  }
  42% {
    変換: translate3d(0px, 0px, 0px) 回転(20度);
  }
  52% {
    変換: 回転(-15度);
  }
  60% {
    変換: 回転(8度);
  }
  65% {
    変換: 回転(-3度);
  }
  67%
    変換: 回転(1度);
  }
  70% {
    変換: 回転(0度);
  }
  に {
    変換: translate3d(0px, 0px, 0px) 回転(0);
  }
}

シェイク キーフレームで定義されたアニメーションは.shakeで使用され、実行時間は 0.8 秒、アニメーション実行関数は easy-in-out です。キーフレームにはたくさんのコードがありますが、どれも非常にシンプルです。爆発の効果をシミュレートし、X軸とY軸のオフセットを動かします。オフセットの振幅が小さくなるにつれて速度が増し、パーセンテージ間隔がどんどん小さくなっているのがわかります。アニメーションの 42% で、着地時の振動効果を作成するために回転アニメーションが追加されました。 rotate() を使用する場合の回転軸は要素の中央にあるため、メッセージ バブルの軸を変更して、よりリアルな効果を実現できます。

.メッセージ p {
  transform-origin: 左下;
}
.message.mine p {
  transform-origin: 右下;
}

ここでは、相手が送信したメッセージの軸を左下に設定し、自分が送信したメッセージを右下に設定します。

要約する

現在、WeChat 8.0 アニメーション絵文字をシミュレートする機能が実現されています。主なポイントは次のとおりです。

  • lottie ライブラリを使用してアニメーションを読み込んで再生します。
  • フルスクリーンアニメーションの位置とタイミングを決定します。
  • メッセージが揺れるアニメーションの CSS 実装。

学びましたか?ご質問やご提案がありましたら、コメントを残してください。この記事が気に入ったら、「いいね!」またはフォローしてください。今後、さらに興味深い記事を投稿する予定です。ありがとうございます!

著者: Fenghua、紹介: フロントエンドエンジニアが、直感的かつ専門的な方法でプログラミングの知識を共有します。 Bilibili UP@Fenghua フロントエンドエンジニア

この記事のすべてのアドレス:

例のアドレス: https://codechina.csdn.net/mirrors/zxuqian/html-css-examples

コードアドレス: https://codechina.csdn.net/mirrors/zxuqian/html-css-examples/-/tree/master/31-05-wechat-emoji-effect

lottie: https://cdnjs.com/libraries/bodymovin 、lottie.min.js をダウンロード

カボチャの絵文字: https://lottiefiles.com/43215-pumpkins-sticker-4

爆弾の絵文字: https://lottiefiles.com/3145-bomb

爆発アニメーション: https://lottiefiles.com/9990-explosion

ロッティー公式サイト: https://airbnb.io/lottie

300行以上のCSSコードを使用してWeChat 8.0の爆発特殊効果を実現する方法についての記事はこれで終わりです。WeChat 8.0の爆発特殊効果に関するより関連性の高いコンテンツについては、123WORDPRESS.COMの過去の記事を検索するか、以下の関連記事を引き続き閲覧してください。皆様の今後の123WORDPRESS.COMへのご支援をお待ちしております。

<<:  Vue.js アプリケーションのパフォーマンス最適化分析 + ソリューション

>>:  水平スクロールバーを実装する2つの方法の例

推薦する

CentOS7 での MySQL 8.0.16 のインストールと設定のチュートリアル

MySQLの古いバージョンをアンインストールします(古いバージョンがない場合は、この手順をスキップし...

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

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

MYSQL ロック解除とロックテーブルの紹介

MySQL ロックの概要他のデータベースと比較すると、MySQL のロック メカニズムは比較的単純で...

Vueでシングルサインオンを実装する方法のまとめ

最近プロジェクトが中断され、RageFrame の研究は一時的に終了しました。この記事では、シングル...

Vueウォッチの監視方法の概要

目次1. Vueにおけるwatchの役割はその名の通り、監視の役割です。 2. このオブジェクトのプ...

jQueryは記事の折りたたみと展開の機能を実装します

この記事の例では、記事の折りたたみと展開の機能を実現するためのjQueryの具体的なコードを参考まで...

フォント宝庫 50 種類の素晴らしい無料英語フォントリソース パート 1

デザイナーは独自のフォント ライブラリを持っているため、プロジェクトの設計時にすぐに使用できます。今...

MySQL CHARとVARCHARの選択方法

目次VARCHAR 型と CHAR 型結論: VARCHAR 型と CHAR 型VARCHAR と ...

MySQL 子テーブルで外部キー制約チェックを無効にする方法

準備する:教師テーブルと生徒テーブルを定義し、生徒テーブルで教師テーブルIDを参照します。テーブルt...

jQueryは従業員情報の追加と削除の機能を実装します

この記事では、従業員情報の追加と削除の機能を実装するためのjQueryの具体的なコードを参考までに共...

DIVのぼかし機能を実装する方法

マウスを動かしたときにDIVが消えるように手ぶれ補正を使用するdiv タグ自体は onblur イベ...

Pure CSS と Flutter はそれぞれブリージング ライト効果を実現します (サンプル コード)

前回、非常に熱心なファンから、月を呼吸する光の効果にできるかどうか尋ねられました。月の大きさの写真が...

Linux での JDK のインストール (OpenJDK のアンインストールを含む) の概要

1. openjdkを表示する rpm -qa|grep jdk 2. openjdk を削除します...

Windows Server win2003、win2008R2、win2012、win2016、win2019 システム バージョン間の違い

最近、Microsoft は 2019 サーバー システムをリリースしました。一般的に、Micros...

Dockerコンテナはルーティングを介して直接通信し、ネットワーク通信を実現します。

概要Docker 自体の現在のデフォルト ネットワークについては、単一ホスト上の異なる Docker...