主頁 >  其他 > 讓微信 8.0 「裂開」「炸彈」的特效代碼來了

讓微信 8.0 「裂開」「炸彈」的特效代碼來了

2021-01-29 13:24:36 其他

微信 8.0 更新的一大特色就是支持影片表情,如果發送的訊息只有一個內置的表情圖示,這個表情會有一段簡單的影片,一些特殊的表情還有全屏特效,例如煙花表情有全屏放煙花的特效,炸彈表情有爆炸影片并且訊息和頭像也會隨之震動,本著作為前端工程師的職業精神,我就想看看能不能實作一個類似的特效,折騰許久之后,做出來的效果如下:

demo.gif

專案的核心是使用到了 lottie 影片庫,Lottie 是 Airbnb 出品的、全平臺(Web、Android、IOS、React Native)的影片庫,它的特點在于能夠直接播放使用 Adobe After Effects 制作的影片,設計師在 After Effects 中,利用 Bodymovin 插件把影片匯出為 JSON 格式之后,開發者就能夠通過相應平臺的 SDK 進行播放,

  • Lottie 官網:https://airbnb.io/lottie

在做完這個專案之后我感覺到自己的前端儲備又豐富了一層,在以后應對復雜特效時又有了新的思路,如果你也想進一步提升前端開發技能,可以跟著這篇文章實踐一下,本篇文章除了使用 lottie 庫之外,全部都是使用原生 HTML/CSS/JavaScript 實作的,這樣無論你是 React、Vue 還是其它工程師,都可以快速掌握,

一、撰寫界面

本來想跳過 HTML/CSS 部分,但是想到 CSS 可能是大部分人的弱項,所以我決定還是把實作界面的思路寫一下,想看核心部分的可以直接跳到:二、發送普通訊息部分,

1. HTML 部分

首先看 HTML 部分,從效果圖來看:

  • 上邊有一個標題欄,顯示與 XXX 聊天,
  • 中間是聊天資訊面板,包含著雙方發送的訊息,每條訊息由發送者頭像和訊息內容組成,我發送的在右側,對方發送的在左側,
  • 下方是底部資訊,有表情選擇按鈕、編輯訊息文本框和發送按鈕,

那么根據這個結構撰寫的 HTML 代碼如下所示:

<main>
  <div class="chat">
    <div class="titleBar">與 XXX 聊天</div>
    <div class="panel">
      <div class="message mine">
        <img src="./me.png" alt="" />
        <p><span>你好</span></p>
      </div>
      <div class="message yours">
        <img class="avatar" src="./you.png" alt="" />
        <p><span>Hi</span></p>
      </div>
      <!-- 省略其它訊息 -->
    </div>
    <footer>
      <button class="chooseSticker">
        <img src="./emoji.svg" alt="" />
        <div class="stickers"></div>
      </button>
      <input
             class="messageInput"
             type="text"
             name=""
             id=""
             placeholder="請輸入聊天資訊"
             />
      <button class="send">發送</button>
    </footer>
  </div>
</main>

各個元素所對應的界面部分為:

  • <main /> 元素是一個整體的容器,用于把聊天視窗居中對齊

  • <div class="chat"> 是聊天應用的容器,用于布局標題欄、聊天面板和底部發送框,

  • <div class="titleBar"> 用于顯示標題欄,

  • <div class="panel"> 是訊息面板,用于布局其中的訊息,

  • <div class="message"> 為訊息容器,使用不同的 class 來區分發送方, mine 代表我發送的, yours 代表對方發送的,每條訊息里邊使用 <img class="avatar" > 來展示頭像,使用 <p> 元素來顯示文本, <p> 元素里邊的 <span> 元素將會作為 lottie 的容器來播放表情影片,

  • <footer> 用于布局底部操作按鈕和訊息發送框,其中:

    • <button class="chooseSticker"> 是表情選擇按鈕,使用一個笑臉 svg 圖片表示,里邊的 <div class="stickers"> 是表情選擇框彈出層,里邊的表情將在 JS 中動態加載,目的是為了實作影片預覽,
    • <input class="messageInput" /> 是聊天訊息輸入框,沒什么特別的,
    • <button class="send"> 是發送按鈕

