-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
133 lines (131 loc) · 5.79 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/12.0.0/marked.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"></script>
<link
href="https://fonts.googleapis.com/css2?family=Crimson+Text:ital,wght@0,400;0,600;1,400;1,600;1,900&display=swap"
rel="stylesheet">
<link rel="stylesheet" href="style.css">
<title>GENERATIVE-DIAGRAM</title>
</head>
<body>
<div id="wrapper" >
<div id="timeline">
</div>
<div id="diagram">
</div>
<canvas id="paths"></canvas>
</div>
<script>
const diagram = [];
(async function () {
let content = await fetch('content.md')
content = await content.text()
content.split('-----').map((session, sessionIndex) => {
//split the session into text and relations
let [text, relations] = session.split('---')
//append the text
let contentDiv = document.createElement('div')
contentDiv.classList.add("text")
contentDiv.innerHTML = marked.parse(text)
document.getElementById('timeline').appendChild(contentDiv)
//process relations
relations = bilink(d3.hierarchy(JSON.parse(relations)))
//push each diagram to the diagram array
diagram.push(relations)
})
//draw the first diagram
draw(diagram[0])
})()
function draw(relations){
let diagram = document.getElementById('diagram')
diagram.innerHTML = ''
let paths = document.getElementById('paths')
let body = document.getElementsByTagName('body')[0]
paths.width = window.innerWidth * 2
paths.height = window.innerHeight * 2
let diagramWidth = document.getElementById('diagram').offsetWidth
let diagramHeight = document.getElementById('diagram').offsetHeight
let canvas = document.getElementById('paths')
let context = canvas.getContext('2d')
context.strokeStyle = 'black'
context.lineWidth = 2
context.clearRect(0, 0, canvas.width, canvas.height)
let rows = (window.innerHeight - 100) / relations.children.length
let lines = [];
relations.children.map((level, levelID) => {
let row = document.createElement('div')
row.classList.add('row')
row.style.height = `${rows}px`
row.style.width = `${diagramWidth}px`
row.style.transform = `translate(0, ${rows * levelID}px)`
document.getElementById('diagram').appendChild(row)
level.children.map((entity, entityID) => {
console.log(entity)
let div = document.createElement('div')
entity.dom = div
div.classList.add(entity.data.type, "diagramObject")
div.innerHTML = marked.parse(entity.data.content)
row.appendChild(div)
entity.outgoing.map(relation => lines.push([relation[0],relation[1]]))
})
})
let offset = 100
function animate() {
offset -= 2
context.clearRect(0, 0, canvas.width, canvas.height)
lines.map(l => {
line(l[0], l[1], context, offset)
})
if(offset > 0){
console.log('animating')
requestAnimationFrame(animate)
}
}
animate()
}
function line(entity, parent,context,offset) {
let entityBounding = entity.dom.getBoundingClientRect()
let parentBounding = parent.dom.getBoundingClientRect()
context.beginPath()
context.setLineDash([3100,3100]);
context.lineDashOffset = -offset*10
context.moveTo(entityBounding.x * 2 + entityBounding.width, entityBounding.y * 2 - 10 )
context.bezierCurveTo(
entityBounding.x * 2 + entityBounding.width, parentBounding.y * 2 + parentBounding.height * 2 + (entityBounding.y * 2 - parentBounding.y * 2) / 2 - 10,
parentBounding.x * 2 + parentBounding.width, parentBounding.y * 2 + parentBounding.height * 2 + (entityBounding.y * 2 - parentBounding.y * 2) / 2 - 10,
parentBounding.x * 2 + parentBounding.width, parentBounding.y * 2 + parentBounding.height * 2 + 10
)
context.stroke()
}
function bilink(root) {
const map = new Map(root.leaves().map(d => [id(d), d]));
for (const d of root.leaves()) {
d.incoming = [];
d.outgoing = d.data.imports.map(i => [d, map.get(i)]);
}
for (const d of root.leaves()) {
for (const o of d.outgoing) {
o[1].incoming.push(o);
}
}
return root;
}
function id(node) {
return `${node.parent != null ? this.id(node.parent) + "." : ""}${node.data.name}`;
}
let lastIndex = 0
document.addEventListener('scroll', (event) => {
let scroll = window.scrollY + window.innerHeight / 3
let stage = Math.floor( scroll / (document.getElementById('timeline').offsetHeight / diagram.length));
if(lastIndex != stage){
lastIndex = stage
draw(diagram[stage])
}
})
</script>
</body>
</html>