This 1k app generates a realtime heatmap depending on the user's mouse movement (default map size is 999x500)
var $=(function(){var f,k,g,d,j=25,i=50,b=false,a=function(w,v,m){if(w+m>g){w=g-m}if(w<0){w=0}if(v<0){v=0}if(v+m>d){v=d-m}var n=k.getImageData(w,v,m,m),c=n.data,o=c.length;for(var s=3;s<o;s+=4){var h=0,t=0,u=0,q=0,p=c[s];if(p<=255&&p>=235){q=255-p;h=255-q;t=q*12}else{if(p<=234&&p>=200){q=234-p;h=255-(q*8);t=255}else{if(p<=199&&p>=150){q=199-p;t=255;u=q*5}else{if(p<=149&&p>=100){q=149-p;t=255-(q*5);u=255}else{u=255}}}}c[s-3]=h;c[s-2]=t;c[s-1]=u}n.data=c;k.putImageData(n,w,v)},e=function(m){if(b){var c,o;if(m.layerX){c=m.layerX;o=m.layerY}else{if(m.offsetX){c=m.offsetX;o=m.offsetY}}var l=j;var h=i;var n=k.createRadialGradient(c,o,l,c,o,h);n.addColorStop(0,"rgba(0,0,0,0.1)");n.addColorStop(1,"rgba(0,0,0,0)");k.fillStyle=n;k.fillRect(c-h,o-h,2*h,2*h);b=!b;a(c-h,o-h,2*h)}};return{i:function(m,h,l){m=document.getElementById(m);m.width=h;m.height=l;m.style.border="2px solid black";k=m.getContext("2d");g=h;d=l;m.onmousemove=function(c){e(c)}},a:function(){b=!b}}}());$.i("c",999,500);setInterval("$.a();",50);
dmFyICQ9KGZ1bmN0aW9uKCl7dmFyIGYsayxnLGQsaj0yNSxpPTUwLGI9ZmFsc2UsYT1mdW5jdGlvbih3LHYsbSl7aWYodyttPmcpe3c9Zy1tfWlmKHc8MCl7dz0wfWlmKHY8MCl7dj0wfWlmKHYrbT5kKXt2PWQtbX12YXIgbj1rLmdldEltYWdlRGF0YSh3LHYsbSxtKSxjPW4uZGF0YSxvPWMubGVuZ3RoO2Zvcih2YXIgcz0zO3M8bztzKz00KXt2YXIgaD0wLHQ9MCx1PTAscT0wLHA9Y1tzXTtpZihwPD0yNTUmJnA+PTIzNSl7cT0yNTUtcDtoPTI1NS1xO3Q9cSoxMn1lbHNle2lmKHA8PTIzNCYmcD49MjAwKXtxPTIzNC1wO2g9MjU1LShxKjgpO3Q9MjU1fWVsc2V7aWYocDw9MTk5JiZwPj0xNTApe3E9MTk5LXA7dD0yNTU7dT1xKjV9ZWxzZXtpZihwPD0xNDkmJnA+PTEwMCl7cT0xNDktcDt0PTI1NS0ocSo1KTt1PTI1NX1lbHNle3U9MjU1fX19fWNbcy0zXT1oO2Nbcy0yXT10O2Nbcy0xXT11fW4uZGF0YT1jO2sucHV0SW1hZ2VEYXRhKG4sdyx2KX0sZT1mdW5jdGlvbihtKXtpZihiKXt2YXIgYyxvO2lmKG0ubGF5ZXJYKXtjPW0ubGF5ZXJYO289bS5sYXllcll9ZWxzZXtpZihtLm9mZnNldFgpe2M9bS5vZmZzZXRYO289bS5vZmZzZXRZfX12YXIgbD1qO3ZhciBoPWk7dmFyIG49ay5jcmVhdGVSYWRpYWxHcmFkaWVudChjLG8sbCxjLG8saCk7bi5hZGRDb2xvclN0b3AoMCwicmdiYSgwLDAsMCwwLjEpIik7bi5hZGRDb2xvclN0b3AoMSwicmdiYSgwLDAsMCwwKSIpO2suZmlsbFN0eWxlPW47ay5maWxsUmVjdChjLWgsby1oLDIqaCwyKmgpO2I9IWI7YShjLWgsby1oLDIqaCl9fTtyZXR1cm57aTpmdW5jdGlvbihtLGgsbCl7bT1kb2N1bWVudC5nZXRFbGVtZW50QnlJZChtKTttLndpZHRoPWg7bS5oZWlnaHQ9bDttLnN0eWxlLmJvcmRlcj0iMnB4IHNvbGlkIGJsYWNrIjtrPW0uZ2V0Q29udGV4dCgiMmQiKTtnPWg7ZD1sO20ub25tb3VzZW1vdmU9ZnVuY3Rpb24oYyl7ZShjKX19LGE6ZnVuY3Rpb24oKXtiPSFifX19KCkpOyQuaSgiYyIsOTk5LDUwMCk7c2V0SW50ZXJ2YWwoIiQuYSgpOyIsNTApOw==
/*
Copyright (c) 2010, Patrick Wied. All rights reserved.
Code licensed under the BSD License:
http://patrick-wied.at/static/license.txt
*/
var heatmapApp = (function(){
// var definition
// canvas: the canvas element
// ctx: the canvas 2d context
// width: the heatmap width for border calculations
// height: the heatmap height for border calculations
// invoke: the app doesn't react on the mouse events unless the invoke var is set to true
var canvas,
ctx,
width,
height,
radius1 = 25,
radius2 = 50,
invoke = false,
// function for coloring the heatmap
colorize = function(x,y,x2){
// initial check if x and y is outside the app
// -> resetting values
if(x+x2>width)
x=width-x2;
if(x<0)
x=0;
if(y<0)
y=0;
if(y+x2>height)
y=height-x2;
// get the image data for the mouse movement area
var image = ctx.getImageData(x,y,x2,x2),
// some performance tweaks
imageData = image.data,
length = imageData.length;
// loop thru the area
for(var i=3; i < length; i+=4){
var r = 0,
g = 0,
b = 0,
tmp = 0,
// [0] -> r, [1] -> g, [2] -> b, [3] -> alpha
alpha = imageData[i];
// coloring depending on the current alpha value
if(alpha<=255 && alpha >= 235){
tmp=255-alpha;
r=255-tmp;
g=tmp*12;
}else if(alpha<=234 && alpha >= 200){
tmp=234-alpha;
r=255-(tmp*8);
g=255;
}else if(alpha<= 199 && alpha >= 150){
tmp=199-alpha;
g=255;
b=tmp*5;
}else if(alpha<= 149 && alpha >= 100){
tmp=149-alpha;
g=255-(tmp*5);
b=255;
}else
b=255;
// we ve started with i=3
// set the new r, g and b values
imageData[i-3]=r;
imageData[i-2]=g;
imageData[i-1]=b;
}
// the rgb data manipulation didn't affect the ImageData object(defined on the top)
// after the manipulation process we have to set the manipulated data to the ImageData object
image.data = imageData;
ctx.putImageData(image,x,y);
},
// this handler is listening to the mouse movement of the user
mouseMoveHandler = function(ev){
// if the invoke variable is set to true -> do the alphamap manipulation
if(invoke){
// at first we have to get the x and y values of the user's mouse position
var x, y;
if (ev.layerX) { // Firefox
x = ev.layerX;
y = ev.layerY;
} else if (ev.offsetX) { // Opera
x = ev.offsetX;
y = ev.offsetY;
}
// storing the variables because they will be often used
var r1 = radius1;
var r2 = radius2;
// create a radial gradient with the defined parameters. we want to draw an alphamap
var rgr = ctx.createRadialGradient(x,y,r1,x,y,r2);
// the center of the radial gradient has .1 alpha value
rgr.addColorStop(0, 'rgba(0,0,0,0.1)');
// and it fades out to 0
rgr.addColorStop(1, 'rgba(0,0,0,0)');
// drawing the gradient
ctx.fillStyle = rgr;
ctx.fillRect(x-r2,y-r2,2*r2,2*r2);
// negate the invoke variable
// next execution of the logic is when the activate method activates the invoke var again
invoke=!invoke;
// at least colorize the area
colorize(x-r2,y-r2,2*r2);
}
};
return {
// initialization
initialize: function(c, wt, ht){
canvas = document.getElementById(c);
canvas.width = wt;
canvas.height = ht;
canvas.style.border = "2px solid black";
ctx = canvas.getContext("2d");
width = wt;
height = ht;
canvas["onmousemove"] = function(ev){ mouseMoveHandler(ev); };
},
// activating the logic
activate: function(){
invoke = !invoke;
}
};
}());
// call the initialization
heatmapApp.initialize("c",999,500);
// and call the activate function in an interval of 50ms
setInterval("heatmapApp.activate();",50);