這個是 HTML 的基本結構,接下來看一下 CSS 樣式,

2. CSS 部分

在專案根目錄下創建一個 style.css 檔案并在 index.html 的 標簽中引入:

<link rel="stylesheet" href="style.css" />

1)全域樣式

首先定義一些 CSS 變數,CSS 變數是為了方便我們參考同一屬性值的,后邊如果更新樣式時,可以避免多次修改:

:root {
  --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);
}

這些變數的含義分別是:

  • --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) ,小陰影,例如輸入框和表情選擇彈出層,

接下來是一些重置樣式:

* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
  font-family: Helvetica, "PingFang SC", "Microsoft Yahei", sans-serif;
}

這些樣式對所有元素都有效,設定盒子模型為 border-box ,這樣內邊距、邊框都算在寬高之內,設定內間距和外間距為 0,最后設定默認字體,

2)Main 容器

Main 容器用于定位聊天應用容器到瀏覽器中間,使用 grid 布局,寬高分別設定為瀏覽器可視區域的 100%,并把背景色設定為黑灰色:

main {
  display: grid;
  place-items: center;
  width: 100vw;
  height: 100vh;
  background-color: hsl(0, 0%, 10%);
}

3)聊天應用容器

聊天應用容器設定了固定寬高,模擬手機螢屏,并使用 grid 布局來控制標題欄、聊天面板和底部操作欄的位置:

.chat {
  width: 375px;
  height: 700px;
  background: hsl(0, 0%, 100%);
  border-radius: 8px;
  display: grid;
  grid-template-rows: max-content 1fr max-content;
}

這里使用了 grid-template-rows 把聊天應用分成了 3 行,第一行的標題欄和最后一行的標底部操作欄的高度分別為內容的最大高度,中間的聊天面板則是浮動高度,

4)標題欄

標題欄簡單的設定了一個內間距、文字居中方式和陰影:

.titleBar {
  padding: 24px 0;
  text-align: center;
  box-shadow: var(--shadow-large);
}

界面優化提示:內間距用來增加留白,在視覺上引起放松,陰影則為了和下邊的聊天面板區分開

5)聊天面板

聊天面板使用 flex 布局對其中的訊息進行排列,并設定方向為按列排布,然后設定 overflow 為 auto,在訊息整體高度超出面板高度時,出現滾動條:

.panel {
  display: flex;
  flex-direction: column;
  padding: 24px 12px;
  overflow: auto;
}

界面優化提示:這里的 padding 同樣是為了留出足夠多的空白,來與其它元素隔開一段距離,以避免擁擠感,

6)訊息

訊息分為訊息容器、頭像和訊息體 3 個部分,其中訊息體和頭像包含在訊息容器中,先來看訊息容器的樣式,訊息容器使用 flex 布局來把訊息體和頭像放在一行,寬度最大為面板寬度的 80%,并設定字體和外邊距:

.message {
  display: flex;
  max-width: 80%;
  font-size: 14px;
  margin: 8px 0;
  position: relative;
}

這里的 position 設定為 relative 是為了定位后邊的全屏特效影片,

頭像簡單設定了寬高、圓角和距離訊息體的間距:

.message img {
  width: 40px;
  height: 40px;
  border-radius: 12px;
  margin-right: 12px;
}

界面優化提示:這里不得不再提一下間距的重要性,一定不要把各個元素安排的太過緊湊,否則十分影響視覺效果,最直接的影響就是引起視覺上的擁擠感,造成視覺疲勞,

訊息體同樣的設定了間距和圓角,這里的圓角和頭像的保持一致,以增加和諧感,它還設定了陰影,并使用 flex 布局,把里邊的文字或表情訊息居中對齊:

.message p {
  padding: 8px 12px;
  border-radius: 12px;
  box-shadow: var(--shadow-large);
  display: flex;
  align-items: center;
}

這些樣式默認都是基于對方的訊息的,如果是我發送的訊息需要放到右邊,并作一些調整,首先對于我發送的訊息,把 flex-flow 改為 row-reverse 這樣頭像和訊息體的位置就互換了,然后使用 align-self 對齊到面板的右邊:

