| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- /** @type {function(string, Object<string, Chatter>, Function)} */
- var createContextBackground = (function() {
- var canvas = document.createElement("canvas"),
- ctx = canvas.getContext('2d'),
- /** @const */
- WIDTH = canvas.width = 250,
- /** @const */
- HEIGHT = canvas.height = 290,
- /** @const */
- MARGIN = 20,
- /** @const */
- NB_ITEM = 3,
- /** @const */
- ITEM_SIZE = (WIDTH -2*MARGIN) / NB_ITEM,
- /** @const */
- ITEM_SPACING = 0.1 * ITEM_SIZE,
- /** @const */
- ITEM_INNER_SIZE = Math.floor(ITEM_SIZE -(ITEM_SPACING*2)),
- /** @const */
- AVATAR_SIZE = ITEM_INNER_SIZE * 0.5,
- /** @type {Object<string, string>} */
- RESULT = {},
- drawItem = function(background, avatar, x0, y0) {
- var y0Index = Math.floor(y0),
- y1Index = Math.floor(y0 + ITEM_SIZE),
- topColor = [
- background.data[y0Index *WIDTH *4 +0],
- background.data[y0Index *WIDTH *4 +1],
- background.data[y0Index *WIDTH *4 +2]
- ],
- botColor = [
- background.data[y1Index *WIDTH *4 +0],
- background.data[y1Index *WIDTH *4 +1],
- background.data[y1Index *WIDTH *4 +2]
- ],
- targetPcent = 1.1,
- targetColor = (((topColor[0] *targetPcent) << 16) |
- ((topColor[1] *targetPcent) << 8) |
- (topColor[2] *targetPcent)).toString(16);
- ctx.fillStyle = '#' +targetColor;
- ctx.beginPath();
- ctx.moveTo(x0 +ITEM_SIZE /2, y0 +ITEM_SPACING);
- ctx.lineTo(x0 -ITEM_SPACING +ITEM_SIZE, y0 +ITEM_SIZE /2);
- ctx.lineTo(x0 +ITEM_SIZE /2, y0 -ITEM_SPACING +ITEM_SIZE);
- ctx.lineTo(x0 +ITEM_SPACING, y0 +ITEM_SIZE /2);
- ctx.closePath();
- ctx.fill();
- ctx.putImageData(
- blend(
- ctx.getImageData(
- x0 +ITEM_SPACING,
- y0 +ITEM_SPACING,
- ITEM_INNER_SIZE,
- ITEM_INNER_SIZE),
- avatar),
- x0 +ITEM_SPACING,
- y0 +ITEM_SPACING);
- },
- blend = function(img, img2) {
- var margin = (img.height -img2.height) /2;
- for (var i =0; i < img2.height; i++)
- for (var j =0; j < img2.width; j++) {
- var img2Grey = (img2.data[(i *img2.width +j) *4]) / 255,
- iImg = ((i +margin) *img.width +j +margin) *4;
- img.data[iImg] *= img2Grey;
- img.data[iImg +1] *= img2Grey;
- img.data[iImg +2] *= img2Grey;
- }
- return img;
- },
- drawBackground = function() {
- var grd = ctx.createLinearGradient(0, 0, 0, HEIGHT);
- grd.addColorStop(0, "#4D394B");
- grd.addColorStop(1, "#201820");
- ctx.fillStyle = grd;
- ctx.fillRect(0, 0, WIDTH, HEIGHT);
- return ctx.getImageData(0, 0, WIDTH, HEIGHT);
- },
- filterImage = function(img) {
- var pixelSum = 0,
- i;
- for (i =0; i < img.width *img.height *4; i +=4) {
- img.data[i] = img.data[i +1] = img.data[i +2] = (img.data[i] +img.data[i +1] +img.data[i +2]) / 3;
- img.data[i +3] = 50;
- pixelSum += img.data[i];
- }
- // Invert colors if image is dark
- if (pixelSum / (img.height * img.width) < 50)
- for (i =0; i < img.width *img.height *4; i +=4)
- img.data[i] = img.data[i +1] = img.data[i +2] = 255 - img.data[i];
- return img;
- },
- loadImgFromUrl = function(src, cb) {
- new HttpRequest(src)
- .callbackSuccess(function(code, head, response) {
- if (response) {
- var img = new Image();
- img.onload = function() {
- var imgCanvas = document.createElement("canvas");
- imgCanvas.height = imgCanvas.width = AVATAR_SIZE;
- var imgCtx = imgCanvas.getContext('2d');
- imgCtx.drawImage(img, 0, 0, AVATAR_SIZE, AVATAR_SIZE);
- cb(filterImage(imgCtx.getImageData(0, 0, AVATAR_SIZE, AVATAR_SIZE)));
- };
- img.onerror = function() {
- cb(null);
- };
- img.src = window.URL.createObjectURL(/** @type {Blob!} */ (response));
- } else {
- cb(null);
- }
- })
- .callbackError(function() {
- cb(null);
- })
- .setResponseType(HttpRequestResponseType.BLOB)
- .send();
- },
- loadImages = function(userImgs, doneImgLoading) {
- for (var i =0, nbImgs = userImgs.length; i < nbImgs; i++) {
- if (userImgs[i].img === undefined) {
- // Do load image
- loadImgFromUrl(userImgs[i].src, function(img) { // jshint ignore: line
- userImgs[i].img = img;
- loadImages(userImgs, doneImgLoading);
- });
- return;
- }
- }
- var imgs = [];
- userImgs.forEach(function(i) {
- if (i.img)
- imgs.push(i.img);
- });
- doneImgLoading(imgs);
- },
- compareImgs = function(a, b) {
- if (!a.img)
- return 1;
- if (!b.img)
- return -1;
- return Math.random() - 0.5;
- },
- renderAvatars = function(background, imgs) {
- imgs.sort(function(a, b) {
- return Math.random() - 0.5;
- });
- for (var imgIndex =0, i =MARGIN; i < WIDTH -MARGIN*2; i += ITEM_SIZE)
- for (var j =0; j +ITEM_SIZE <= HEIGHT; j += ITEM_SIZE) {
- drawItem(background, imgs[imgIndex], i, j);
- imgIndex++;
- if (imgIndex === imgs.length) {
- imgs.sort(compareImgs);
- imgIndex = 0;
- }
- }
- },
- callbacks = {},
- isLoading = {};
- return function(ctxId, users, cb) {
- if (RESULT[ctxId]) {
- cb(RESULT[ctxId]);
- } else if (isLoading[ctxId]) {
- if (!callbacks[ctxId])
- callbacks[ctxId] = [ cb ];
- else
- callbacks[ctxId].push(cb);
- } else {
- var background = drawBackground(),
- userImgs = [];
- isLoading[ctxId] = true;
- if (!callbacks[ctxId])
- callbacks[ctxId] = [ cb ];
- else
- callbacks[ctxId].push(cb);
- for (var userId in users) {
- if (!users[userId].deleted && !users[userId].isBot)
- userImgs.push({
- src: users[userId].getSmallIcon()
- });
- }
- loadImages(userImgs, function(imgs) {
- renderAvatars(background, imgs);
- RESULT[ctxId] = canvas.toDataURL();
- callbacks[ctxId].forEach(function(i) {
- i(RESULT[ctxId]);
- });
- });
- }
- };
- })();
|