Our company website has a “random splicer generator” built into Flash that creates random alternating alternating color graphics of fragments under the site’s title.
http://www.clarendonmarketing.com
I am trying to replicate this effect using HTML5, and although I can easily generate random shards, mixed overlap (multiplication in Adobe terms) is a problem.
I have a solution that basically creates an array of all canvas pixel data before each shape, and then another array with canvas pixel data after every shard. Then it compares the two and where it finds an opaque pixel in the first array, the corresponding pixel in the second array corresponds to the current selected fill color, it redraws it with the new color value defined by the multiply function (topValue * bottomValue / 255).
As a rule, this works perfectly and achieves the desired effect, EXCLUDING around the edges of overlapping fragments, where the effect of the dentate is created.
I believe this is related to browser antialiasing. I tried to reproduce the original pixel alpha channel value for the calculated pixel, but this does not seem to help.
JavaScript:
var theCanvas;
var ctx;
var maxShards = 6;
var minShards = 3;
var fillArray = new Array(
[180,181,171,255],
[162,202,28,255],
[192,15,44,255],
[222,23,112,255],
[63,185,127,255],
[152,103,158,255],
[251,216,45,255],
[249,147,0,255],
[0,151,204,255]
);
var selectedFill;
window.onload = function() {
theCanvas = document.getElementById('shards');
ctx = theCanvas.getContext('2d');
var totalShards = getRandom(maxShards, minShards);
for(i=0; i<=totalShards; i++) {
imgData = ctx.getImageData(0,0,theCanvas.width,theCanvas.height);
currentPix = imgData.data
drawRandomShard();
imgData = ctx.getImageData(0,0,theCanvas.width,theCanvas.height);
pix = imgData.data;
for (var j = 0, n = currentPix.length; j < n; j += 4) {
if (
(currentPix[j+3]>0)
&&
(pix[j]==selectedFill[0] && pix[j+1]==selectedFill[1] && pix[j+2]==selectedFill[2])
) {
pix[j] = multiply(selectedFill[0], currentPix[j]);
pix[j+1] = multiply(selectedFill[1], currentPix[j+1]);
pix[j+2] = multiply(selectedFill[2], currentPix[j+2]);
}
}
ctx.putImageData(imgData, 0, 0);
}
};
function drawRandomShard() {
var maxShardWidth = 200;
var minShardWidth = 30;
var maxShardHeight = 16;
var minShardHeight = 10;
var minIndent = 4;
var maxRight = theCanvas.width-maxShardWidth;
var randomLeftAnchor = getRandom(maxRight, 0);
var randomRightAnchor = getRandom((randomLeftAnchor+maxShardWidth),(randomLeftAnchor+minShardWidth));
var randomLowerAnchorX = getRandom((randomRightAnchor - minIndent),(randomLeftAnchor + minIndent));
var randomLowerAnchorY = getRandom(maxShardHeight, minShardHeight);
var fillSelector = getRandom(fillArray.length-1,0);
selectedFill = fillArray[fillSelector];
drawShard(randomLeftAnchor, randomLowerAnchorX, randomLowerAnchorY, randomRightAnchor, selectedFill);
}
function drawShard(leftAnchor, lowerAnchorX, lowerAnchorY, rightAnchor, selectedFill) {
ctx.beginPath();
ctx.moveTo(leftAnchor,0);
ctx.lineTo(lowerAnchorX,lowerAnchorY);
ctx.lineTo(rightAnchor,0);
ctx.closePath();
fillColour = 'rgb('+selectedFill[0]+','+selectedFill[1]+','+selectedFill[2]+')';
ctx.fillStyle=fillColour;
ctx.fill();
};
function getRandom(high, low) {
return Math.floor(Math.random() * (high-low)+1) + low;
}
function multiply(topValue, bottomValue){
return topValue * bottomValue / 255;
};
:
http://www.clarendonmarketing.com/html5shards.html