This is based on an old ink mixing formula, mentioned in a guide to inking traditionally I was reading. Now that I've done a Colour Science course at school, I can state it's pretty much an interpretation of Maxwell's equations.
[UPDATE 1: This update is just meant to show that the algorithm for transitions is pretty effective.]
[Update 2: As I hadn't written anything in JS in a while, I converted it to JS and it draws to the canvas http://jsdo.it/NME/hoON Also because I can't ignore the A in RGBA with JS, I made it work with the Alpha too]
A little more work because of having to set the bounds per row or column based on the lines between points, but not too difficult. I might do it, if I have time.
I mean you could have 2x2 bitmap, set the pixels to corner colors you want and stretch it to the whole screen, letting the built-in sampler to do interpolation.
//Written by Anthony Pace, in Toronto Ontario Canada, ap13mo@student.ocadu.ca
package {
import flash.utils.setInterval;
import flash.geom.Rectangle;
import flash.utils.ByteArray;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
public class ColourTran1 extends Sprite {
public function ColourTran1() {
init();
Wonderfl.disable_capture ();//
}
public function init():void{
var bgWidth:uint = stage.stageWidth-1,bgHeight:uint = stage.stageHeight-1;
var bmd:BitmapData = new BitmapData(bgWidth,bgHeight,false);
var bmp:Bitmap = new Bitmap(bmd);
this.addChild(bmp);
//colours to use to make the transition points on the grid
var tlc:uint = 0xff0000,
trc:uint = 0xffff00,
blc:uint = 0xffffff,
brc:uint = 0x00ffff;
//used to maintain a smooth transition from corner colour to corner colour
var tlcVec:Vector.<uint> = new Vector.<uint>,
trcVec:Vector.<uint>,
blcVec:Vector.<uint>,
brcVec:Vector.<uint>;
var stepsInTime:uint = 14;//decrease this number to increase the variations per second in the corners
var iid:uint = setInterval(function():void{
if(tlcVec.length==0){
tlcVec = transitionColours(stepsInTime,Math.random()*0xffffff,tlc);
trcVec = transitionColours(stepsInTime,Math.random()*0xffffff,trc);
blcVec = transitionColours(stepsInTime,Math.random()*0xffffff,blc);
brcVec = transitionColours(stepsInTime,Math.random()*0xffffff,brc);
tlcVec.fixed = trcVec.fixed = blcVec.fixed = brcVec.fixed = false;
}
tlc = tlcVec.pop();
trc = trcVec.pop();
blc = blcVec.pop();
brc = brcVec.pop();
drawBMD(bmd, tlc, trc, blc, brc);
},1000/60);
}
public function drawBMD(bmd:BitmapData,tlc:uint, trc:uint,blc:uint,brc:uint):void{
var bgRect:Rectangle = new Rectangle(0,0,bmd.width,bmd.height),
colRect:Rectangle = new Rectangle(0,0,1,bmd.height);
var l2rt:Vector.<uint> = transitionColours(bmd.width,tlc,trc),
l2rb:Vector.<uint> = transitionColours(bmd.width,blc,brc);
//and then go top to bottom per column
var t2b:Vector.<uint> = new Vector.<uint>;
bmd.lock();
var i:uint,j:uint;
for(i = 0;i!=bmd.width;i++){
t2b = transitionColours(bmd.height,l2rt[i],l2rb[i]);
colRect.x=i;
bmd.setVector(colRect,t2b);
}
bmd.unlock();
}
public function transitionColours(maxSteps:uint,startClr:uint,endClr:uint):Vector.<uint>{
var r1:uint = startClr>>16,
g1:uint = (startClr>>8)&0xff,
b1:uint = startClr&0xff;
var r2:uint = endClr>>16,
g2:uint = (endClr>>8)&0xff,
b2:uint = endClr&0xff;
var transitionVec:Vector.<uint>;
if(maxSteps <2){
maxSteps = 2;
}
transitionVec = new Vector.<uint>(maxSteps,true);
var msn1:uint = maxSteps-1;
var rFac:Number= ((r2-r1)/msn1),
gFac:Number = ((g2-g1)/msn1),
bFac:Number = ((b2-b1)/msn1);
transitionVec[0]=startClr;
for (var i:uint = 1;i!=msn1;i++){
transitionVec[i]= (uint(r1+i*rFac)<< 16) | (uint(g1+i*gFac) << 8) | uint(b1+i*bFac);
}
transitionVec[i] = endClr;
return transitionVec;
}
}
}