From 66fb068fa5be7d625963da1951f1e782701190a4 Mon Sep 17 00:00:00 2001 From: Adrian Heine Date: Thu, 17 Sep 2020 19:18:29 +0200 Subject: [PATCH] Link --- src/display.js | 54 ++++++++++++++++++++++++++++++-------------------- src/index.js | 17 +++++++++++----- style.css | 7 +++++-- 3 files changed, 50 insertions(+), 28 deletions(-) diff --git a/src/display.js b/src/display.js index 1cf5c01..d935f1b 100644 --- a/src/display.js +++ b/src/display.js @@ -2,57 +2,64 @@ export class Display { constructor(baseUrl, dispatch, target) { this.baseUrl = baseUrl this.target = target - target.addEventListener('click', e => { - let target = e.target + const findA = target => { while (target.nodeName !== 'A') { target = target.parentNode if (!target) return } + return target + } + target.addEventListener('click', e => { + let target = findA(e.target) + 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' - - field.addEventListener('dragstart', e => { + target.addEventListener('dragstart', e => { let target = findA(e.target) if (!target || !target.draggable) return e.dataTransfer.setData('application/prs.x', target.dataset['id']) e.dataTransfer.effectAllowed = 'link' }) - field.addEventListener('dragenter', e => { + target.addEventListener('dragenter', e => { let target = findA(e.target) if (!target) return e.preventDefault() }) - field.addEventListener('dragover', e => { + target.addEventListener('dragover', e => { let target = findA(e.target) if (!target) return e.preventDefault() }) - field.addEventListener('drop', e => { + target.addEventListener('drop', e => { let target = findA(e.target) if (!target) return e.preventDefault() dispatch({ action: 'link', from: e.dataTransfer.getData("application/prs.x"), to: target.dataset['id']}) }) + 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)) } + for (const item of state.links) { + graph.addEdge(new Springy.Edge(item.id, graph.nodeSet[item.from], graph.nodeSet[item.to], {})) + } let currentBB = this.layout.getBoundingBox() let width = this.target.scrollWidth || 100 let height = this.target.scrollHeight || 100 @@ -86,7 +93,12 @@ export class Display { 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})` + a.draggable = false + if (item.data.state !== 'face-down') { + a.style.backgroundImage = `url(/img/${item.data.img})` + a.dataset['id'] = item.id + a.draggable = true + } dom.className = item.data.state dom.style.position = 'absolute' dom.style.left = target.x + 'px' diff --git a/src/index.js b/src/index.js index 5fcfe77..f00f536 100644 --- a/src/index.js +++ b/src/index.js @@ -2,7 +2,7 @@ import {Display} from './display.js' const target = document.createElement('div') -const state = {items: [], show: null } +const state = {items: [], show: null, links: [] } for (let i = 0; i < 16; ++i) { state.items.push({id: i, state: 'face-down', img: 'weben.svg'}) } @@ -17,15 +17,22 @@ class Actions { reset() { state.show = null } + link(from, to) { + state.links.push({id: state.links.length, from, to}) + } } const actions = new Actions let display const dispatch = target => { - const match = target.match(/\/([^/]+)\/([^/]+)/) - if (match && Object.hasOwnProperty.call(Actions.prototype, match[2])) { - actions[match[2]](match[1]) - } else actions.reset() + if (target.action) { + actions[target.action](target.from, target.to) + } else { + const match = target.match(/\/([^/]+)\/([^/]+)/) + if (match && Object.hasOwnProperty.call(Actions.prototype, match[2])) { + actions[match[2]](match[1]) + } else actions.reset() + } display.render(state) } window.onpopstate = e => { diff --git a/style.css b/style.css index 8166b32..e52e145 100644 --- a/style.css +++ b/style.css @@ -27,8 +27,9 @@ body { width: 120px; height: 120px; background: #D66C00; - border-radius: 60px; + border-radius: 80px; display: block; + border: 3px solid #1a1c1c; } .items > li a:hover { @@ -37,8 +38,10 @@ body { } .items > li.face-up a { - background-size: cover; background-color: #ed8112; + background-size: contain; + background-repeat: no-repeat; + background-position: center; } .fullview {