Nhúng stickers động từ Telegram và Zalo vào blog Notion
🟡

Nhúng stickers động từ Telegram và Zalo vào blog Notion

Category
Coding
Tags
Web Dev
Published Date
Jun 9, 2023
Gần đây thì mình có làm một idea là tích hợp những stickers từ Telegram và Zalo để hiển thị trên blog này, vấn đề nếu sticker là ảnh tĩnh (static image) thì chỉ cần copy & paste là xong.
Tuy nhiên mình thì thích những sticker động (animation) hơn và vấn đề là nếu như mình convert sang ảnh gif thì chất lượng sẽ bị giảm và có background nền trắng phía sau (theme blog mình lại là Dark mode 😎). Sau khi tìm hiểu một số platform có nhiều sticker động thì mình chọn được Zalo & Telegram để get sticker 🧑‍💻.
 
Để có thể nhúng được sticker vào trong Notion thì mình sẽ build một mini site và cho các sticker play trên site đó, sau đó mình sẽ embed mini site vào trong page Notion (thông qua tính năng embed website đã có sẵn trong Notion).
Ở bài viết này mình sẽ viết chi tiết về cơ chế stickers được hiển thị ở mini site.

Zalo

  • Với Zalo thì các sticker động chỉ là một sprite animation. Tức là có một ảnh 2D lớn gồm nhiều phần ảnh nhỏ, mỗi phần là một cử động. Khi mình lướt nhanh những phần ảnh nhỏ đó sẽ thấy nó chuyển động mượt.
 
  • Mình sẽ tạo một div và dùng CSS để tạo sprite image (Zalo Web cũng sử dụng cách này)
    • <div style="display: block"> <div id="sticker"></div> </div>
      <style> #sticker { margin: 0 auto; width: 130px; height: 130px; background-position: 0 0; background-repeat: repeat-x; } </style>
  • Để lướt nhanh các phần ảnh nhỏ trong một ảnh lớn thì dùng Javascript (or jQuery) để thay đổi background-position kết hợp với setInterval để làm sticker chuyển động liên tục.
  • Thuộc tính background-position cần được tính toán để có thể “cắt” đúng vị trí nối giữa các phần ảnh nhỏ
    • Cách tính thì mình sẽ dựa vào height của sprite image. Ví dụ một sprite image get từ Zalo có width = 2210 & height = 130 thì mỗi lần thay đổi background-position mình sẽ +130 cho tới khi = width thì set lại về 0.
    • Vậy nên mình tận dụng built-in function onload của Image trong JS vừa để add image src và vừa get được widthheight của image (image được truyền qua query string của url).
    • const stickerEl = $("#sticker"); const img = new Image(); let stickerWidth = 2210; let stickerHeight = 130; img.onload = function () { stickerWidth = this.width; stickerHeight = this.height; stickerEl.css( "background-size", stickerWidth + "px " + stickerHeight + "px" ); }; img.src = stickerUrl; stickerEl.css("background-image", "url(" + stickerUrl + ")");
      setTimeout(function () { const maxX = stickerWidth; let x = 0; setInterval(function () { x += stickerHeight; if (x >= maxX) { x = 0; } $("#sticker").css("background-position", "-" + x + "px 0"); }, 100); }, 500);
  • Full code cho phần sticker Zalo thì bạn xem ở link này nhé:
  • Và đây là kết quả hiển thị một sticker của Zalo (Ami bụng bự)

Telegram

  • Với sticker lấy từ Telegram thì hơi phức tạp một chút, vì Telegram dùng file có format .tgs để làm sticker động. Và để hiển thị được file tgs này lên web thì mình cần dùng một animation library nổi tiếng là Lottie.
  • Trước đây mình tìm hiểu thì Lottie sẽ nhận input là file JSON, nhưng mình vừa phát hiện thì Lottie cũng vừa có một library mới support định dạng mới .lottie (file này sẽ nhẹ hơn JSON vì đã được compressed). Các bạn có thể tìm hiểu thêm tại: https://dotlottie.io/.
  • Đây là diagram các bước cần để convert một sticker từ Telegram cho tới có thể play được trên dotLottie player.
notion image
  • Mình đang làm một con bot Telegram để tự động hoá các bước trên vì hiện tại mình đang làm thủ công nên sẽ không giới thiệu ở bài viết này (khá rắc rối 😮‍💨)
  • Khi có file .lottie thì mình sẽ load vào trong player của dotLottie là xong, full code ở đây nha.
 
Nếu bạn có idea hoặc optimize thêm thì tạo PR cho source code này nhé vì mình chỉ build nhanh để adapt được blog mình nên chưa customize đủ flexible để làm một template chung 🙇 
sticker-play
tvqqqUpdated Jun 9, 2023