Mashape logo hover effect (intro to canvas ImageData)

In the latest incarnation of Mashape, we’ve added a few goodies for people using modern browsers. One of those is the hover effect on the Mashape logo. We’ve found that the logo hover event is the most fired event and scales with other activity on our site. In this blog post, I’ll be going over some basics of pixel manipulation in the HTML5 canvas.

HTML5 provides a lot of access to browser data that was previously inaccessible. Let’s initialize the canvas:

var canvas = document.getElementById("logoCanvas"),
    ctx = canvas.getContext("2d");

The variable “canvas” gets the canvas element from the DOM, and “ctx” gets the rendering context so that we can use 2d canvas functions. We’ll also need to define functions for getting and setting individual pixels:

function getPixel(imageData, x, y) {
     var index = (x + y * width) * 4,
         r =[index+0],
         g =[index+1],
         b =[index+2],
         a =[index+3];
     return [r,g,b,a];
function setPixel(imageData, x, y, r, g, b, a) {
     var index = (x + y * width) * 4;[index+0] = r;[index+1] = g;[index+2] = b;[index+3] = a;

We assume imageData is an ImageData object, and width is already defined as the width of the canvas. The format of the actual data is an one-dimensional array that stores the red, green, blue, and alpha values of each pixel in sequence from left to right, row by row. That means each pixel takes up 4 values in the array, and in order to translate from Cartesian (x, y) coordinates to this array, we need to get the index by multiplying y by the width and adding x, then multiplying it all by 4.

Now that we have these 2 basic pixel manipulation functions, the fun part begins. Let’s define a function to shift a column of pixels by some number, and then another function that shifts multiple columns like a sine wave:

function shiftColumn(imageData, x, offset) {
     var i, o;
     if(offset < 0) { // going up
         for(i=0; i0; i--) {
             o = getPixel(imageData,x,i);
             setPixel(imageData, x, i+offset, o[0], o[1], o[2], o[3]);
function sineTransform(imageData, wavelength, amplitude, phase) {
     var offset;
     for(var i=0; i 0 && x < width) {
         offset = -Math.round(waveHeight*(-Math.cos(i*Math.PI*2/waveWidth)+1)/2);
         x = i+phase;
         if(x > 0 && x < paddedWidth) {
             shiftColumn(imageData, x, offset);

The function shiftColumn gets and sets pixels in a column. Depending on the direction, it iterates up or down to be careful not to get already moved pixels. sineTransform applies shiftColumn to multiple columns. That’s it! If you’d like to see a working example of the effect in action, go to and hover over the logo. Enjoy!

Mashape logo hover effect

- Mashaper, Dali



Mashape is the largest API hub in the world where you can consume, distribute, monitor and monetize your public and private APIs. Mashape powers 10,000 public & private APIs in every major industry, including finance, healthcare, and entertainment. We’re a Series A startup backed by Jeff Bezos (Amazon), Eric Schmidt (Google), Stanford University and top tier VC firms including Index Ventures, NEA and CRV.

Introducing API Glossary by Mashape

  When it comes to APIs, there’s a lot of jargon out there. The meaning of certain terms isn’t always obvious, and API providers sometimes use different ones to

Using Unirest (Java) for your Android projects

This post will show you how to get Unirest-java running on your Android projects.  Unirest is a lightweight HTTP client library with port available in many languages. This is a

Installing unirest-java with the Maven Assembly Plugin

Managing dependencies for your Java applications is difficult, unless you have Maven!  Maven is an Apache build manager for Java projects.  In this post, we will use a Maven

30+ ways to make REST calls in Node.js, PHP, Python, Rails, Obj-C, .NET, and Java / Android

Here’s a list of resources on how to make REST calls in different languages.  (We also have this list of 40+ tutorials on how to create an API in