use SVG to render identicon so the browser can auto-resize the image

Temporary fix for websites with small width, where the identicon
overlaps with the textarea field.
This commit is contained in:
Martin Zimmermann 2013-10-29 16:58:38 +01:00
parent b672dae624
commit c3b6e0319e
5 changed files with 35 additions and 38 deletions

View File

@ -52,8 +52,9 @@ a {
> div.avatar { > div.avatar {
@include span-columns(1 of 11); @include span-columns(1 of 11);
> canvas { > svg {
@include isso-shadow; @include isso-shadow;
max-height: 48px;
} }
} }
@ -151,8 +152,9 @@ a {
> .avatar { > .avatar {
@include span-columns(1 of 11); @include span-columns(1 of 11);
> canvas { > svg {
@include isso-shadow; @include isso-shadow;
max-height: 48px;
} }
} }

View File

@ -12,13 +12,13 @@ define(["app/text/html", "app/dom", "app/utils", "app/api", "app/markup", "app/i
var el = $.htmlify(Mark.up(templates["postbox"])); var el = $.htmlify(Mark.up(templates["postbox"]));
// add a default identicon to not waste CPU cycles // add a default identicon to not waste CPU cycles
$(".avatar > canvas", el).replace(lib.identicons.blank(48, 48)); $(".avatar > svg", el).replace(lib.identicons.blank(4, 48));
// on text area focus, generate identicon from IP address // on text area focus, generate identicon from IP address
$(".textarea-wrapper > textarea", el).on("focus", function() { $(".textarea-wrapper > textarea", el).on("focus", function() {
if ($(".avatar canvas", el).classList.contains("blank")) { if ($(".avatar svg", el).classList.contains("blank")) {
$(".avatar canvas", el).replace( $(".avatar svg", el).replace(
lib.identicons.generate(lib.pbkdf2(api.remote_addr, api.salt, 1000, 6), 48, 48)); lib.identicons.generate(lib.pbkdf2(api.remote_addr, api.salt, 1000, 6), 4, 48));
} }
}); });
@ -31,7 +31,7 @@ define(["app/text/html", "app/dom", "app/utils", "app/api", "app/markup", "app/i
active = setTimeout(function() { active = setTimeout(function() {
lib.pbkdf2($(".input-wrapper > [type=email]", el).value || api.remote_addr, api.salt, 1000, 6) lib.pbkdf2($(".input-wrapper > [type=email]", el).value || api.remote_addr, api.salt, 1000, 6)
.then(function(rv) { .then(function(rv) {
$(".avatar canvas", el).replace(lib.identicons.generate(rv, 48, 48)); $(".avatar svg", el).replace(lib.identicons.generate(rv, 4, 48));
}); });
}, 200); }, 200);
}, false); }, false);
@ -96,7 +96,7 @@ define(["app/text/html", "app/dom", "app/utils", "app/api", "app/markup", "app/i
setTimeout(refresh, 60*1000); setTimeout(refresh, 60*1000);
}; refresh(); }; refresh();
$("div.avatar > canvas", el).replace(lib.identicons.generate(comment.hash, 48, 48)); $("div.avatar > svg", el).replace(lib.identicons.generate(comment.hash, 4, 48));
var entrypoint; var entrypoint;
if (comment.parent === null) { if (comment.parent === null) {

View File

@ -12,7 +12,6 @@ define(["q"], function(Q) {
var GRID = 5; var GRID = 5;
// Padding on the edge of the canvas in px // Padding on the edge of the canvas in px
var PADDING = 4;
var pad = function(n, width) { var pad = function(n, width) {
return n.length >= width ? n : new Array(width - n.length + 1).join("0") + n; return n.length >= width ? n : new Array(width - n.length + 1).join("0") + n;
@ -21,43 +20,39 @@ define(["q"], function(Q) {
/** /**
* Fill in a square on the canvas. * Fill in a square on the canvas.
*/ */
var fillBlock = function(x, y, color, ctx) { var fill = function(svg, x, y, padding, size, color) {
ctx.beginPath(); var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
ctx.rect(
PADDING+x*SQUARE, rect.setAttribute("x", padding + x * size);
PADDING+y*SQUARE, rect.setAttribute("y", padding + y * size);
SQUARE, rect.setAttribute("width", size);
SQUARE rect.setAttribute("height", size);
); rect.setAttribute("style", "fill: " + color);
ctx.fillStyle = color;
ctx.fill(); svg.appendChild(rect);
}; };
/** /**
* Pick random squares to fill in. * Pick random squares to fill in.
*/ */
var generateIdenticon = function(key, height, width) { var generateIdenticon = function(key, padding, size) {
var canvas = document.createElement("canvas"), var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
ctx = canvas.getContext("2d"); svg.setAttribute("version", "1.1");
canvas.width = width; svg.setAttribute("viewBox", "0 0 " + size + " " + size);
canvas.height = height; svg.setAttribute("preserveAspectRatio", "xMinYMin meet");
svg.setAttribute("shape-rendering", "crispEdges");
// FILL CANVAS BG fill(svg, 0, 0, 0, size + 2*padding, "#F0F0F0");
ctx.beginPath();
ctx.rect(0, 0, height, width);
ctx.fillStyle = '#F0F0F0';
ctx.fill();
if (typeof key === null) { if (typeof key === null) {
return canvas; return svg;
} }
Q.when(key, function(key) { Q.when(key, function(key) {
var hash = pad((parseInt(key, 16) % Math.pow(2, 18)).toString(2), 18), var hash = pad((parseInt(key, 16) % Math.pow(2, 18)).toString(2), 18),
index = 0, color = null; index = 0, color = null;
canvas.setAttribute("data-hash", key); svg.setAttribute("data-hash", key);
// via http://colrd.com/palette/19308/ // via http://colrd.com/palette/19308/
switch (hash.substring(hash.length - 3, hash.length)) { switch (hash.substring(hash.length - 3, hash.length)) {
@ -92,11 +87,11 @@ define(["q"], function(Q) {
for (var y=0; y<GRID; y++) { for (var y=0; y<GRID; y++) {
if (hash.charAt(index) === "1") { if (hash.charAt(index) === "1") {
fillBlock(x, y, color, ctx); fill(svg, x, y, padding, 8, color);
// FILL RIGHT SIDE SYMMETRICALLY // FILL RIGHT SIDE SYMMETRICALLY
if (x < Math.floor(GRID/2)) { if (x < Math.floor(GRID/2)) {
fillBlock((GRID-1) - x, y, color, ctx); fill(svg, (GRID-1) - x, y, padding, 8, color);
} }
} }
index++; index++;
@ -104,7 +99,7 @@ define(["q"], function(Q) {
} }
}); });
return canvas; return svg;
}; };
var generateBlank = function(height, width) { var generateBlank = function(height, width) {
@ -116,7 +111,7 @@ define(["q"], function(Q) {
].join(""), 2).toString(16); ].join(""), 2).toString(16);
var el = generateIdenticon(blank, height, width); var el = generateIdenticon(blank, height, width);
el.className = "blank"; el.classList.add("blank");
return el; return el;
}; };

View File

@ -1,6 +1,6 @@
<div class="isso-comment" id="isso-{{ id | blank }}"> <div class="isso-comment" id="isso-{{ id | blank }}">
<div class="avatar"> <div class="avatar">
<canvas data-hash="{{ hash }}" height="48px" width="48px"></canvas> <svg data-hash="{{ hash }}"></svg>
</div> </div>
<div class="text-wrapper"> <div class="text-wrapper">
<div class="isso-comment-header" role="meta"> <div class="isso-comment-header" role="meta">

View File

@ -1,6 +1,6 @@
<div class="postbox"> <div class="postbox">
<div class="avatar"> <div class="avatar">
<canvas class="placeholder" height="48px" width="48px"></canvas> <svg class="blank" data-hash="{{ hash }}"></svg>
</div> </div>
<div class="form-wrapper"> <div class="form-wrapper">
<div class="textarea-wrapper"> <div class="textarea-wrapper">