| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- 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
- ,RESULT;
- var 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);
- };
- var 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;
- }
- var 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)
- };
- var filterImage = function(img) {
- var pixelSum = 0;
- for (var 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 (var 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;
- }
- var loadImgFromUrl = function(src, cb) {
- var xhr = new XMLHttpRequest();
- xhr.responseType = 'blob';
- xhr.onreadystatechange = function() {
- if (xhr.readyState === 4) {
- if (xhr.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!} */ (xhr.response));
- } else {
- cb(null);
- }
- }
- };
- xhr.open('GET', src, true);
- xhr.send(null);
- };
- var 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) {
- userImgs[i].img = img;
- loadImages(userImgs, doneImgLoading);
- });
- return;
- }
- }
- var imgs = [];
- userImgs.forEach(function(i) {
- if (i.img)
- imgs.push(i.img);
- });
- doneImgLoading(imgs);
- };
- var 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(function(a, b) {
- if (!a.img)
- return 1;
- if (!b.img)
- return -1;
- return Math.random() - 0.5;
- });
- imgIndex = 0;
- }
- }
- }
- var callbacks = [],
- isLoading = false;
- return function(cb) {
- if (RESULT) {
- cb(RESULT);
- } else if (isLoading) {
- callbacks.push(cb);
- } else {
- var background = drawBackground()
- ,userImgs = [];
- isLoading = true;
- callbacks.push(cb);
- for (var userId in SLACK.context.users) {
- if (!SLACK.context.users[userId].deleted)
- userImgs.push({
- src: "api/avatar?user=" +userId
- });
- }
- loadImages(userImgs, function(imgs) {
- renderAvatars(background, imgs);
- RESULT = canvas.toDataURL();
- callbacks.forEach(function(i) {
- i(RESULT);
- });
- });
- }
- }
- })();
|