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.
- Để lấy được URL của sprite image thì mình dùng tool Inspect, URL sẽ nằm ở phần
background-image - Example URL: https://zalo-api.zadn.vn/api/emoticon/sprite?eid=45349&size=130&checksum=b3f81751b002b8838b6caa265c4d19c0
- Sau đó bạn có thể upload lại image này lên một site khác hoặc để ở local (phòng trường hợp có thể sau này Zalo sẽ thay đổi pattern hay remove sticker này).
- Mình sẽ tạo một
divvà dùngCSSđể 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-positionkết hợp vớisetIntervalđể làm sticker chuyển động liên tục.
- Thuộc tính
background-positioncầ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
heightcủa sprite image. Ví dụ một sprite image get từ Zalo cówidth = 2210&height = 130thì mỗi lần thay đổibackground-positionmình sẽ+130cho tới khi = width thì set lại về 0. - Vậy nên mình tận dụng built-in function
onloadcủaImagetrong JS vừa để add image src và vừa get đượcwidthvàheightcủ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.
- 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
.lottiethì mình sẽ load vào trong player của dotLottie là xong, full code ở đây nha.
- Và đây là kết quả hiển thị một sticker của Telegram (Frog by @shurmin_jpg).
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
tvqqq • Updated Jun 9, 2023