added superzoom

master
vitrinekast 1 year ago
parent 287c2adf5a
commit ebc1ab7fc5

@ -25,18 +25,18 @@
</head> </head>
<body> <body>
<div id="container"></div>
for
<header> <header>
<h1>Granularchive</h1> <h1>Granularchive</h1>
</header> </header>
<aside class="text fn-text">
<h2 class='fn-title'></h2>
<iframe src="" frameborder="0"></iframe>
</aside>
<main> <main>
<div id="container"></div>
<section class="loading">building graph...</section> <section class="loading fn-loading">building graph...</section>
<?php print("<pre>" . print_r($dataset, true) . "</pre>"); ?>
<script type="text/javascript"> <script type="text/javascript">
var dataset = <?php echo $dataset; ?>; var dataset = <?php echo $dataset; ?>;
@ -44,9 +44,9 @@
</script> </script>
</main> </main>
<footer>
<audio controls src="/small-filesize/output_lower.mp3" autoplay></audio>
<footer>
<audio controls src="/small-filesize/output_lower.mp3" class="fn-audio" autoplay></audio>
</footer> </footer>
<script src="https://cdn.jsdelivr.net/npm/d3@7"></script> <script src="https://cdn.jsdelivr.net/npm/d3@7"></script>
<script type="text/javascript" src="script.js"> </script> <script type="text/javascript" src="script.js"> </script>

