export class Display { constructor(baseUrl, dispatch, target) { this.baseUrl = baseUrl this.target = target target.addEventListener('click', e => { let target = e.target while (target.nodeName !== 'A') { target = target.parentNode if (!target) return } window.history.pushState(null, "", target.href) dispatch(target.getAttribute('href')) e.preventDefault() }) this.graph = new Springy.Graph() this.layout = new Springy.Layout.ForceDirected( this.graph, 400.0, // Spring stiffness 400.0, // Node repulsion 0.5 // Damping ) } render(state) { const target = document.createElement('div') target.className = 'wrapper' const field = document.createElement('ul') field.className = 'items' const graph = this.graph for (const item of state.items) { graph.addNode(new Springy.Node(item.id, item)) } let currentBB = this.layout.getBoundingBox() let width = this.target.scrollWidth || 100 let height = this.target.scrollHeight || 100 var toScreen = function(p) { var size = currentBB.topright.subtract(currentBB.bottomleft); var sx = p.subtract(currentBB.bottomleft).divide(size.x).x * (width - 100); var sy = p.subtract(currentBB.bottomleft).divide(size.y).y * (height - 100); return new Springy.Vector(sx, sy); }; var fromScreen = function(s) { var size = currentBB.topright.subtract(currentBB.bottomleft); var px = (s.x / canvas.width) * size.x + currentBB.bottomleft.x; var py = (s.y / canvas.height) * size.y + currentBB.bottomleft.y; return new Springy.Vector(px, py); }; var renderer = new Springy.Renderer( this.layout, () => { currentBB = this.layout.getBoundingBox() width = this.target.scrollWidth height = this.target.scrollHeight field.innerHTML = '' }, function drawEdge(edge, p1, p2) { // draw an edge }, function drawNode(item, p) { const target = toScreen(p) const dom = document.createElement('li') const a = document.createElement('a') const action = item.data.state == 'face-down' ? 'flip' : 'show' a.href = `/${item.id}/${action}` a.style.backgroundImage = `url(img/${item.data.img})` dom.className = item.data.state dom.style.position = 'absolute' dom.style.left = target.x + 'px' dom.style.top = target.y + 'px' dom.appendChild(a) field.appendChild(dom) }, undefined, undefined, () => { const dd = new diffDOM.DiffDOM() const diff = dd.diff(this.target.children[0], field) dd.apply(this.target.children[0], diff) } ); target.appendChild(field) if (state.show !== null) { const wrapper = document.createElement('a') wrapper.href = '/' const fullview = document.createElement('div') wrapper.className = 'fullview' wrapper.appendChild(fullview) target.appendChild(wrapper) } const dd = new diffDOM.DiffDOM() const diff = dd.diff(this.target, target) dd.apply(this.target, diff) renderer.start(); } }