.message.mine {
  flex-flow: row-reverse;
  align-self: flex-end;
}

調整頭像的外邊距,現在應該是距離左邊的訊息體的邊距了:

.message.mine img {
  margin-right: 0;
  margin-left: 12px;
}

設定訊息體的背景色為藍色,文字為白色:

.message.mine p {
  background-color: var(--primary-color);
  color: white;
}

7)底部操作欄

先看底部操作欄容器的整體布局,使用 grid 布局把表情選擇按鈕、訊息發送框和發送按鈕分成 3 列,其中除訊息發送框為浮動寬度外,其它的兩個按鈕為固定寬度,默認居中對齊,最后設定陰影和間距:

footer {
  display: grid;
  grid-template-columns: 48px 1fr 75px;
  justify-items: center;
  padding: 12px;
  box-shadow: var(--shadow-large);
}

表情選擇按鈕把自己進行了靠左對齊,并設定相對定位,用于定位表情選擇彈出層,然后設定按鈕圖示的大小:

.chooseSticker {
  justify-self: start;
  position: relative;
}
.chooseSticker img {
  width: 36px;
  height: 36px;
}

表情選擇彈出層的 CSS 代碼比較多但都很簡單,先看一下代碼:

.stickers {
  display: grid;
  grid-template-columns: repeat(auto-fill, 24px);
  column-gap: 18px;
  
  border-radius: 8px;
  background-color: white;
  box-shadow: var(--shadow-medium);
  padding: 6px 12px;
  font-size: 24px;
  
  position: absolute;
  top: calc(-100% - 18px);
  width: 300px;
  opacity: 0;
}

這段代碼的含義是:

  • 彈出層使用 grid 布局,repeat(auto-fill, 24px) 指的是在寬度允許的條件下,在一行中盡可能放置最多的列元素,每列的寬度固定為 24px,然后設定列間距為 18px,
  • 設定圓角、背景色、陰影、內間距和字體大小,
  • 定位設定為絕對定位,把它向上移動包含元素高度(也就是 .chooseSticker 的高度)的 100% 并減去 18px,調整到合適的位置,寬度設定為 300px,透明度設定為 0 把它隱藏,

訊息輸入框和按鈕的樣式比較簡單,訊息輸入框的寬度占滿整列,發送按鈕使用 justify-self: end 把自己進行靠右對齊,這里把代碼一次性貼出來:

.messageInput {
  box-shadow: var(--shadow-medium);
  padding: 0px 12px;
  border-radius: 8px;
  width: 100%;
}

.send {
  height: 100%;
  width: 90%;
  border-radius: 8px;
  justify-self: end;
  color: white;
  background-color: var(--inverse-color);
}

最后再添加一個 .show 樣式,用于在點擊發送表情按鈕時,給表情彈出層添加該樣式以顯示出來:

.show {
  opacity: 1;
}

3. JS 部分

在給聊天界面加上功能之前,先撰寫一些基礎的 JS 代碼,在專案根目錄創建一個 index.js 檔案,并在 index.html 中參考,注意放到 關閉標簽的上方,這樣當 HTML DOM 加載完成之后才會執行 js 中的代碼,防止找不到元素:

 <body>
   <!-- 其它代碼省略 -->
   <script src="index.js"></script>
 </body>

在 index.js 中,先獲取要操作的 DOM 元素:

const panelEle = document.querySelector(".panel");
const chooseStickerBtn = document.querySelector(".chooseSticker");
const stickersEle = document.querySelector(".stickers");
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("click", () => {
  const msg = msgInputEle.value;
  if (msg) {
    appendMsg(msg);
  }
});

在事件處理函式中:

  • 判斷用戶是否輸入了訊息,
  • 如果輸入了就追加到訊息串列中,

來看一下 appendMsg() 函式的代碼:

