var ctx = display.getContext("2d"); function log(s){ _console.value += s + "\n"; } function combine(c1, c2){ /* Algorithm courtesy of http://stackoverflow.com/a/727339/1175714 */ c3 = {}; c3.a = 1 - (1 - c2.a) * (1 - c1.a); c3.r = c2.r * c2.a / c3.a + c1.r * c1.a * (1 - c2.a) / c3.a; c3.g = c2.g * c2.a / c3.a + c1.g * c1.a * (1 - c2.a) / c3.a; c3.b = c2.b * c2.a / c3.a + c1.b * c1.a * (1 - c2.a) / c3.a; return c3; } function rgb_string(c){ return "rgb(" + parseInt(c.r) + "," + parseInt(c.g) + "," + parseInt(c.b) + ")"; } function fill(c, x, y, w, h){ ctx.fillStyle = rgb_string(c); ctx.fillRect(x, y, w, h); } var black = { r: 0, g: 0, b: 0, a: 1 }, yellow = { r: 255, g: 255, b: 0, a: 1 }, blue = { r: 0, g: 0, b: 255, a: 0.2 }, white = { r: 255, g: 255, b: 255, a: 0.6 }; var wb = combine(black, white); log("0.6-alpha white over 1.0-alpha black:"); log(" r: " + wb.r + " (" + (wb.r/255 * 100) + "%)"); log(" g: " + wb.g + " (" + (wb.g/255 * 100) + "%)"); log(" b: " + wb.b + " (" + (wb.b/255 * 100) + "%)"); log(" a: " + wb.a + " (" + (wb.a/1 * 100) + "%)"); fill(black, 0, 0, display.width, display.height); fill(yellow, 0, 0, 20, 20); fill(wb, 20,0,20,20); fill(white, 40,0,display.width-40, display.height); white.a = 1; var blue_02 = combine(white, blue); fill(blue_02, 60,0,50,50); blue.a = 0.5; fill(combine(blue_02, blue), 70,10,50,50); fill(blue, 80, 20, 50, 50); /* The algorithm makes it possible to combine two colors, but combining more than that (trying to draw a transparent blue square over the white background and the blue tint simultaneously), would require some cleverness. */