diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/graph.js | 18 | ||||
| -rw-r--r-- | src/views/Clock.js | 108 | ||||
| -rw-r--r-- | src/views/Clocks.js | 15 | ||||
| -rw-r--r-- | src/views/Detail.js | 5 | ||||
| -rw-r--r-- | src/views/Legend.js | 17 |
5 files changed, 156 insertions, 7 deletions
diff --git a/src/graph.js b/src/graph.js index a210f23..3a0e8a1 100644 --- a/src/graph.js +++ b/src/graph.js @@ -3,7 +3,9 @@ import ForceGraph3D from "3d-force-graph"; import SpriteText from "three-spritetext"; import { union } from "./utils/set_utils.js"; -const IMG_SCALE = 20; +const IMG_SCALE = 16; +const MAIN_IMG_SCALE = 80; +const OBJECT_SCALE = 10; export default function buildGraph({ db, objects, handlers }) { const linkable = {}; @@ -85,7 +87,7 @@ export default function buildGraph({ db, objects, handlers }) { var center = new THREE.Vector3(); box.getCenter(center); object.position.sub(center); - object.scale.set(100, 100, 100); + object.scale.set(OBJECT_SCALE, OBJECT_SCALE, OBJECT_SCALE); return object; } else if (node.data.thumbnail?.uri) { if (node.data.thumbnail.type === "video") { @@ -103,7 +105,11 @@ export default function buildGraph({ db, objects, handlers }) { const aspect = node.data.thumbnail.width / node.data.thumbnail.height; material = new THREE.SpriteMaterial({ map: texture }); sprite = new THREE.Sprite(material); - sprite.scale.set(IMG_SCALE, IMG_SCALE / aspect); + if (node.id === 0) { + sprite.scale.set(MAIN_IMG_SCALE, MAIN_IMG_SCALE / aspect); + } else { + sprite.scale.set(IMG_SCALE, IMG_SCALE / aspect); + } return sprite; } else { sprite = new SpriteText( @@ -117,6 +123,12 @@ export default function buildGraph({ db, objects, handlers }) { }) .onNodeClick(handlers.click); + // TrackballControls + graph.controls().addEventListener("change", () => { + const position = graph.cameraPosition(); + // console.log(position); + }); + const initialZoom = () => { const distance = 20000; let angle = 0; diff --git a/src/views/Clock.js b/src/views/Clock.js new file mode 100644 index 0000000..a394b62 --- /dev/null +++ b/src/views/Clock.js @@ -0,0 +1,108 @@ +/** + * Analog Clock + */ + +import React, { useState, useEffect } from "react"; + +const clock = { + width: "20vw", + height: "20vw", + background: "url(assets/img/clock/clock.png)", + backgroundSize: "contain", + backgroundPosition: "center center", + backgroundRepeat: "no-repeat", + position: "relative", +}; + +const handStyle = { + position: "absolute", + top: "0%", + left: "0%", +}; + +const hourStyle = { + ...handStyle, + height: "calc(540 / 1268 * 10vw)", + transformOrigin: "45.46% 96.62%", +}; + +const minuteStyle = { + ...handStyle, + height: "calc(795 / 1268 * 10vw)", + transformOrigin: "50% 84.05%", +}; + +const secondStyle = { + ...handStyle, + height: "calc(993 / 1268 * 10vw)", + transformOrigin: "45.83% 76.63%", +}; + +const hourTransform = + "translateX(10.45vw) translateY(10vw) translateX(-100%) translateY(-100%) "; +const minuteTransform = + "translateX(10.45vw) translateY(10.8vw) translateX(-100%) translateY(-100%) "; +const secondTransform = + "translateX(10.2vw) translateY(11.5vw) translateX(-100%) translateY(-100%) "; + +export default function Clock({ utc }) { + const [hour, setHour] = useState({}); + const [minute, setMinute] = useState({}); + const [second, setSecond] = useState({}); + + useEffect(() => { + const update = () => { + const time = new Date(); + const hours = utc ? time.getUTCHours() : time.getHours(); + const minutes = time.getMinutes(); + const seconds = time.getSeconds(); + const ms = time.getMilliseconds(); + setHour({ + ...hourStyle, + transform: + hourTransform + + "rotate(" + + (((hours % 12) + minutes / 60 + seconds / 3600) / 12) * 360 + + "deg)", + }); + setMinute({ + ...minuteStyle, + transform: + minuteTransform + + "rotate(" + + (minutes / 60 + seconds / 3600) * 360 + + "deg)", + }); + setSecond({ + ...secondStyle, + transform: + secondTransform + + "rotate(" + + (seconds / 60 + ms / 60000) * 360 + + "deg)", + }); + }; + update(); + const intervalId = setInterval(update, 50); + return () => clearInterval(intervalId); + }, []); + + return ( + <div style={clock}> + <img src="assets/img/clock/hour.png" style={hour} /> + <img src="assets/img/clock/minute.png" style={minute} /> + <img src="assets/img/clock/second.png" style={second} /> + </div> + ); +} + +// ratio: 500 / 1268 +// hour: 540 +// minute: 795 +// second: 993 + +// hour transform origin: 40 x 515 // 88 / 533 +// minute transform origin: 37 x 622 // 72 x 740 +// second transform origin: 11 x 751 // 24 x 980 + +const rand = (n) => Math.random() * n; diff --git a/src/views/Clocks.js b/src/views/Clocks.js new file mode 100644 index 0000000..d984f7b --- /dev/null +++ b/src/views/Clocks.js @@ -0,0 +1,15 @@ +/** + * Two clocks + */ + +import React from "react"; +import Clock from "./Clock.js"; + +export default function Clocks() { + return ( + <div className="clocks"> + <Clock /> + <Clock utc /> + </div> + ); +} diff --git a/src/views/Detail.js b/src/views/Detail.js index ff6a6a5..b1c4dcf 100644 --- a/src/views/Detail.js +++ b/src/views/Detail.js @@ -5,6 +5,7 @@ import React from "react"; import Gallery from "./Gallery.js"; +import Clocks from "./Clocks.js"; import Vimeo from "@u-wave/react-vimeo"; export default function Detail({ node, visible, onClose }) { @@ -39,7 +40,9 @@ export default function Detail({ node, visible, onClose }) { <div className="buttons close"> <img src="/assets/img/close.svg" onClick={onClose} /> </div> - {data.type === "video" ? ( + {index === 33 ? ( + <Clocks /> + ) : data.type === "video" ? ( visible && ( <div className="video"> <Vimeo diff --git a/src/views/Legend.js b/src/views/Legend.js index fe7db4d..411ca81 100644 --- a/src/views/Legend.js +++ b/src/views/Legend.js @@ -4,9 +4,20 @@ import React, { useState, useEffect } from "react"; -const categories = "No6092,1620s,painting,blunt,National Gallery of Canada,AGO,courtauld,intervensions,connsoeurship,double agent,forensics,black box,Stankievech".split( - "," -); +var categories = [ + // tag ID = array offset + 1 + "1620s", + "painting", + "blunt", + "National Gallery of Canada", + "Art Gallery of Ontario", + "Courtauld Institute", + "Stankievech", + "connsoeurship", + "double agent", + "forensics", + "black box", +]; export default function Legend({ visible, selected, onSelect }) { return ( |