@ -1,10 +1,15 @@
// Create some global variables // Create some global variables
var width, height, audioEl; var width, height, audioEl, textEl;
let currentTransform;
var links = [], var links = [],
nodes = [], nodes = [],
groups = []; groups = [];
let zoomLvl = 1; let zoomLvl = 1;
let lastK = 0; let lastK = 0;
let svg;
var zoom;
let simulation;
const ROOT = "https://hub.xpub.nl/chopchop/archive_non-tree/";
function parseExifData(files) { function parseExifData(files) {
// loop trough all files in JSON and add each to the list of nodes // loop trough all files in JSON and add each to the list of nodes
@ -72,8 +77,9 @@ function parseExifData(files) {
function createGraph() { function createGraph() {
// Create a scale to set the radius based on a file size (0 to 3 GB) // Create a scale to set the radius based on a file size (0 to 3 GB)
var rScale = d3.scaleLinear().domain([0, 30000000]).range([2, 15]); var rScale = d3.scaleLinear().domain([0, 30000000]).range([2, 15]);
currentTransform = [width / 2, height / 2, height];
const simulation = d3 simulation = d3
.forceSimulation(nodes) .forceSimulation(nodes)
.force("center", d3.forceCenter(width / 2, height / 2)) .force("center", d3.forceCenter(width / 2, height / 2))
.force( .force(
@ -95,7 +101,7 @@ function createGraph() {
// .alphaTarget(0.3); // stay hot // .alphaTarget(0.3); // stay hot
const svg = d3 svg = d3
.create("svg") // .create("svg") //
.attr("width", width) .attr("width", width)
.attr("height", height); .attr("height", height);
@ -132,11 +138,20 @@ function createGraph() {
.attr("r", 3) .attr("r", 3)
.attr("stroke", "black") .attr("stroke", "black")
.attr("fill", (d) => { .attr("fill", (d) => {
return d.FileType === "directory" ? "orange" : "white"; if (d.FileType === "directory") {
return "orange";
} else if (d.FileType === "TXT") {
return "blue";
} else if (d.FileType === "PNG") {
return "pink";
} else {
return "white";
}
}) })
// .attr("fill","rgba(255,255,255,.5)") // .attr("fill","rgba(255,255,255,.5)")
.attr("label", (d) => d.id) .attr("label", (d) => d.id)
.attr("path", (d) => d.id) .attr("path", (d) => d.id)
.attr("file-type", (d) => d.FileType)
.attr("group", (d) => d.group); .attr("group", (d) => d.group);
// Add a drag behavior. // Add a drag behavior.
@ -161,17 +176,15 @@ function createGraph() {
}); });
// add zoom behavior // add zoom behavior
svg.call( var zoom = d3
d3
.zoom() .zoom()
.extent([ .extent([
[0, 0], [0, 0],
[width, height], [width, height],
]) ])
.scaleExtent([1, 100]) .scaleExtent([1, 100])
.on("zoom", zoomed) .on("zoom", zoomed);
); svg.call(zoom);
// add some mouse behaviors // add some mouse behaviors
svg svg
.selectAll("circle") .selectAll("circle")
@ -185,10 +198,20 @@ function createGraph() {
d3.select(this).attr("fill", "black"); d3.select(this).attr("fill", "black");
var path = this.getAttribute("path"); var path = this.getAttribute("path");
svg
.transition() //
.duration(300)
.ease(d3.easeCubic)
.call(zoom.translateTo, this.getAttribute("cx"), this.getAttribute("cy"));
// do things based on the file type // do things based on the file type
if (path.match(/\.(?:wav|mp3|flac)$/i)) { if (path.match(/\.(?:wav|mp3|flac)$/i)) {
playAudio(path); playAudio(path);
} }
if (path.match(/\.(?:txt|png)$/i)) {
playText(path);
}
}) })
.on("mouseleave", function () { .on("mouseleave", function () {
if (d3.select(this).attr("fill") !== "black") { if (d3.select(this).attr("fill") !== "black") {
@ -234,20 +257,56 @@ function createGraph() {
} }
function playAudio(src) { function playAudio(src) {
console.log("play audio: ", src);
audioEl.src = src; audioEl.src = src;
audioEl.currentTime = 0; audioEl.currentTime = 0;
audioEl.play(); audioEl.play();
} }
function playText(src) {
textEl.setAttribute("active", "true");
textEl.querySelector(".fn-title").textContent = src.split("/")[src.split("/").length - 1];
textEl.querySelector("iframe").src = ROOT + "/" + src;
window.setTimeout(function () {
svg.on("click", onBodyClick);
}, 300);
}
function onBodyClick() {
textEl.setAttribute("active", "false");
svg.on("click", null);
}
function updateWindow() {
width = window.innerWidth - 10;
height = window.innerHeight - 10;
simulation.force("center", d3.forceCenter(width / 2, height / 2));
svg.attr("width", width).attr("height", height);
}
window.onload = function () { window.onload = function () {
// TODO: add resize function // TODO: add resize function
width = window.innerWidth; width = window.innerWidth - 10;
height = window.innerHeight; height = window.innerHeight - 10;
audioEl = document.querySelector(".fn-audio");
textEl = document.querySelector(".fn-text");
parseExifData(dataset); parseExifData(dataset);
createGraph(); createGraph();
var filetypes = [];
nodes.forEach((node) => {
if (filetypes.indexOf(node.FileType) == -1) {
filetypes.push(node.FileType);
}
});
console.log(filetypes);
// clear loading screen // clear loading screen
document.querySelector(".loading").style.display = "none"; document.querySelector(".loading").style.display = "none";
// Add resize features
d3.select(window).on("resize.updatesvg", updateWindow);
}; };

@ -11,15 +11,36 @@ body {
} }
footer, footer,
header { header,
aside {
position: fixed;
bottom: .5rem;
left: .5rem;
width: calc(100% - 1rem);
background-color: white;
border: 2px solid black; border: 2px solid black;
box-shadow: -5px -5px 0px rgba(0, 0, 0, .1); box-shadow: -5px -5px 0px rgba(0, 0, 0, .1);
padding: .5rem 1rem; padding: .5rem 1rem;
text-align: center; }
position: fixed;
bottom: 0; aside {
width: 100%; width: 30%;
background-color: white; min-width: 500px;
right: 0;
top: 4rem;
left: auto;
right: .5rem;
bottom: 6rem;
display: none;
flex-direction: column;
}
aside[active="true"] {
display: flex;
}
aside iframe {
flex-grow: 1;
} }
h1 { h1 {
@ -28,19 +49,14 @@ h1 {
header { header {
bottom: auto; bottom: auto;
top: 0; top: .5rem;
font-size: 1rem; text-align: center;
} }
footer audio { footer audio {
width: 100%; width: 100%;
} }
main {
margin-top: 4rem;
margin-bottom: 4rem;
}
pre { pre {
max-width: 50svw; max-width: 50svw;
} }

Loading…
Cancel
Save