function appendMsg(msg, type) {
  // 創建訊息元素
  const msgEle = panelEle.appendChild(document.createElement("div"));
  msgEle.classList.add("message", "mine"); // 設定為“我“發送的樣式
  msgEle.innerHTML = `
    <img class="avatar" src="./me.png" alt="" />
    <p><span>${msg}</span></p>
  `;
  // 滾動到最新訊息
  panelEle.scrollTop = panelEle.scrollHeight;
  msgInputEle.value = "";
}

函式接收兩個引數,msg 和 type,分別是要追加的訊息內容和型別,type 為可選的,不傳則認為是普通文本訊息,如果傳遞了 “stickers” 則為表情訊息,現在還用不到它,在這個函式中主要做了下面幾件事情:

  • 按照訊息的 HTML 結構創建一個新的訊息元素 msgEle,并追加到訊息串列中,
  • 把訊息的樣式設定為我發送的,
  • 內部的元素分別為頭像和文本訊息,使用模板字串的形式賦值給 msgEle 的 innerHTML 屬性中,并在 <p> 中使用 msg 變數的值,
  • 最后把滾動條滾動到最新的訊息處,并清空輸入框中的訊息,

這樣就可以發送普通的文本訊息了,

三、發送影片表情

在發送影片表情之前,需要先加載影片表情,在 index.js 的最上方先定義表情名稱和表情影片檔案路徑的鍵值對資訊:

const stickers = {
  bomb: {
    path: "./3145-bomb.json",
  },
  pumpkin: {
    path: "./43215-pumpkins-sticker-4.json",
  },
};

我們會根據 bombpumkin 這樣的 key 來找到對應的影片路徑,接著初始化彈出層中的表情以供用戶選擇:

// 初始化表情面板,也可以在表情選擇窗彈出時再初始化
Object.keys(stickers).forEach((key) => {
  const lottieEle = stickersEle.appendChild(document.createElement("span"));
  // 對每個表情創建 lottie 播放器
  const player = lottie.loadAnimation({
    container: lottieEle,
    renderer: "svg",
    loop: true,
    autoplay: false,
    path: stickers[key].path,
  });

  // 當選擇表情時,發送訊息,并設定型別為 sticker 表情訊息
  lottieEle.addEventListener("click", () => {
    appendMsg(key, "sticker");
  });

  // 當滑鼠劃過時,播放影片預覽
  lottieEle.addEventListener("mouseover", () => {
    player.play();
  });
  // 當滑鼠劃過時,停止影片預覽
  lottieEle.addEventListener("mouseleave", () => {
    player.stop();
  });
});

這里的代碼分別作了下邊這些操作:

  • 遍歷存盤表情資訊的物件,

  • 創建一個 lottie 的容器,使用 span 元素,因為 lottie 影片的播放器需要掛載到一個具體的 html 元素中,

  • 呼叫 lottie 的 loadAnimation() 加載影片,它需要傳遞這樣幾個引數:

    • container: 播放器要掛載到的容器,
    • renderer:可以選擇是使用 svg 還是 canvas 渲染影片,
    • loop: 是否回圈播放,由于此處是在表情選擇彈出層中預覽影片,所以支持回圈播放,
    • autoplay:是否自動播放,這里設定為了否,后邊讓它在滑鼠劃過時再播放影片,
    • path:影片 json 檔案路徑,直接從物件中獲取,
  • loadAnimation() 會回傳 lottie 的實體,把它保存在 player 中,

然后后邊則注冊了幾個事件:

  • 當 lottieEle 也就是表情被點擊時,發送表情訊息,給 appendMsg() 的 msg 引數設定為表情的 key,type 引數設定為 “sticker”,
  • 當滑鼠劃過表情時,開始播放影片,
  • 當滑鼠劃出表情時,停止影片,

接著給發送表情按鈕添加事件,點擊時,切換表情彈出層的顯示狀態:

chooseStickerBtn.addEventListener("click", () => {
  stickersEle.classList.toggle("show");
});

這時點擊發送表情按鈕就可以看到表情選擇彈出層了,現在還不能發送表情,因為還沒在 appendMsg() 函式中處理,現在來修改一下它里邊的代碼,首先判斷:如果是表情訊息,則不在訊息中的 <p> 元素里添加任何資訊:

function appendMsg(msg, type) {
 // ... 
  msgEle.innerHTML = `
    <img class="avatar" src="./me.png" alt="" />
    <p><span>${type === "sticker" ? "" : msg}</span></p>
  `;
}

然后在它的下方,呼叫 playSticker() 函式來播放影片:

// 處理表情訊息,播放相關影片
if (type === "sticker") {
  playSticker(msg, msgEle);
}

playSticker() 函式接收兩個引數,一個是表情的 key,一個是訊息元素,此時的 msg 變數的內容就是在 lottieEle 點擊事件中傳遞過來的表情 key,函式中的代碼如下:

function playSticker(key, msgEle) {
  // 表情訊息,創建 lottie 影片
  const lottieEle = msgEle.querySelector("span");
  lottieEle.style.width = "40px";
  lottieEle.style.height = "40px";
  lottie.loadAnimation({
    container: lottieEle,
    renderer: "svg",
    loop: false,
    autoplay: true,
    path: stickers[key].path,
  });
}

在這個函式里主要做了下邊幾項操作:

  • 獲取訊息中的 span 元素,它將作為 lottie 的影片容器,
  • 設定表情影片的寬高為 40px,
  • 使用 lottie 加載影片,并設定回圈播放為 false,自動播放為 true,來讓表情發送時自動播放影片,且只播放一次,

現在可以發送表情訊息了,相關的影片也會自動播放,接下來看一下怎么實作炸彈的全屏影片和對訊息元素的晃動效果,

四、發送帶全屏特效的表情

對于這種帶全屏特效的表情可以單獨進行判斷,也可以在保存表情的物件中定義相關的操作,這里為了簡單起見,我們單獨判斷用戶是否發送了炸彈表情,然后施加相應特效,

首先在 appendMsg() 函式里,進行判斷,如果發送的訊息是表情訊息,且表情為炸彈,則播放全屏影片并晃動訊息:

function appendMsg(msg, type) {
  if (type === "sticker") {
    playSticker(msg, msgEle);
    if (msg === "bomb") {
      // 播放爆炸影片
      setTimeout(() => {
        playExplosion(msgEle);
      }, 800);
      // 晃動訊息串列
      shakeMessages();
    }
  }
}

這里爆炸全屏影片延遲了 800 毫秒之后再執行,目的是在炸彈表情播放到合適的時間時,再播放全屏影片,播放影片使用了 playExplosion() 函式,并傳遞了訊息元素進去,在爆炸全屏影片結束之后,呼叫 shakeMessages() 來晃動訊息,這里先看一下 playExplosion() 函式的代碼:

function playExplosion(anchor) {
  const explosionAnimeEle = anchor.appendChild(document.createElement("div"));
  explosionAnimeEle.style.position = "absolute";
  explosionAnimeEle.style.width = "200px";
  explosionAnimeEle.style.height = "100px";
  explosionAnimeEle.style.right = 0;
  explosionAnimeEle.style.bottom = 0;

  const explosionPlayer = lottie.loadAnimation({
    container: explosionAnimeEle,
    renderer: "svg",
    loop: false,
    autoplay: true,
    path: "./9990-explosion.json",
  });
  explosionPlayer.setSpeed(0.3);
  // 播放完成后,銷毀爆炸相關的影片和元素
  explosionPlayer.addEventListener("complete", () => {
    explosionPlayer.destroy();
    explosionAnimeEle.remove();
  });
}

playExplosion() 函式接收一個 anchor 錨點,就是說基于哪個位置開始播放全屏影片,由于示例中的影片畫幅比較小,所以把它固定在了最新發送的訊息的下方,這里爆炸影片的 anchor 就是訊息元素,之后函式做了下邊的這些操作:

  • 添加全屏影片元素,設定為絕對定位,寬度 200px,高度 100px,放在最新訊息元素的右下角,
  • 加載 lottie 影片,不回圈、自動播放,
  • 由于原影片速度過快,這里呼叫 lottie 實體的 setSpeed() 方法,把速度設定為 0.3 倍速,
  • 之后給 lottie 實體設定事件監聽:“complete”,它會在影片執行完成時觸發,里邊銷毀了 lottie 實體和全屏影片元素,

