1675886220
Freezeframe.js is a library that pauses animated .gifs and enables them to animate on mouse hover / mouse click / touch event, or triggered manually.
Freezeframe is now written in / supports TypeScript! The library will still support usage in JavaScript, but if your project uses TypeScript, you'll have access to Freezeframe's type definitions, improved input validation, and depending on your IDE/text editor, autocompletion/intellisense.
To get started using freezeframe 5:
npm install freezeframe
npm install vue-freezeframe
npm install react-freezeframe
npm install angular-freezeframe
Version 5+ is built with modern development in mind. It's transpiled from TypeScript to JavaScript, and it should work in all modern browsers, but we are no longer supporting older browsers, or the jquery plugin.
If you need to support older browsers (and don't need TypeScript), try v4.x:
npm install freezeframe@4.1.3
If you want to use freezeframe as a jquery plugin, check out freezeframe v3.0.10.
This is a lerna.js monorepo, containing the following packages, each with their own docs:
For the curious, we are able to pause animated gifs by writing their data to a canvas element. Only the first frame of the animation can be written to the canvas, so we now have a frozen version of the gif.
Unfortunately, browser security prevents reading the actual data of the image if it is hosted on a different domain, which prevents us from being able to truly "pause" the gif on the true current frame. Supporting gifs on other domains is a requirement for this project, so the only frame you can pause on is the first frame.
npm install -g lerna
npm install
npm run bootstrap
npm test
npm run build
Then, submit your PR for review.
Author: ctrl-freaks
Source Code: https://github.com/ctrl-freaks/freezeframe.js
License: MIT license
1664931000
A Simple to use javascript .GIF decoder.
We needed to be able to efficiently load and manipulate GIF files for the Ruffle hybrid app (for mobiles). There are a couple of example libraries out there like jsgif & its derivative libgif-js, however these are admittedly inefficient, and a mess. After pulling our hair out trying to understand the ancient, mystic gif format (hence the project name), we decided to just roll our own. This library also removes any specific drawing code, and simply parses, and decompresses gif files so that you can manipulate and display them however you like. We do include imageData
patch construction though to get you most of the way there.
You can see a demo of this library in action here
Installation:
npm install gifuct-js
Decoding:
This decoder uses js-binary-schema-parser to parse the gif files (you can examine the schema in the source). This means the gif file must firstly be converted into a Uint8Array
buffer in order to decode it. Some examples:
fetch
import { parseGIF, decompressFrames } from 'gifuct-js'
var promisedGif = fetch(gifURL)
.then(resp => resp.arrayBuffer())
.then(buff => {
var gif = parseGIF(buff)
var frames = decompressFrames(gif, true)
return gif;
});
XMLHttpRequest
import { parseGIF, decompressFrames } from 'gifuct-js'
var oReq = new XMLHttpRequest();
oReq.open("GET", gifURL, true);
oReq.responseType = "arraybuffer";
oReq.onload = function (oEvent) {
var arrayBuffer = oReq.response; // Note: not oReq.responseText
if (arrayBuffer) {
var gif = parseGIF(arrayBuffer);
var frames = decompressFrames(gif, true);
// do something with the frame data
}
};
oReq.send(null);
Result:
The result of the decompressFrames(gif, buildPatch)
function returns an array of all the GIF image frames, and their meta data. Here is a an example frame:
{
// The color table lookup index for each pixel
pixels: [...],
// the dimensions of the gif frame (see disposal method)
dims: {
top: 0,
left: 10,
width: 100,
height: 50
},
// the time in milliseconds that this frame should be shown
delay: 50,
// the disposal method (see below)
disposalType: 1,
// an array of colors that the pixel data points to
colorTable: [...],
// An optional color index that represents transparency (see below)
transparentIndex: 33,
// Uint8ClampedArray color converted patch information for drawing
patch: [...]
}
Automatic Patch Generation:
If the buildPatch
param of the dcompressFrames()
function is true
, the parser will not only return the parsed and decompressed gif frames, but will also create canvas ready Uint8ClampedArray
arrays of each gif frame image, so that they can easily be drawn using ctx.putImageData()
for example. This requirement is common, however it was made optional because it makes assumptions about transparency. The demo makes use of this option.
Disposal Method:
The pixel
data is stored as a list of indexes for each pixel. These each point to a value in the colorTable
array, which contain the color that each pixel should be drawn. Each frame of the gif may not be the full size, but instead a patch that needs to be drawn over a particular location. The disposalType
defines how that patch should be drawn over the gif canvas. In most cases, that value will be 1
, indicating that the gif frame should be simply drawn over the existing gif canvas without altering any pixels outside the frames patch dimensions. More can be read about this here.
Transparency:
If a transparentIndex
is defined for a frame, it means that any pixel within the pixel data that matches this index should not be drawn. When drawing the patch using canvas, this means setting the alpha value for this pixel to 0
.
Check out the demo for an example of how to draw/manipulate a gif using this library. We wanted the library to be drawing agnostic to allow users to do what they wish with the raw gif data, rather than impose a method that has to be altered. On this note however, we provide an easy interface for creating commonly used canvas pixel data for drawing ease.
We underestimated the convolutedness of the GIF format, so this library couldn't have been made without the help of:
Author: Matt-way
Source Code: https://github.com/matt-way/gifuct-js
License: MIT license
1664411280
A Javascript library for creating animated GIFs
Include dist/Animated_GIF.js
in your HTML.
var imgs = document.querySelectorAll('img');
var ag = new Animated_GIF();
ag.setSize(320, 240);
for(var i = 0; i < imgs.length; i++) {
ag.addFrame(imgs[i], { delay: 1000 });
}
var animatedImage = document.createElement('img');
// This is asynchronous, rendered with WebWorkers
ag.getBase64GIF(function(image) {
animatedImage.src = image;
document.body.appendChild(animatedImage);
});
If you instance lots of Animated_GIF
objects, it's strongly recommended that you call their destroy
method once you're done rendering the GIFs, as browsers don't seem to be happy otherwise. See the stress test for an example of this in use!
There's a minified version in dist/
: dist/Animated_GIF.min.js
.
You can also use this via npm.
To install:
npm install --save animated_gif
To use:
var Animated_GIF = require('animated_gif');
// And then the examples are as before
var ag = new Animated_GIF();
ag.setSize(320, 240);
// ... etc
Pass an object with the desired values when creating an Animated_GIF
instance:
sampleInterval
: how many pixels to skip when creating the palette. Default is 10. Less is better, but slower.numWorkers
: how many web workers to use. Default is 2.useQuantizer
: this is true
by default, and provides the highest quality results, at the cost of slower processing and bigger files. When this is enabled, a neural network quantizer will be used to find the best palette for each frame. No dithering is available in this case, as the colours are chosen with the quantizer too.dithering
: selects how to best spread the error in colour mapping, to conceal the fact that we're using a palette and not true color. Note that using this option automatically disables the aforementioned quantizer. Best results if you pass in a palette, but if not we'll create one using the colours in the first frame. Possible options:bayer
: creates a somewhat nice and retro 'x' hatched patternfloyd
: creates another somewhat retro look where error is spread, using the Floyd-Steinberg algorithmclosest
: actually no dithering, just picks the closest colour from the palette per each pixelpalette
: An array of integers containing a palette. E.g. [ 0xFF0000, 0x00FF00, 0x0000FF, 0x000000 ]
contains red, green, blue and black. The length of a palette must be a power of 2, and contain between 2 and 256 colours.delay
: set frame delay. Default is Animated_GIF
instance delay.Check the files in the tests
folder:
Start the server from the root folder (e.g. Animated_GIF
). One way of doing it is using the simple Python web server:
python -m SimpleHTTPServer
starts a server in http://localhost:8000
. So you can now go to http://localhost:8000/tests/
and see the available examples.
Here's a quick walkthrough of each of the files in src/
and what they do:
Animated_GIF.js
- definition of the Animated_GIF
class. Holds the logic for the queueing and rendering of the files, and parsing config options.Animated_GIF.worker.js
- code for the web worker that color-indexes frames in the background, using node-dithering
and NeuQuant.js
. This is bundled in dist/Animated_GIF.js
, using workerify.main.js
- stub in order to export the library using Browserify (you won't generally need to touch this one)External / included libraries --see Credits for more information on these. You generally don't want to touch these because it will make very difficult to track updates in those libraries:
lib/NeuQuant.js
- color quantizer based on a neural network algorithm, this is an external libraryomggif.js
- GIF89 encoder/decodernode-dithering
- class with three different types of dithering algorithmsdist
filesIf you made changes in the library, you'll need to rebuild the files in dist/
in order to see the changes working. We have a node.js-based script to regenerate those files.
Once node.js is installed in your system, do:
cd Animated_GIF # or however you cloned the library to
npm install # this pulls dependencies for building (uglify, browserify)
npm run build # and this actually builds
Once you do the initial two steps you just need to execute npm run build
whenever you change things and want to rebuild the files in dist/
. Or you can also use npm run watch
to have it build the library automatically.
We're using these fantastic libraries to do GIF stuff:
And then, to build the dist
files
Author: Sole
Source Code: https://github.com/sole/Animated_GIF
1657849080
GIFBar
A system tray icon that helps you find the perfect GIF
Made with Electron.
Init | npm install |
Run | npm start |
Build | npm run build |
Author: Dcrousso
Source Code: https://github.com/dcrousso/GIFBar
License: MIT license
1650763560
gifgen
Simple high quality GIF encoding
If you've ever tried encoding GIFs with ffmpeg
there's a good chance your results came out looking pretty bad. This is because GIFs are limited to a palette of 256 colours and ffmpeg
just uses a generic palette to be able to cover a wide range of colours.
gifgen
produces much better results by doing a 2-pass encode. The first pass generates a custom colour palette based on all of the pixels from each frame. The second pass encodes the GIF using this palette instead of the default one bundled with ffmpeg
.
ffmpeg default:
gifgen:
$ gifgen -h
gifgen 1.2.0
Usage: gifgen [options] [input]
Options:
-o Output file [input.gif]
-f Frames per second [10]
-s Optimize for static background
-v Display verbose output from ffmpeg
-w Scale output with horizontal resolution
-b Begin the clip at a given timestamp (in seconds)
-d Duration in seconds of the resulting gif, can be combined with at
Examples:
$ gifgen video.mp4
$ gifgen -o demo.gif SCM_1457.mp4
$ gifgen -sf 15 screencap.mov
$ gifgen -sf 15 -w 320 screencap.mov
Begin at 3.5 seconds into the video, make the gif using the next 5.5 seconds
$ gifgen -b 3.5 -d 5.5 screencap.mov
brew install lukechilds/tap/gifgen
Just clone this repo and either copy/symlink gifgen
to your PATH or run the script directly with ./gifgen
. Requires ffmpeg
to be installed.
¯\_(ツ)_/¯
gifgen
is pretty much just the information from this blog article wrapped up in a shell script. Full credit goes to the original author.
Author: lukechilds
Source Code: https://github.com/lukechilds/gifgen
License: MIT License
1649751780
画像を操作するときは、さまざまなファイルの種類を理解することが重要です。どのフォーマットがどのアプリケーションに最適ですか?
このチュートリアルでは、最も一般的な画像ファイルの種類と、それらをいつ使用する必要があるかについて説明します。
これは短い、非技術的な記事であることに注意してください。パフォーマンスの面でさらに深く掘り下げたい場合は、Webサイトの画像をWeb用に最適化する方法に関するこれらのガイドをお読みください。
まず、画像圧縮がどのように機能するかについて簡単に説明します。
可逆圧縮は、元のデータを圧縮データから完全に再構築できるようにするデータ圧縮アルゴリズムのクラスです。
ファイルに含まれる情報の一部を破棄し始める前に、ファイルを圧縮できるのは非常に限られています。
これが「非可逆」圧縮の出番です。一部の情報が失われるという点で非可逆です。
非可逆圧縮では、元のデータの近似値のみを再構築できます(ただし、通常は圧縮率が大幅に向上します)。
さまざまな画像ファイル形式を説明すると、「ロスレス」と「ロッシー」の両方の用語が下に表示されます。
JPEGは、画像の最も一般的なファイルタイプです。色の多い写真やその他の画像に最適です。
JPEG形式は、デジタル画像の「不可逆圧縮形式」です。それはそれがいくつかを失うことを意味します
ちなみに、JPEGはJoint Photographic Experts Groupの略で、標準を開発したチームです。
JPEGファイルは他の種類のファイルよりも小さいため、ダウンロードと共有が簡単です。
いいえ。GIF、SVG、PNGとは異なり、JPEGの背景を透明にすることはできません。JPEGを別のファイル形式に変換する必要があります。
はい–唯一の違いは、従来、ファイル拡張子は3文字しかないことです。「.jpg」は「.jpeg」の短縮形です。
PNGは、デジタル画像の可逆圧縮形式です。PNGは、GIFの改良された代替品として作成されました。これは、Web上で最も広く使用されているロスレス画像圧縮形式になりました。
PNGは、ロゴなどの透明度のある画像に最適なファイルタイプです。PNGファイルは通常JPEGよりも大きいため、大きな画像には適していません。
PNGは背景を透明にすることができます。
GIF形式は、Webで一般的に使用される別の種類の画像ファイルです。GIFファイルは通常、他の種類の画像ファイルよりも小さいため、Webでの使用に最適です。
静止画像にはGIFを使用できます。しかし、それらはより一般的にアニメーション、つまり自動再生される一連の画像に関連付けられています。たとえば、これはパブリックドメインのGIFです。
回転する地球のパブリックドメインGIF
これは実際には、ループで再生される1ダースほどの一連の画像です。
GIFは背景を透明にすることもできることに注意してください。
GIF形式の作成者であるStephenWilhiteは、「jif」を「Jif」ピーナッツバターのように発音したと述べています。
ジフピーナッツバター。ブライアン・カントーニによるクリエイティブ・コモンズの写真。
そうは言っても、私が知っているほとんどすべての開発者は、「gift」のように「gif」と発音します。これは、これからも最も人気のある言い方だと思います。
The Tonight Showの世論調査では、5,767人の回答者の73.7%が、GIFを「gift」のように「gif」と発音したと答えています。
TIFFは、編集が必要な高品質の画像に使用するのに最適なファイルタイプです。TIFFファイルは大きいため、オンラインでの共有には適していません。
ファイルサイズよりも品質が重要な場合は、TIFFを使用する必要があります。実際には、特にWeb上の画像を処理する場合は、ほとんどの場合、PNGの方が適しています。
SVGはスケーラブルベクターグラフィックです。これは、品質を損なうことなく、グラフィックを任意のサイズに拡大縮小できることを意味します。
この記事で説明している他のすべてのファイル形式とは異なり、SVGファイルはベクターファイルです。(JPEG、PNG、GIF、およびTIFFはラスターファイルです。)
つまり、SVGファイルは品質を損なうことなく任意のサイズに拡大縮小できますが、ラスターファイルは拡大すると品質が低下します。
ベクター編集ソフトウェアを使用してSVGファイルを編集できます(またはグラフィックの座標と色を手動で更新するだけです)。PNGファイルは、ラスター編集ソフトウェアを使用してのみ編集できます。
これは、 MozillaDeveloperNetworkのSVGファイルの例です。これは、SVGがネイティブXMLコード形式でどのように見えるかです。
<svg version="1.1"
width="300" height="200"
xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" fill="red" />
<circle cx="150" cy="100" r="80" fill="green" />
<text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text>
</svg>
そして、この単純なコードはこの画像をレンダリングします:
緑の点とその上に「SVG」の文字が付いた赤い正方形。
SVGファイルは画像の描画に必要なデータのみを含むため、通常はPNGファイルよりも小さくなりますが、PNGファイルには画像全体のデータが含まれます。
SMILと呼ばれるツールを使用してSVGファイルをアニメーション化することもできます。したがって、これらは非常にスペース効率の高いGIFファイルとして機能します。そして、あなたが本当に冒険好きなら、SVGをプログラムすることができます。
光ファイバーケーブルの展開が進み、高速衛星インターネットが一般的になるにつれて、Webの外観は将来大きく変わる可能性があります。
ただし、今のところ、ほとんどの画像にJPEGを使用することをお勧めします。
会社のロゴや品質が重要な非常に重要な写真がある場合は、PNGが適しています。
ロゴの場合は、SVGを使用することをお勧めします。これは、無限に拡大縮小でき、サイズが非常にコンパクトであるためです。
画像ファイルの種類について多くのことを学んだことを願っています。
ソース:https ://www.freecodecamp.org/news/image-file-types-picture-format-extensions-jpeg-gif-png-svg-tiff/
1649751602
Cuando trabaja con imágenes, es importante comprender los diferentes tipos de archivos. ¿Qué formato es mejor para qué aplicación?
En este tutorial, explicaremos los tipos de archivos de imagen más comunes y cuándo debe usarlos.
Tenga en cuenta que este es un artículo breve y no técnico. Si desea profundizar mucho más en el aspecto del rendimiento, lea estas guías sobre cómo optimizar las imágenes de su sitio web para la web .
Primero, una explicación rápida de cómo funciona la compresión de imágenes.
La compresión sin pérdidas es una clase de algoritmos de compresión de datos que permite reconstruir perfectamente los datos originales a partir de los datos comprimidos.
Hay tanto que puede comprimir un archivo antes de comenzar a desechar parte de la información que contiene el archivo.
Aquí es donde entra en juego la compresión "Lossy". Con pérdida, ya que pierde parte de la información.
La compresión con pérdida permite la reconstrucción solo de una aproximación de los datos originales (aunque generalmente con tasas de compresión muy mejoradas).
Verá que los términos "Lossless" y "Lossy" aparecen a continuación cuando describimos diferentes formatos de archivo de imagen.
JPEG es el tipo de archivo más común para las imágenes. Se utiliza mejor para fotos y otras imágenes con muchos colores.
El formato JPEG es un "formato de compresión con pérdida" para imágenes digitales. Eso significa que pierde algo de la
Por cierto, JPEG significa Joint Photographic Experts Group, el equipo que desarrolló el estándar.
Los archivos JPEG son más pequeños que otros tipos de archivos, por lo que son fáciles de descargar y compartir.
No. A diferencia de los GIF, SVG y PNG, los archivos JPEG no pueden tener fondos transparentes. Necesitará convertir su JPEG a un formato de archivo diferente.
Sí, la única diferencia es que, tradicionalmente, las extensiones de archivo tienen solo 3 caracteres. ".jpg" es una forma abreviada de ".jpeg".
PNG es un formato de compresión sin pérdidas para imágenes digitales. PNG se creó como un reemplazo mejorado para GIF. Se ha convertido en el formato de compresión de imágenes sin pérdidas más utilizado en la web.
PNG es un tipo de archivo que se usa mejor para imágenes con transparencia, como logotipos. Los archivos PNG suelen ser más grandes que los JPEG, por lo que no son ideales para imágenes grandes.
Los PNG pueden tener un fondo transparente.
El formato GIF es otro tipo de archivo de imagen que se usa comúnmente en la web. Los archivos GIF suelen ser más pequeños que otros tipos de archivos de imagen, lo que los hace ideales para usar en la web.
Los GIF se pueden usar para imágenes estáticas. Pero se asocian más comúnmente con animaciones, una serie de imágenes que se reproducen automáticamente. Por ejemplo, aquí hay un GIF de dominio público.
Un GIF de dominio público del globo giratorio
Esto es realmente solo una serie de una docena de imágenes que se reproducen en un bucle.
Tenga en cuenta que los GIF también pueden tener un fondo transparente.
El creador del formato GIF, Stephen Wilhite, dijo que pronunciaba "jif" como "Jif" mantequilla de maní.
Mantequilla de maní Jif. Foto de Creative Commons por Brian Cantoni.
Dicho esto, casi todos los desarrolladores que conozco lo pronuncian "gif", como en "regalo", y creo que seguirá siendo la forma más popular de decirlo.
Una encuesta de The Tonight Show donde el 73,7% de los 5.767 encuestados dijeron que pronunciaban GIF como "gif" como en "regalo".
TIFF es un tipo de archivo que es mejor usar para imágenes de alta calidad que necesitan ser editadas. Los archivos TIFF son grandes, por lo que no son ideales para compartir en línea.
Debe usar un TIFF cuando la calidad es más importante que el tamaño del archivo. En la práctica, un PNG es casi siempre una mejor opción, especialmente cuando se trata de imágenes en la web.
Un SVG es un gráfico vectorial escalable. Esto significa que el gráfico se puede escalar a cualquier tamaño sin perder calidad.
A diferencia de todos los demás formatos de archivo que analizamos en este artículo, los archivos SVG son archivos vectoriales. (JPEG, PNG, GIF y TIFF son archivos de trama).
Esto significa que los archivos SVG se pueden escalar a cualquier tamaño sin perder calidad, mientras que los archivos raster perderán calidad cuando se amplíen.
Puede editar archivos SVG utilizando un software de edición de vectores (o simplemente actualizar manualmente las coordenadas y los colores de los gráficos). Solo puede editar archivos PNG utilizando un software de edición de tramas.
Aquí hay un archivo SVG de ejemplo de Mozilla Developer Network . Así es como se ve SVG en su forma de código XML nativo:
<svg version="1.1"
width="300" height="200"
xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" fill="red" />
<circle cx="150" cy="100" r="80" fill="green" />
<text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text>
</svg>
Y este código simple representa esta imagen:
Un cuadrado rojo con un punto verde y las letras "SVG" en él.
Los archivos SVG suelen ser más pequeños que los archivos PNG, porque solo contienen los datos necesarios para dibujar la imagen, mientras que los archivos PNG contienen los datos de toda la imagen.
También puede animar archivos SVG usando una herramienta llamada SMIL. Por lo tanto, pueden servir como archivos GIF extremadamente eficientes en el espacio. Y si eres realmente aventurero, puedes programar SVG.
La web puede verse muy diferente en el futuro, a medida que implementemos más y más cable de fibra óptica y el Internet satelital de alta velocidad se vuelva más común.
Pero por ahora, mi recomendación es usar archivos JPEG para la mayoría de sus imágenes.
Si tienes el logo de una empresa o una foto muy importante donde la calidad es vital, PNG es una buena opción.
Para los logotipos, recomiendo usar un SVG, ya que se escalará infinitamente y tiene un tamaño muy compacto.
Espero que hayas aprendido mucho sobre los tipos de archivos de imagen.
Fuente: https://www.freecodecamp.org/news/image-file-types-picture-format-extensions-jpeg-gif-png-svg-tiff/
1626524760
Learn how to make a moving animated GIF in Fireworks CS5. Animated pictures can look really good on your website and this is why we are learning how to make them.
Don’t forget to Subscribe here: https://www.youtube.com/channel/UCWkzkhQ3syxBjjAYwqCbzYg?sub_confirmation=1
#cs5 #gif #fireworks
1621842966
This video on Play GIF On Hover | Animate GIF on hover | How To Animate GIF On Hover In CSS
Related contents
➤ gif animation in CSS
➤ play gif on hover codepen
➤ css animation
Download Code From Here:
➤ https://deecoder.in/
Subscribe: https://www.youtube.com/c/DEECODER/featured
#css #gif
1606206525
Hey there, yogi bear. Tired of creating gifs? Seriously, that takes time and most of the time it has a huge file size and a crappy resolution. What if you can create a gif(ish) element out of CSS? Because you can.
CSS has come a long way we can now create our own GIF-ish contents and the best part, we have full control over it.
Read this blog to learn more
https://www.loginradius.com/engineering/blog/create-a-loading-spinner-using-css/
#css #loader #gif #programming #coding #engineering
1600965416
Custom Hooks in React are useful for much more than just managing the local state. They provide a new layer of abstraction to accomplish new and amazing patterns. In this video, I’m going to teach you how to use custom hooks to build a GIF Application.
GitHub Repository: https://github.com/adrianhajdin/project_gif_app
CSS code and URLs: https://gist.github.com/adrianhajdin/4beeeab4c8515bd72bbd1e29a09bd668
Subscribe : https://www.youtube.com/channel/UCmXmlB4-HJytD7wek0Uo97A
#react #gif #react-hooks
1597995337
Most tutorials nowadays contain many visuals to grab the reader’s attention and explain how to better solve different problems. Specifically, I found that GIFs are a very good tool for presenting GUIs. In this article, I will show you how to make animated GIFs that can be used alongside text to create faster and better demos.
#tech #animation #gif #web-development #user-experience
1597466040
This article will show you two simple and quick steps you can take to make a GIF file out of an already dynamic Tableau visualization.
Nowadays, the proliferation of dynamic and effective data communication is also seeing charts being more and more prone to being communicated in an interactive way that is aligned with the type of digital media most people communicate with. GIFs are definitely a trend in this regard, and they can be potentially very effective when it comes to augmenting the degree of interactivity of your data charts and the way you present them to your relevant audience.
Therefore, I will walk you through a brief example on how to turn a Tableau chart into a GIF file, which can be then shared via reports/presentations to add a touch of interactivity to whatever content you will be sharing with your network.
The objective of this chart is to examine the correlation of income inequality, as estimated by the Gini coefficient, and a country’s total Covid-19 cases per one million inhabitants (data sources can be found at the top of the page), and see how the correlation appears to be developing over time. To do this, you are going to make use of two datasets and of Tableau’s Pages Shelf to add the first element of interactivity into our chart.
As a first thing, you can input the two data sources necessary for this example and join them using Tableau’s data source tab, as shown in the below image. You can use the “Country column” on the Gini coefficient table to perform a left join with the second data source, as to get you to a single table which features both the Gini coefficient and Covid-19 related columns (number of cases, tests, etc by date).
#gif #tableau #data-visualization #data visualization
1592875440
1590120840
Even though the Facebook and Messenger apps are bad, they have really cute stickers 🤪. But you try to download, there is no way to download as a gif file file. Anyway, it appears already, there is no way to download. Try inspecting the element, we will see it appears to be a spritesheet set background-image
and used background-position
to change the frame.
This is the spritesheet.
So now we will do like this:
gif
Looking at the spritesheet up there, you can see that it has 8 frames, each size 288px * 288px
. You can manually cut it out by any app. Or we will write a script to cut out. We will use the Canvas API to render frames from spritesheet.
Suppose we have a spritesheet loaded on a page like this
<img id="spritesheet" src="https://scontent.fhan5-7.fna.fbcdn.net/v/t39.1997-6/72568563_526222821444483_279572336263299072_n.png?_nc_cat=100&_nc_sid=0572db&_nc_oc=AQlkAKjDakbfs1blUQC66vLLLnC5bCz1Eh6KJf_9JCgjaxqJ4kO1GhPF-CAkq3MZqGX5m_ar6Gu7tbuCFn06FXnA&_nc_ht=scontent.fhan5-7.fna&oh=fff5b86d6e73bd2c11d359b4f5b63b96&oe=5EE5DA80">
To cut out each frame, we will create a canvas with the size 288px * 288px
and render the corresponding part on the sprite sheet onto that canvas. For example, to cut the first frame, we do like this
const spritesheet = document.getElementById('spritesheet');
const canvas = document.createElement('canvas');
canvas.width = 288;
canvas.height = 288;
const ctx = canvas.getContext('2d');
ctx.drawImage(spritesheet, 0, 0, 288, 288, 0, 0);
document.body.appendChild(canvas);
You should see the first frame like this
The 2nd and 3rd parameters of drawImage
will be the position of the frame on the spritesheet. Document details here .
To cut all the frames, we make a loop like this
const frames = [];
while (y < spritesheet.height) {
x = 0;
while (x < spritesheet.width) {
const canvas = document.createElement('canvas');
canvas.width = canvasWidth;
canvas.height = canvasHeight;
const ctx = canvas.getContext('2d');
ctx.drawImage(spritesheet, x, y, 288, 288, 0, 0);
const isEmpty = ctx.getImageData(0, 0, canvasWidth, canvasHeight).data.every(channel => channel === 0);
if (!isEmpty) {
frames.push(canvas);
}
x += originalWidth;
}
y += originalHeight;
}
You will see that we have left a last empty frame empty, so I have to add a check to see if the frame we just cut has data before adding it to the array frames
. Simply check whether all its pixels have data or not.
const isEmpty = ctx.getImageData(0, 0, canvasWidth, canvasHeight).data.every(channel => channel === 0);
If I have frames then I can stitch them together. I will use the package [gif.js](http://npmjs.com/package/gif.js)
to create gif images. Creating images from frames is as simple as this.
const fps = 8;
const gif = new GIF({
workers: 2,
quality: 1,
});
frames.forEach(frame => gif.addFrame(frame, {
delay: 1000 / fps,
}));
gif.on('finished', (blob) => {
const url = URL.createObjectURL(blob);
const img = document.createElement('img');
img.setAttribute('src', url);
document.body.appendChild(img);
});
gif.render();
Just add the frames and the delay between frames then render. To make it easy to calculate, we use the concept of frame rate, often the Facebook stickers I see have frame rate from 8-12 fps. The result will be raw data so we can use URL.createObjectURL
to create a temporary URL. Our result is like this.
It’s okay, except for the black background ra. This is because our image is partially transparent, so the gif is rendered. If add options transparent
for gif.js
like this
const gif = new GIF({
workers: 2,
quality: 1,
transparent: 'rgba(0, 0, 0, 0)',
});
Then we get results like this.
There is a transparent background but the contours are not very good. This is due to format limitations GIF
. Normally, with a transparent image such as PNG, the transition from the image to the transparent place will be a lot of pixels with reduced transparency like this to make the border of the image smooth.
However, with the GIF format, each px can only be colored or completely transparent, not half transparent like PNG. So the contour looks like a low-quality serrated pattern. So a gif that has a transparent background usually has a small white border (or something similar to the background where people plan to put the gif on) to make the border look smoother. For simplicity, I will give the white background as well.
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
Remember to color before drawImage
it will overlap the image. Our result is like this.
This is the whole code if you want to play with it.
Link codepen if the embed doesn’t load 😔 https://codepen.io/thphuong/pen/qBOyRaz
Regarding how Facebook works, why use a spritesheet without using a GIF image. Doing this also has some benefits.
But there must also be some that are not beneficial
background-image
and background-position
so the sticker size is fixed, want to change spritesheet to change.#gif #programming