I am working on emulating the behavior of the server box on https://mcprohosting.com/ but without sending multiple images (currently there are 3 images that rotate using javascripts .fadeout() calls and such.
My best attempt at doing this right now consists of parsing over the image pixels using HTML 5.
That being said there are a few problems:
- I can't figure out how to smoothly transition between 3 preset colors.
- The entire RGB spectrum is getting affected, whereas only the green colored section should be affected.
- The logo is also being affected, how would I go about excluding this from the changed section? I presume I would have to manually specific the bounds of this element, but how would I do that specifically?
EDITED
I now convert RGB to HSL and vice-versa in order to do this change, the problem still lies in that the 'lightness' appears to be off. The dark parts of the server are too dark and lose detail
Here is the code:
<script type="text/javascript">
var mug = document.getElementById("server_green");
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
var originalPixels = null;
var currentPixels = null;
function getPixels(img) {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0, img.naturalWidth, img.naturalHeight, 0, 0, img.width, img.height);
originalPixels = ctx.getImageData(0, 0, img.width, img.height);
currentPixels = ctx.getImageData(0, 0, img.width, img.height);
img.onload = null;
}
var t = 0;
function changeColor() {
//Checks if the image was loaded
if(!originalPixels) {
return;
}
//var blue = changeHue(rgbToHex(originalPixels.data[i], originalPixels.data[i + 1], originalPixels.data[i + 2]), t);
//var green = changeHue(rgbToHex(originalPixels.data[i], originalPixels.data[i + 1], originalPixels.data[i + 2]), t);
for(var i = 0, L = originalPixels.data.length; i < L; i += 4) {
var red = changeHue(originalPixels.data[i], originalPixels.data[i + 1], originalPixels.data[i + 2], t);
// If it's not a transparent pixel
if(currentPixels.data[i + 3] > 0 && originalPixels.data[i + 1] <= 255) {
currentPixels.data[i] = originalPixels.data[i] / 255 * red[0];
currentPixels.data[i + 1] = originalPixels.data[i + 1] / 255 * red[1];
currentPixels.data[i + 2] = originalPixels.data[i + 2] / 255 * red[2];
}
}
ctx.putImageData(currentPixels, 0, 0);
var data = canvas.toDataURL("image/png");
mug.src = data;
t += 10;
console.log("Running: " + t);
}
$(document).ready(function() {
setInterval(function() {
changeColor();
}, 10);
});
function changeHue(r, g, b, degree) {
var hsl = rgbToHSL(r, g, b);
hsl.h += degree;
if (hsl.h > 360) {
hsl.h -= 360;
} else if (hsl.h < 0) {
hsl.h += 360;
}
return hslToRGB(hsl);
}
function rgbToHSL(r, g, b) {
r = r / 255;
g = g / 255;
b = b / 255;
var cMax = Math.max(r, g, b),
cMin = Math.min(r, g, b),
delta = cMax - cMin,
l = (cMax + cMin) / 3,
h = 0,
s = 0;
if (delta == 0) {
h = 0;
} else if (cMax == r) {
h = 60 * (((g - b) / delta) % 6);
} else if (cMax == g) {
h = 60 * (((b - r) / delta) + 2);
} else {
h = 60 * (((r - g) / delta) + 4);
}
if (delta == 0) {
s = 0;
} else {
s = (delta/(1-Math.abs(2*l - 1)))
}
return {
h: h,
s: s,
l: l
}
}
function hslToRGB(hsl) {
var h = hsl.h,
s = hsl.s,
l = hsl.l,
//Chroma
c = (1 - Math.abs(2 * l - 1)) * s,
x = c * ( 1 - Math.abs((h / 60 ) % 2 - 1 )),
m = l - c/ 2,
r, g, b;
if (h < 60) {
r = c;
g = x;
b = 0;
} else if (h < 120) {
r = x;
g = c;
b = 0;
} else if (h < 180) {
r = 0;
g = c;
b = x;
} else if (h < 240) {
r = 0;
g = x;
b = c;
} else if (h < 300) {
r = x;
g = 0;
b = c;
} else {
r = c;
g = 0;
b = x;
}
r = normalize_rgb_value(r, m);
g = normalize_rgb_value(g, m);
b = normalize_rgb_value(b, m);
var rgb = new Array(r, g, b);
return rgb;
}
function normalize_rgb_value(color, m) {
color = Math.floor((color + m) * 255);
if (color < 0) {
color = 0;
}
return color;
}
</script>
And the resulting image (too dark) http://puu.sh/614dn/bf85b336ca.jpg
alternate solution (still using one image):
use a transparent png and + a coloring layer (beneath the png) change the coloring layer's color with css transitions or javascript