summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2021-09-21 15:24:38 +0200
committerJules Laplace <julescarbon@gmail.com>2021-09-21 15:24:38 +0200
commit48374c440e344745ecbf96a3e2803fdc2bf35626 (patch)
tree83351e625743b31e5d13d797b8687742637457ea
parentb08b596b34a9f84248df294c7ee4f0c953e000a2 (diff)
font and sky and such
-rw-r--r--data_store/tags.csv2
-rw-r--r--db.json34
-rw-r--r--load_spreadsheet.js3
-rw-r--r--public/assets/css/css.css19
-rw-r--r--public/assets/css/fonts.css8
-rw-r--r--src/graph.js110
-rw-r--r--src/views/Legend.js12
7 files changed, 108 insertions, 80 deletions
diff --git a/data_store/tags.csv b/data_store/tags.csv
index 4732384..1a2874b 100644
--- a/data_store/tags.csv
+++ b/data_store/tags.csv
@@ -1,4 +1,4 @@
-Title,,1620s,painting,blunt,National Gallery of Canada,Art Gallery of Ontario,Courtauld Institute,Stankievech,connsoeurship,double agent,forensics ,black box,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
+Title,,1620s,painting,blunt,National Gallery of Canada,Art Gallery of Ontario,Courtauld Institute,Stankievech,connsoeurship,double agent,forensics,black box,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
01 Poussin: No6092,1,x,x,x,x,,,,x,,x,x,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
02 No6092: Xray,2,,,,x,,,,,,x,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
03 Blunt: Apollo,3,,,x,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
diff --git a/db.json b/db.json
index 075cb1c..9f6a3c0 100644
--- a/db.json
+++ b/db.json
@@ -11,8 +11,8 @@
"tag_2": 3,
"tag_3": 4,
"tag_4": 8,
- "tag_5": 11,
- "tag_6": 0,
+ "tag_5": 10,
+ "tag_6": 11,
"tag_7": 0,
"tag_8": 0,
"images": [
@@ -42,7 +42,7 @@
"short_title": "02 No6092: Xray",
"type": "image",
"tag_0": 4,
- "tag_1": 0,
+ "tag_1": 10,
"tag_2": 0,
"tag_3": 0,
"tag_4": 0,
@@ -210,7 +210,7 @@
"short_title": "06 NGC: Record ",
"type": "image",
"tag_0": 4,
- "tag_1": 0,
+ "tag_1": 10,
"tag_2": 0,
"tag_3": 0,
"tag_4": 0,
@@ -364,7 +364,7 @@
"short_title": "10 No6092: Label ",
"type": "image",
"tag_0": 4,
- "tag_1": 0,
+ "tag_1": 10,
"tag_2": 0,
"tag_3": 0,
"tag_4": 0,
@@ -749,7 +749,7 @@
"short_title": "20 Rees: Xrays",
"type": "image",
"tag_0": 6,
- "tag_1": 0,
+ "tag_1": 10,
"tag_2": 0,
"tag_3": 0,
"tag_4": 0,
@@ -806,7 +806,7 @@
"type": "image",
"tag_0": 2,
"tag_1": 4,
- "tag_2": 0,
+ "tag_2": 10,
"tag_3": 0,
"tag_4": 0,
"tag_5": 0,
@@ -929,7 +929,7 @@
"short_title": "25 Chu: Courbet Signature",
"type": "image",
"tag_0": 5,
- "tag_1": 0,
+ "tag_1": 10,
"tag_2": 0,
"tag_3": 0,
"tag_4": 0,
@@ -964,7 +964,7 @@
"short_title": "26 Fernier: Courbet Signatures",
"type": "image",
"tag_0": 5,
- "tag_1": 0,
+ "tag_1": 10,
"tag_2": 0,
"tag_3": 0,
"tag_4": 0,
@@ -999,7 +999,7 @@
"short_title": "27 Courbet: Signature",
"type": "image",
"tag_0": 5,
- "tag_1": 0,
+ "tag_1": 10,
"tag_2": 0,
"tag_3": 0,
"tag_4": 0,
@@ -1449,7 +1449,7 @@
"tag_0": 6,
"tag_1": 8,
"tag_2": 9,
- "tag_3": 0,
+ "tag_3": 10,
"tag_4": 0,
"tag_5": 0,
"tag_6": 0,
@@ -1485,7 +1485,7 @@
"tag_1": 2,
"tag_2": 8,
"tag_3": 9,
- "tag_4": 0,
+ "tag_4": 10,
"tag_5": 0,
"tag_6": 0,
"tag_7": 0,
@@ -1519,7 +1519,7 @@
"tag_0": 1,
"tag_1": 7,
"tag_2": 8,
- "tag_3": 0,
+ "tag_3": 10,
"tag_4": 0,
"tag_5": 0,
"tag_6": 0,
@@ -1594,8 +1594,8 @@
"short_title": "44 Poe: Purloined Letter",
"type": "image",
"tag_0": 9,
- "tag_1": 11,
- "tag_2": 0,
+ "tag_1": 10,
+ "tag_2": 11,
"tag_3": 0,
"tag_4": 0,
"tag_5": 0,
@@ -1792,8 +1792,8 @@
"tag_0": 3,
"tag_1": 5,
"tag_2": 9,
- "tag_3": 11,
- "tag_4": 0,
+ "tag_3": 10,
+ "tag_4": 11,
"tag_5": 0,
"tag_6": 0,
"tag_7": 0,
diff --git a/load_spreadsheet.js b/load_spreadsheet.js
index acfdd35..1d4539f 100644
--- a/load_spreadsheet.js
+++ b/load_spreadsheet.js
@@ -60,6 +60,9 @@ async function main() {
// if there is a corresponding record in the data store, accumulate it
if (String(index + 1) in dataStore) {
await loadFiles(dataStore[index + 1], record);
+ if (!record.images.length) {
+ console.log(`/!\\ No images: ${dataStore[index + 1]} // ${row.Title}`);
+ }
}
// if we haven't seen this ID before, append it
if (!pageById[index]) {
diff --git a/public/assets/css/css.css b/public/assets/css/css.css
index 590e530..287dceb 100644
--- a/public/assets/css/css.css
+++ b/public/assets/css/css.css
@@ -6,7 +6,7 @@ body {
height: 100%;
overflow: hidden;
background: black;
- font-family: "Merriweather", serif;
+ font-family: "Spectral", serif;
}
.scene-tooltip {
background: black;
@@ -16,7 +16,7 @@ body {
text-align: center;
font-size: 1rem !important;
line-height: 1.5;
- font-family: "Merriweather", serif !important;
+ font-family: "Spectral", serif !important;
}
/** Legend */
@@ -25,15 +25,12 @@ body {
position: absolute;
bottom: 0;
left: 0;
- font-size: 0.75rem;
+ font-size: 0.875rem;
line-height: 1.75;
- padding: 1rem;
- margin: 1rem 2rem;
- background: rgba(0, 0, 0, 0.5);
+ margin: 1rem 1.5rem;
+ /*background: rgba(0, 0, 0, 0.5);*/
color: #fff;
transition: opacity 0.2s;
- text-transform: uppercase;
- font-variant: small-caps;
}
.legend .category {
cursor: pointer;
@@ -69,7 +66,7 @@ body {
pointer-events: none;
transition: opacity 0.2s;
opacity: 0;
- background: rgba(0, 0, 0, 0.75);
+ background: rgba(0, 0, 0, 0.8);
color: white;
display: flex;
flex-direction: row;
@@ -85,7 +82,7 @@ body {
.detail .content > div {
min-height: 100%;
padding: 3rem 5rem 6rem 5rem;
- background: rgba(0, 0, 0, 0.5);
+ /*background: rgba(0, 0, 0, 0.5);*/
}
.detail .media {
padding: 3rem 5rem;
@@ -106,8 +103,6 @@ body {
font-size: 1.25rem;
line-height: 1.5;
margin-bottom: 2rem;
- text-transform: capitalize;
- font-variant: small-caps;
}
.detail .title .index {
margin-bottom: 0.75rem;
diff --git a/public/assets/css/fonts.css b/public/assets/css/fonts.css
index f1e8429..a4fecb5 100644
--- a/public/assets/css/fonts.css
+++ b/public/assets/css/fonts.css
@@ -1,11 +1,11 @@
@font-face {
- font-family: "Merriweather";
- src: url("../fonts/merriweather/Merriweather-Regular.ttf");
+ font-family: "Spectral";
+ src: url("../fonts/spectral/Spectral-Regular.ttf");
font-style: normal;
}
@font-face {
- font-family: "Merriweather";
- src: url("../fonts/merriweather/Merriweather-Italic.ttf");
+ font-family: "Spectral";
+ src: url("../fonts/spectral/Spectral-Italic.ttf");
font-style: italic;
}
diff --git a/src/graph.js b/src/graph.js
index 84d9d79..ffba2c2 100644
--- a/src/graph.js
+++ b/src/graph.js
@@ -3,12 +3,17 @@ import ForceGraph3D from "3d-force-graph";
import SpriteText from "three-spritetext";
import { union } from "./utils/set_utils.js";
import { randint, choice, pad } from "./utils/index.js";
+import { addSkyGradient } from "./sky.js";
const IMG_SCALE = 16;
-const MAIN_IMG_SCALE = 80;
+const MAIN_IMG_SCALE = 100;
const PAINTING_SCALE = 30;
const VIDEO_SCALE = 40;
const OBJECT_SCALE = 10;
+const OBJECT_SCALES = {
+ 39: 20,
+ 31: 20,
+};
const PAINTINGS = new Set([2, 10, 21, 22, 23, 24, 27, 40, 42]);
@@ -22,7 +27,6 @@ export default function buildGraph({ db, handlers }) {
/**
* load nodes and links
*/
-
db.page.forEach((item, index) => {
const node = {
title: item.short_title,
@@ -81,27 +85,44 @@ export default function buildGraph({ db, handlers }) {
const highlightNodes = new Set();
const highlightLinks = new Set();
let selectedNode = null;
- const objects = [];
+ let objects = [];
/** build group */
- let graph = ForceGraph3D();
+ let graph = ForceGraph3D({ controlType: "orbit" });
graph(document.querySelector("#graph"))
.graphData(data)
.showNavInfo(false)
.nodeLabel((node) => node.title)
.nodeThreeObject((node) => {
let sprite, material, texture, video;
+ let catNumber = node.id + 1;
+ // if (catNumber !== 48) return null;
+ // 3D object
if (node.data.object) {
- objects.push({ id: node.id, object: node.data.object });
- const object = node.data.object;
+ const object = node.data.object.clone();
+ const objectHandle = { catNumber, object };
+ objects.push(objectHandle);
var box = new THREE.Box3().setFromObject(object);
var center = new THREE.Vector3();
box.getCenter(center);
object.position.sub(center);
- object.scale.set(OBJECT_SCALE, OBJECT_SCALE, OBJECT_SCALE);
+ if (OBJECT_SCALES[catNumber]) {
+ object.scale.set(
+ OBJECT_SCALES[catNumber],
+ OBJECT_SCALES[catNumber],
+ OBJECT_SCALES[catNumber]
+ );
+ } else {
+ object.scale.set(OBJECT_SCALE, OBJECT_SCALE, OBJECT_SCALE);
+ }
+ const quaternion = graph.camera().quaternion;
+ reorientObject(quaternion)(objectHandle);
return object;
- } else if (node.data.thumbnail?.uri) {
+ }
+ // Videos and images
+ else if (node.data.thumbnail?.uri) {
+ // Video thumbs
const isVideo = node.data.thumbnail.type === "video";
if (isVideo) {
video = document.createElement("video");
@@ -111,24 +132,34 @@ export default function buildGraph({ db, handlers }) {
video.autoplay = true;
video.play();
texture = new THREE.VideoTexture(video);
- } else {
+ }
+ // Image thumbs
+ else {
texture = new THREE.TextureLoader().load(node.data.thumbnail.uri);
}
- // console.log(imgTexture);
const aspect = node.data.thumbnail.width / node.data.thumbnail.height;
material = new THREE.SpriteMaterial({ map: texture });
sprite = new THREE.Sprite(material);
+ // First image
if (node.id === 0) {
sprite.scale.set(MAIN_IMG_SCALE, MAIN_IMG_SCALE / aspect);
- } else if (PAINTINGS.has(node.id + 1)) {
+ }
+ // Paintings
+ else if (PAINTINGS.has(catNumber)) {
sprite.scale.set(PAINTING_SCALE, PAINTING_SCALE / aspect);
- } else if (isVideo) {
+ }
+ // Videos
+ else if (isVideo) {
sprite.scale.set(VIDEO_SCALE, VIDEO_SCALE / aspect);
- } else {
+ }
+ // Other images
+ else {
sprite.scale.set(IMG_SCALE, IMG_SCALE / aspect);
}
return sprite;
- } else {
+ }
+ // Texts
+ else {
sprite = new SpriteText(
node.title.split(/[ :]+/).slice(0, 3).join(" ")
);
@@ -154,19 +185,31 @@ export default function buildGraph({ db, handlers }) {
handlers.click(node);
})
- .linkWidth((link) => (highlightLinks.has(link) ? 4 : 1));
+ .linkWidth((link) => (highlightLinks.has(link) ? 2 : 0.75));
- graph.controls().addEventListener("change", () => {
+ // graph.backgroundColor("#000000");
+ // graph.renderer().setClearColor(0x000000, 0);
+ addSkyGradient(graph.scene());
+
+ const reorient = () => {
const quaternion = graph.camera().quaternion;
- const { axis, angle } = getAxisAndAngelFromQuaternion(quaternion);
- objects.forEach(({ id, object }) => {
- object.setRotationFromQuaternion(quaternion);
- // the clock object is turned 90 degrees
- if (id === 32) {
- object.rotateY(Math.PI / 2);
- }
- });
- });
+ objects.forEach(reorientObject(quaternion));
+ };
+
+ const reorientObject = (quaternion) => ({ catNumber, object }) => {
+ object.setRotationFromQuaternion(quaternion);
+ // the clock object is turned 90 degrees
+ if (catNumber === 33) {
+ object.rotateY(Math.PI / 2);
+ }
+ if (catNumber === 48) {
+ object.rotateZ(Math.PI * -0.25);
+ object.rotateX(Math.PI * -0.45);
+ object.rotateY(Math.PI * 0.5);
+ }
+ };
+
+ graph.controls().addEventListener("change", reorient);
const updateHighlight = () => {
// trigger update of highlighted objects in scene
@@ -221,6 +264,7 @@ export default function buildGraph({ db, handlers }) {
}
const { nodes, links } = data;
const visible = new Set();
+ objects = [];
const selectedData = {};
selectedData.nodes = nodes.filter((node) => {
@@ -243,7 +287,7 @@ export default function buildGraph({ db, handlers }) {
zoomIn();
};
- // graph.d3Force("charge").strength(-150);
+ graph.d3Force("charge").strength(-100);
// camera orbit
initialZoom();
@@ -254,18 +298,4 @@ export default function buildGraph({ db, handlers }) {
// stars();
}
-function getAxisAndAngelFromQuaternion(q) {
- const angle = 2 * Math.acos(q.w);
- var s;
- if (1 - q.w * q.w < 0.000001) {
- // test to avoid divide by zero, s is always positive due to sqrt
- // if s close to zero then direction of axis not important
- // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/
- s = 1;
- } else {
- s = Math.sqrt(1 - q.w * q.w);
- }
- return { axis: new THREE.Vector3(q.x / s, q.y / s, q.z / s), angle };
-}
-
const commonGroups = (a, b) => union(a.groups, b.groups);
diff --git a/src/views/Legend.js b/src/views/Legend.js
index 411ca81..eac860c 100644
--- a/src/views/Legend.js
+++ b/src/views/Legend.js
@@ -7,16 +7,16 @@ import React, { useState, useEffect } from "react";
var categories = [
// tag ID = array offset + 1
"1620s",
- "painting",
- "blunt",
+ "Painting",
+ "Blunt",
"National Gallery of Canada",
"Art Gallery of Ontario",
"Courtauld Institute",
"Stankievech",
- "connsoeurship",
- "double agent",
- "forensics",
- "black box",
+ "Connosieurship",
+ "Double Agent",
+ "Forensics",
+ "Black Box",
];
export default function Legend({ visible, selected, onSelect }) {