Browse Source

Link

master
Adrian Heine 4 years ago
parent
commit
66fb068fa5
  1. 54
      src/display.js
  2. 17
      src/index.js
  3. 7
      style.css

54
src/display.js

@ -2,57 +2,64 @@ export class Display {
constructor(baseUrl, dispatch, target) { constructor(baseUrl, dispatch, target) {
this.baseUrl = baseUrl this.baseUrl = baseUrl
this.target = target this.target = target
target.addEventListener('click', e => {
let target = e.target
const findA = target => {
while (target.nodeName !== 'A') { while (target.nodeName !== 'A') {
target = target.parentNode target = target.parentNode
if (!target) return if (!target) return
} }
return target
}
target.addEventListener('click', e => {
let target = findA(e.target)
if (!target) return
window.history.pushState(null, "", target.href) window.history.pushState(null, "", target.href)
dispatch(target.getAttribute('href')) dispatch(target.getAttribute('href'))
e.preventDefault() 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) let target = findA(e.target)
if (!target || !target.draggable) return if (!target || !target.draggable) return
e.dataTransfer.setData('application/prs.x', target.dataset['id']) e.dataTransfer.setData('application/prs.x', target.dataset['id'])
e.dataTransfer.effectAllowed = 'link' e.dataTransfer.effectAllowed = 'link'
}) })
field.addEventListener('dragenter', e => {
target.addEventListener('dragenter', e => {
let target = findA(e.target) let target = findA(e.target)
if (!target) return if (!target) return
e.preventDefault() e.preventDefault()
}) })
field.addEventListener('dragover', e => {
target.addEventListener('dragover', e => {
let target = findA(e.target) let target = findA(e.target)
if (!target) return if (!target) return
e.preventDefault() e.preventDefault()
}) })
field.addEventListener('drop', e => {
target.addEventListener('drop', e => {
let target = findA(e.target) let target = findA(e.target)
if (!target) return if (!target) return
e.preventDefault() e.preventDefault()
dispatch({ action: 'link', from: e.dataTransfer.getData("application/prs.x"), to: target.dataset['id']}) 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 const graph = this.graph
for (const item of state.items) { for (const item of state.items) {
graph.addNode(new Springy.Node(item.id, item)) 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 currentBB = this.layout.getBoundingBox()
let width = this.target.scrollWidth || 100 let width = this.target.scrollWidth || 100
let height = this.target.scrollHeight || 100 let height = this.target.scrollHeight || 100
@ -86,7 +93,12 @@ export class Display {
const a = document.createElement('a') const a = document.createElement('a')
const action = item.data.state == 'face-down' ? 'flip' : 'show' const action = item.data.state == 'face-down' ? 'flip' : 'show'
a.href = `/${item.id}/${action}` 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.className = item.data.state
dom.style.position = 'absolute' dom.style.position = 'absolute'
dom.style.left = target.x + 'px' dom.style.left = target.x + 'px'

17
src/index.js

@ -2,7 +2,7 @@ import {Display} from './display.js'
const target = document.createElement('div') const target = document.createElement('div')
const state = {items: [], show: null }
const state = {items: [], show: null, links: [] }
for (let i = 0; i < 16; ++i) { for (let i = 0; i < 16; ++i) {
state.items.push({id: i, state: 'face-down', img: 'weben.svg'}) state.items.push({id: i, state: 'face-down', img: 'weben.svg'})
} }
@ -17,15 +17,22 @@ class Actions {
reset() { reset() {
state.show = null state.show = null
} }
link(from, to) {
state.links.push({id: state.links.length, from, to})
}
} }
const actions = new Actions const actions = new Actions
let display let display
const dispatch = target => { 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) display.render(state)
} }
window.onpopstate = e => { window.onpopstate = e => {

7
style.css

@ -27,8 +27,9 @@ body {
width: 120px; width: 120px;
height: 120px; height: 120px;
background: #D66C00; background: #D66C00;
border-radius: 60px;
border-radius: 80px;
display: block; display: block;
border: 3px solid #1a1c1c;
} }
.items > li a:hover { .items > li a:hover {
@ -37,8 +38,10 @@ body {
} }
.items > li.face-up a { .items > li.face-up a {
background-size: cover;
background-color: #ed8112; background-color: #ed8112;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
} }
.fullview { .fullview {

Loading…
Cancel
Save