xxxxxxxxxx
130
const apiKey = '54cf2520-1884-4a07-88b5-5502ab007ac9'
const lowObjectCount = 20
let loading;
let cultures;
let images = []
function setup() {
createCanvas(1, 1);
loadJSON(`https://api.harvardartmuseums.org/culture?size=500&apikey=${apiKey}`, cultureHandler)
createElement('h1', 'Collection objects by culture').style('padding', '0').style('margin', '0')
createElement('h5', '+ Object images from less represented cultures').style('padding', '0').style('margin', '0')
createElement('span', 'green: large collection |x| dark grey: small collection |x| images from small collections sorted by dominant color').style('font-size', '10px')
loading = createElement('div', 'LOADING IMAGES BELOW...')
.style('float', 'right')
.style('font-size', '12px')
.style('position', 'relative')
.style('top', '-50px')
}
function draw() {
background(255);
}
// view
function displayCultures() {
cultures = cultures.sort((a, b) => (a.name > b.name) ? 1 : -1)
const average = cultures.reduce((total, next) => total + next.objectcount, 0) / cultures.length;
const main = createElement('div')
.style('float', 'left')
.style('width', '100%')
for (var i = 0; i < cultures.length; i++) {
const culture = cultures[i];
const color = map(culture.objectcount, 0, average, 0, 100);
let wrapper = createElement('div', ` ${culture.name} (${culture.objectcount}) `)
.addClass('center')
.style('display', 'inline-block')
.style('width', '200px')
.style('height', '50px')
.style('text-align', 'center')
.style('text-indent', '20px')
.style('font-size', '10pt')
.style('color', '#000000')
.style('margin', '0')
.style('padding', '0')
.style('padding-top', '30px')
.style('background-color', `hsl(150, ${color}%, ${50}%)`)
if (culture.objectcount <= lowObjectCount)
wrapper.style('background-color', '#2b2b2b')
.style('color', '#bfbaba')
main.child(wrapper)
}
}
function displayObjects() {
loading.remove()
images = images.sort((a, b) => parseFloat(b.color) - parseFloat(a.color));
for (var i = 0; i < images.length; i++) {
const main = createElement('span').style('float', 'left')
const culture = images[i];
const a = createImg(`${culture.image}?height=150`, 'a')
main.child(a)
}
}
// data
function getItemImages(item) {
let images = [];
for (var i = 0; i < item.images.length; i++) {
const image = item.images[i].baseimageurl;
let primaryColor = 0;
if (item.colors) {
primaryColor = Math.max.apply(Math, item.colors.map( (c) => sumColor(hexToRgb(c.color))))
primaryColor = (primaryColor === undefined) ? 0 : primaryColor;
}
images.push({ "image": image, "color": primaryColor });
}
return images
}
function getObjects(page = 1) {
const filteredCultures = cultures.filter( (o) => o.objectcount < lowObjectCount )
const culturesURLParam = filteredCultures.map(culture => culture.name).join('|');
loadJSON(`https://api.harvardartmuseums.org/object?page=${page}&size=500&culture=${culturesURLParam}&apikey=${apiKey}`, objectsHandler)
}
// handlers
function objectsHandler(res) {
const page = res.info.page;
const pageMax = res.info.pages;
for (var i = 0; i < res.records.length; i++) {
const item = res.records[i]
if (!item.images) continue
images.push(getItemImages(item))
}
if (page < pageMax) {
console.log(`recieved page ${page} of ${pageMax}`)
getObjects(page + 1)
return
}
images = images.flat()
displayObjects()
}
function cultureHandler(res) {
cultures = res.records;
displayCultures()
getObjects()
return;
}
// --helpers from the internets--
function sumColor(str) {
if (!str) return 0
const rgb = str.toString().replace(/[()]/g, "").split(",").map(Number);
return 0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2];
}
function hexToRgb(hex) {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return `(${parseInt(result[1], 16)},${parseInt(result[2], 16)},${parseInt(result[3], 16)})`
}
function map(value, x1, y1, x2, y2) {
return (value - x1) * (y2 - x2) / (y1 - x1) + x2;
}