All Projects → leeoniya → Gifter.js

leeoniya / Gifter.js

<canvas> to GIF recorder

Programming Languages

javascript
184084 projects - #8 most used programming language

🎁 GIFter.js

<canvas> to GIF recorder (MIT Licensed)


Intro

Wait, another1 js GIF recorder? Well, yes and no. GIFter.js does record gifs, but it's designed for a specific purpose and offers some unique features which facilitate this. That purpose is to record canvas graphics, animations and pixel-art sprites rather than encoding photos and movie clips. Keeping this in mind, the lib can be used as a general-purpose gif recorder with some settings adjustments (see below).

1 gif.js, jsgif, mothereffinganimatedgif, Animated_GIF


Features

  • Small output - Compact filesize is achieved via sequential frame differencing, computation of an optimal, global color palette and identical frame grouping (todo).
  • High quality - Artifact-free with a good balance between gradient quality and localized detail retention.
  • Fast processing - Color-remap memoization keeps frame processing fast for graphics. However, photographs and images with complex color gradients perform more slowly.
  • Scaling - Nearest-neighbor scaling avoids interpolation = crisp, pixelated, upscaling goodness.
  • Cropping - Record only a portion of the full frame.
  • Layers - Compose several canvas layers in a single frame.
  • Web-worker ready - internal methods do not rely on Canvas for cropping, scaling, or layers via alpha composition.
  • Pluggable quantizer - RgbQuant.js is used by default, but others such as NeuQuant.js, median-cut-js, etc. can be shimmed in its place (see caveats below).

Basic Usage

Use Chrome or Firefox, some HTML5/JS features are used - Canvas, Typed Arrays, Array.forEach, Webworkers (soon).

// options
var width  = 128,
	height = 128,
	opts = {
		loop: 0,
		loopDelay:  50,
		frameDelay: 25,
	//	cropBox: [2,2,5,5],
	};

var gif = new GIFter(width, height, opts);

// layer0 and layer1 are <img> and/or <canvas> elements
gif.addFrame(layer0);
// multi-layer frame
gif.addFrame([layer0, layer1]);

// execute encoder
var img = gif.render();

// lets see it!
document.body.appendChild(img);

See /tests directory for demo


Quantizer Swappage

First, a word of caution. RgbQuant.js supports multi-image palletization, a method that builds up a single palette of 256 most-important colors using multiple sampled frames. This is why GIFter.js employs an explicit palatte building step in global-palette mode. Other quantizers that I've encountered cannot work this way; they will produce a fixed-size palette only from a single image.

In theory, it is possible to then take many frames' palettes and combine them into a single, reduced one, but you would need to implement this for each quantizer. Additionally, merging multiple palettes may negate any quality gained through spatial analysis of each individual image.

So, swapping the quantizer while maintaining a single global palette (and small fileszie) is not a trivial endeavor. However, if palette-per-frame operation is acceptable or desired, the quantizer can be swapped out with relative ease. Consider yourselves warned informed :)


Notes

  • Per-frame options are not implemented yet, though they are supported by the omggif encoder.
  • Framerate is limited to 50fps. This is a browser vendor decision. 20ms is the smallest possible frame delay.
  • If you need absolute smallest filesize, compress the resulting GIFs with gifsicle.

Dependencies

included in /lib

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].