Lens

This lens effect is modeled on optical displacement of a hemisphere

by stupid_genius

HTML

<canvas id="canvas"></canvas>

JavaScript

function createLens(cw, w, d){
    var lens = [];
    for(var i=0;i<w*w;++i)
        lens.push(0);
    var r = Math.round(w/2);
    var r2 = r*r;
    var center = r*(w+1);
    var offset;
    for(var i=0;i<r2;++i)
    {
        var x = i%r;
        var y = Math.floor(i/r);
        var x2 = x*x;
        var y2 = y*y;
        var ix = 0;
        var iy = 0;
        if((x2+y2) < (r2))
        {
            var shift = d/Math.sqrt(d*d - (x2 + y2 - r2));
            ix = Math.floor(x*shift) - x;
            iy = Math.floor(y*shift) - y;
        }
        
        offset = (iy*cw + ix);
        lens[center - (y*w) - x] = -offset;
        lens[center + (y*w) + x] = offset;
        offset = (-iy*cw + ix);
        lens[center - (y*w) + x] = offset;
        lens[center + (y*w) - x] = -offset;
    }
    return lens;
}
function checkerBoard(w, i, s, c)
{
	var x = i%w;
	var y = Math.floor(i/w);
	var f1, f2, rc;

	if(Math.floor(x/s)%2==0)
		f1 = false;
	else
		f1 = true;
	if(Math.floor(y/s)%2==0)
		f2 = f1;
	else
		f2 = !f1;

	//rc = f2*c;
	if(f2)
		rc = c;
	else
		rc = 0;//Math.round(c/2);
	return [rc, rc, rc, 255];
}
function processor(pjs){
    var canvasWidth = 400;
    var canvasHeight = 400;
    var lensWidth = 100;
    var lensDepth = 30;
    var bg;
    var lens;
    var lensLookup;
    var bgPixels;
    var x = canvasWidth/2;
    var y = canvasHeight/2;
    var dx = 1;
    var dy = 2;
    var r = lensWidth/2;

    pjs.setup = function(){
    with(pjs){
        size(canvasWidth, canvasHeight);
        lens = createImage(lensWidth, lensWidth, RGB);
        bg = createImage(canvasWidth, canvasHeight, P3D);
        var pixels = bg.pixels.toArray();
        for(var i=0;i<pixels.length;++i){
            pixels[i] = color.apply(this, checkerBoard(canvasWidth,i,canvasWidth/16,255));
        }
        bg.pixels.set(pixels);
        bg.loaded = true;
        bgPixels = bg.pixels.toArray();
        lensLookup = createLens(canvasWidth, lensWidth, lensDepth);
    }
    }

   ...