How Facebook Messenger Animates their Stickers
Not too long ago, I wanted to copy an animated Facebook sticker to use on another messaging platform. The general technique I’ve used for most digital images on the web is something likeright click
> Copy image
and move on. Not all websites make it this easy, you can’t right-click and copy images on Instagram because of the website layout. From what I can tell at the time of writing this, there are two div elements sandwiching the image which essentially “protect” it from any user interaction, almost like a digital equivalent of a laminated sheet of paper. You can still see the contents just fine, but you aren’t going anywhere with that original image anytime soon.
Other sites, like Imgur, even manipulate the actual file type. I have no idea how they do this, but anyone can upload an animated GIF and some Imgur magic converts the file to a GIFV format, which also means that browsers recognize this as a video, and trying to right-click on it would bring up the video playback context menu (with Play, Pause, Stop, etc.), and, you guessed it, no “Copy image” option either.
If you’ve ever tried to right click on a sticker from a Facebook Messenger chat, you seemingly run into the same issue sticker on Facebook.
So how does Facebook Messenger do it?
I poked around through Messenger.com on Chrome and discovered something interesting: animated stickers are actually displayed as a div element with a set height and width, and then a background image repositioned at set intervals, presumably with Javascript. This div element essentially acts like a “window” that only shows a small bit of the entire background at a time, similar to a digital zoetrope.
Here’s an example of what I mean. In the following gif (which you can right-click and save if you so desire), I’ve placed my Chrome DevTools window next to my Messenger chat. Before hovering my mouse over the sticker, the background-position
property has a value of “-12px -12px”. As the animation plays, the background-position
values (and only the background-position
values) change rapidly, corresponding with the changing “frames” of the “animation”.
The image for this particular animation can be found below.
I thought this was an interesting way of rendering animations on the web, and hadn’t yet read anything else about the topic. I’d imagine this was implemented as a way to have more control over the speed of animations, you can retroactively adjust the FPS quite easily with this method by simply adjusting the Javascript, whereas if you had to rely on embedded gifs, adjusting the frame rate would mean adjusting the entire image itself. Another advantage to this technique is transparency: .gif files don’t support translucency (e.g. every pixel must be entirely opaque or entirely transparent, there’s no in between), but .png files do. So if you want to display animations with varying degrees of opacities, this could be the way to go!