235 lines
6.3 KiB
JavaScript
235 lines
6.3 KiB
JavaScript
|
|
//////////////////////////
|
|
// use texture.js without d3 to create discerning patterns on the email blocks
|
|
/////////////////////////////////////
|
|
|
|
|
|
// some faked dom, see https://github.com/riccardoscalco/textures/issues/17
|
|
function dom(name) {
|
|
this.name = name;
|
|
this.els = [];
|
|
this.attrs = {};
|
|
}
|
|
dom.prototype.append = function(name) {
|
|
if (name === "defs") return this;
|
|
if (this.name === undefined) {
|
|
this.name = name;
|
|
return this;
|
|
}
|
|
var el = new dom(name);
|
|
this.els.push(el);
|
|
return el;
|
|
}
|
|
dom.prototype.attr = function(key, value) {
|
|
this.attrs[key] = value;
|
|
return this;
|
|
}
|
|
dom.prototype.toString = function() {
|
|
var attrs = [];
|
|
var k;
|
|
for (k in this.attrs) {
|
|
attrs += " " + k + "='" + this.attrs[k] + "'";
|
|
}
|
|
if (this.els.length) {
|
|
return "<"+this.name+attrs+">"+this.els.map(function(el) { return el.toString()}).join('\n')+"</"+this.name+">";
|
|
} else {
|
|
return "<"+this.name+attrs+"/>"
|
|
}
|
|
}
|
|
//////////// end of faked dom ///////////////////////////////
|
|
|
|
let categoryMap = {};
|
|
let textureMap = {};
|
|
function getColoredTexture(i, color) {
|
|
let j = i % 11; // update when adding items to switch:
|
|
switch(j) {
|
|
case 0:
|
|
return textures.lines().size(4).strokeWidth(1).stroke(color);
|
|
case 1:
|
|
return textures.circles().radius(2).size(5).fill('none').strokeWidth(1).stroke(color).complement();
|
|
case 2:
|
|
return textures.lines().size(10).orientation("3/8").stroke(color);
|
|
case 3:
|
|
return textures.lines().heavier(4).thinner(.8).stroke(color);
|
|
case 4:
|
|
return textures.paths().d("hexagons").size(3).strokeWidth(1).stroke(color);
|
|
case 5:
|
|
return textures.lines().orientation("vertical", "horizontal").size(4).strokeWidth(1).shapeRendering("crispEdges").stroke(color);
|
|
case 6:
|
|
return textures.paths().d("hexagons").size(5).strokeWidth(2).stroke("rgba(0,0,0,0)").fill(color);
|
|
case 7:
|
|
return textures.circles().size(4).stroke(color);
|
|
case 8:
|
|
return textures.circles().thicker().complement().stroke(color);
|
|
case 9:
|
|
return textures.paths().d("caps").lighter().thicker().size(5).stroke(color);
|
|
case 10:
|
|
return textures.paths().d("hexagons").size(4).strokeWidth(2).stroke(color);
|
|
// textures.lines().size(4).strokeWidth(1).orientation("-3/8"),
|
|
}
|
|
};
|
|
|
|
const categoryColors = {
|
|
"person": "#f00",
|
|
"vehicle": "#0f0",
|
|
"outdoor": "#006",
|
|
"animal": "#ff0",
|
|
"food": "#0ff",
|
|
"furniture": "#f0f",
|
|
"indoor": "#fff",
|
|
"electronic": "#390",
|
|
"kitchen": "#930",
|
|
"accessory": "#f90",
|
|
"sports": "#f09",
|
|
}
|
|
|
|
function getColorForSuperCategory(name) {
|
|
return categoryColors[name];
|
|
}
|
|
|
|
function getTextureForCategory(id) {
|
|
|
|
let hash = id;
|
|
if(!textureMap.hasOwnProperty(hash)) {
|
|
let color = categoryColors[categoryMap[id]['supercategory']];
|
|
textureMap[hash] = getColoredTexture(id, color);
|
|
}
|
|
|
|
return textureMap[hash];
|
|
}
|
|
|
|
|
|
|
|
class CocoCanvas {
|
|
start(){
|
|
this.catNavEl = document.getElementById('catNav');
|
|
this.canvas = document.getElementById('svgCanvas');
|
|
this.loadNav()
|
|
}
|
|
loadNav() {
|
|
let r = new Request('/categories.json');
|
|
fetch(r)
|
|
.then(response => response.json())
|
|
.then(categories => {
|
|
for(let cat of categories) {
|
|
categoryMap[cat['id']] = cat;
|
|
}
|
|
this.buildNav(categories);
|
|
}).catch(function(e){
|
|
console.error(e);
|
|
});
|
|
}
|
|
|
|
buildNav(categories) {
|
|
let ulEl = crel('ul');
|
|
for(let cat of categories) {
|
|
ulEl.appendChild(
|
|
crel('li', {
|
|
'id': 'category-' + cat['id'],
|
|
'on': {
|
|
'click': (e) => {
|
|
this.requestAnnotation(cat['id']);
|
|
}
|
|
}
|
|
}, cat['name'])
|
|
);
|
|
}
|
|
this.catNavEl.appendChild(ulEl);
|
|
|
|
let defsEl = document.createElementNS("http://www.w3.org/2000/svg", 'defs');
|
|
for(let cat of categories) {
|
|
let texture = getTextureForCategory(cat['id']);
|
|
let sel = new dom();
|
|
texture(sel);
|
|
defsEl.innerHTML += sel.toString();
|
|
}
|
|
this.canvas.appendChild(defsEl);
|
|
}
|
|
|
|
requestAnnotation(category_id) {
|
|
let r = new Request(`/annotation.json?category=${category_id}&normalise=100`);
|
|
fetch(r)
|
|
.then(response => response.json())
|
|
.then(annotation => {
|
|
this.addAnnotationAsShape(annotation);
|
|
}).catch(function(e){
|
|
console.error(e);
|
|
});;
|
|
}
|
|
|
|
pointsToD(points) {
|
|
let start = points.shift()
|
|
let d = `M${start[0].toPrecision(4)} ${start[1].toPrecision(4)} L `;
|
|
points = points.map((p) => `${p[0].toPrecision(4)} ${p[1].toPrecision(4)}`);
|
|
d += points.join(' ');
|
|
return d;
|
|
}
|
|
|
|
getMousePosition(evt) {
|
|
// from http://www.petercollingridge.co.uk/tutorials/svg/interactive/dragging/
|
|
let CTM = this.canvas.getScreenCTM();
|
|
return {
|
|
x: (evt.clientX - CTM.e) / CTM.a,
|
|
y: (evt.clientY - CTM.f) / CTM.d
|
|
};
|
|
}
|
|
|
|
addAnnotationAsShape(annotation) {
|
|
console.log('Add annotation', annotation);
|
|
|
|
let category = categoryMap[annotation['category_id']]
|
|
let texture = getTextureForCategory(category['id']);
|
|
|
|
let x = 500 - annotation['bbox'][2]/2;
|
|
let y = 500 - annotation['bbox'][3]/2;
|
|
let annEl = crel(document.createElementNS("http://www.w3.org/2000/svg", 'g'), {
|
|
'data-id': annotation['id'],
|
|
'transform': `translate(${x}, ${y})`,
|
|
'on': {
|
|
'mousedown': function(downE) {
|
|
console.log(downE);
|
|
console.log(this)
|
|
let offset = this.getMousePosition(downE);
|
|
// offset.x -= parseFloat(downE.target.getAttributeNS(null, "x"));
|
|
// offset.y -= parseFloat(downE.target.getAttributeNS(null, "y"));
|
|
|
|
// Get initial translation amount
|
|
console.log(annEl.transform.baseVal);
|
|
let transform = annEl.transform.baseVal.getItem(0);
|
|
offset.x -= transform.matrix.e;
|
|
offset.y -= transform.matrix.f;
|
|
|
|
let moveEvent = (moveE) => {
|
|
let coord = this.getMousePosition(moveE);
|
|
transform.matrix.e = coord.x - offset.x;
|
|
transform.matrix.f = coord.y - offset.y;
|
|
// annEl.setAttributeNS(null, "x", coord.x - offset.x);
|
|
// annEl.setAttributeNS(null, "y", coord.y - offset.y);
|
|
};
|
|
|
|
|
|
document.addEventListener('mousemove', moveEvent);
|
|
document.addEventListener('mouseup', (upE) => {
|
|
document.removeEventListener('mousemove', moveEvent);
|
|
});
|
|
|
|
}.bind(this)
|
|
}
|
|
});
|
|
|
|
for(let segment of annotation['segments']) {
|
|
|
|
let pathEl = crel(document.createElementNS("http://www.w3.org/2000/svg", 'path'), {
|
|
'fill': texture.url(),
|
|
'd': this.pointsToD(segment)
|
|
});
|
|
annEl.appendChild(pathEl);
|
|
}
|
|
console.log(annEl);
|
|
this.canvas.appendChild(annEl);
|
|
}
|
|
}
|
|
|
|
let cc = new CocoCanvas();
|
|
cc.start();
|