這樣全屏影片的效果就實作了,接下來看訊息晃動的代碼:

function shakeMessages() {
  [...panelEle.children]
    .reverse()
    .slice(0, 5)
    .forEach((messageEle) => {
      const avatarEle = messageEle.querySelector("img");
      const msgContentEle = messageEle.querySelector("p");
      avatarEle.classList.remove("shake");
      msgContentEle.classList.remove("shake");
      setTimeout(() => {
        avatarEle.classList.add("shake");
        msgContentEle.classList.add("shake");
      }, 700);
    });
}

這個函式的操作是:

  • 使用 reverse() 和 slice() 對最新的 5 條訊息進行晃動,也可以把 5 改大一點,對更多訊息進行晃動,
  • 然后在回圈中,分別給頭像和訊息添加 shake class 執行晃動影片,這個 class 的內容稍后再介紹,
  • 要注意的是,在添加 shake class執行影片前,需要先洗掉 shake,因為有的訊息可能在之前已經晃動過了,例如當連續發了多個炸彈表情時,后邊在添加 shake class 時,使用 setTimeout() 延遲了 700 毫秒,目的是在全屏影片執行到一定程度時再晃動訊息,

接下來看一下 shake class 的定義,在 style.css 中添加下方代碼:

.shake {
  animation: shake 0.8s ease-in-out;
}

@keyframes shake {
  from {
    transform: translate3d(0, 0px, 0px);
  }
  10% {
    transform: translate3d(6px, -6px, 0px);
  }
  20% {
    transform: translate3d(-5px, 5px, 0px);
  }
  30% {
    transform: translate3d(4px, -4px, 0px);
  }
  35% {
    transform: translate3d(-3px, 3px, 0px);
  }
  39% {
    transform: translate3d(2px, -2px, 0px);
  }
  41% {
    transform: translate3d(-1px, 1px, 0px);
  }
  42% {
    transform: translate3d(0px, 0px, 0px) rotate(20deg);
  }

  52% {
    transform: rotate(-15deg);
  }

  60% {
    transform: rotate(8deg);
  }

  65% {
    transform: rotate(-3deg);
  }

  67% {
    transform: rotate(1deg);
  }

  70% {
    transform: rotate(0deg);
  }

  to {
    transform: translate3d(0px, 0px, 0px) rotate(0);
  }
}

.shake 中使用了 shake keyframes 定義的影片,執行時間為 0.8s,影片執行函式為 ease-in-out,Keyframes 里的代碼比較多,但是都是很簡單的,就是模擬了爆炸時的效果,移動 x 軸和 y 軸的偏移,每次的偏移幅度越來越小,并且越來越快,可以看到百分比的間隔越來越小,在影片進行到 42% 的時候,加了一些旋轉影片,這樣就有了落地時的震動效果,由于使用 rotate() 旋轉時的軸心在元素中間,我們可以把訊息氣泡的軸心修改一下來實作更真實的效果:

.message p {
  transform-origin: left bottom;
}
.message.mine p {
  transform-origin: right bottom;
}

這里把對方發送的訊息的軸心設定在左下角,自己發送的訊息則設定在了右下角,

五、專案檔案

所有需要用到的代碼和示例如下:

  • 示例地址:https://zxuqian.github.io/html-css-examples/31-05-wechat-emoji-effect/
  • 代碼地址:https://github.com/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

總結

現在,這個模擬微信 8.0 影片表情的功能就實作了,主要就是下邊幾點:

  • 使用 lottie 庫加載并播放影片,
  • 確定全屏影片的位置和播放時機,
  • 訊息晃動影片的 CSS 實作,

你學會了嗎?如果有問題或建議可以留個評論,喜歡此文章請點個贊或關注我,后邊還有更多更精彩的文章,感謝!

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/254026.html

標籤:AI

上一篇:清華團隊曝光「新冠病毒」3D高清結構照!這個惡魔已感染1億地球人

下一篇:IntelliJ IDEA 20周歲啦,為期2天的周年慶活動對開發者免費開放

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more