summaryrefslogtreecommitdiff
path: root/src
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 /src
parentb08b596b34a9f84248df294c7ee4f0c953e000a2 (diff)
font and sky and such
Diffstat (limited to 'src')
-rw-r--r--src/graph.js110
-rw-r--r--src/views/Legend.js12
2 files changed, 76 insertions, 46 deletions
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 }) {