ImageGrid/ui (gen4)/experiments/preact-ribbons.html
Alex A. Naanou 831e82a28a experimenting...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
2017-07-29 21:39:47 +03:00

258 lines
4.4 KiB
HTML
Executable File

<!DOCTYPE html>
<html>
<style>
.ribbon {
position: relative;
display: block;
float: left;
clear: left;
white-space: nowrap;
overflow: visible;
margin: 5px 0px;
width: auto;
}
.base.ribbon {
border-bottom: solid 5px red;
}
.mark,
.image {
position: relative;
display: inline-block;
width: 100px;
height: 100px;
outline: solid 1px blue;
background: silver;
vertical-align: middle;
}
.image:after {
content: attr(gid);
}
.current.image {
background: gray;
}
.mark {
margin-left: -100px;
background: none;
pointer-events: none;
}
.mark:after {
position: absolute;
content: "";
top: 0;
right: 0;
width: 0;
height: 0;
border: solid 10px red;
border-bottom-color: transparent;
border-left-color: transparent;
pointer-events: auto;
}
</style>
<script src="../ext-lib/jquery.js"></script>
<script src="../ext-lib/jquery-ui.js"></script>
<!-- preact.js -->
<script src="../node_modules/preact/dist/preact.min.js"></script>
<script src="../lib/jli.js"></script>
<script>
var h = preact.h
var stub_data = {
ribbon_order: ['ra', 'rb', 'rc'],
ribbons: {
ra: [].slice.call('abcde'),
rb: [].slice.call('fghijklm'),
rc: [].slice.call('opqrstuvwxyz'),
},
order: [].slice.call('abcdefghijklmopqrstuvwxyz'),
tags: {
selected: [].slice.call('ahdtu'),
b: [].slice.call('adxz'),
},
current: 'a',
base: 'rb',
}
// XXX needs vertical align...
class IGRibbonSet extends preact.Component {
render(props, state){
var data = props.data
var ribbons = data.ribbon_order.map(function(gid){
return h(IGRibbon, {
gid: gid,
current: data.current,
base: data.base,
data: data
}) })
var s = props.scale || 1
return h('div',
{
className: 'ribbon-set',
style: {
transform: 'scale('+ s +', '+ s +')',
},
}, [
h('div', {className: 'current-marker'}),
h('div', {className: 'ribbon-locator'}, ribbons),
])
}
}
// render:
// - ribbon
// - images
// - image marks
//
// XXX needs horizontal align...
class IGRibbon extends preact.Component {
render(props, state){
var data = props.data
var ribbon = props.gid
var images = data.ribbons[ribbon]
.map(function(gid){
var marks = data.tags.selected.indexOf(gid) >= 0 ?
h(IGImageMark, {
gid: gid,
type: 'selected',
data: data,
})
: []
return [
h(IGImage, {
gid: gid,
data: data,
})].concat(marks)
})
.reduce(function(a, b){ return a.concat(b) })
.filter(function(a){ return !!a })
var base = data.base == ribbon ? ['base'] : []
return h('div',
{
classList: ['ribbon'].concat(base).join(' '),
gid: props.gid,
style: {
// XXX offset...
},
}, images)
}
}
// render:
// - image
class IGImage extends preact.Component {
render(props, state){
var data = props.data
var gid = props.gid
return h('div',
{
classList: ['image']
.concat(data.current == gid ? ['current'] : [])
.join(' '),
gid: gid || '',
style: {
// XXX background-image...
},
// XXX STUB
onClick: function(evt){
// toggle tag...
if(data.current == gid){
var selected = data.tags.selected = data.tags.selected || []
selected.indexOf(gid) < 0 ?
selected.push(gid)
: selected.splice(selected.indexOf(gid), 1)
}
// set current...
data.current = gid
render()
},
})
}
}
// render:
// - image mark
class IGImageMark extends preact.Component {
render(props, state){
var gid = props.gid
var type = props.type
var data = props.data
return h('div',
{
classList: ['mark'].concat([type]).join(' '),
gid: gid,
// XXX STUB...
// ...and there is no way to add the mark back...
onClick: function(evt){
data.tags[type].splice(data.tags[type].indexOf(gid), 1)
render()
},
})
}
}
// XXX HACK...
var ribbon_set_dom
function render(data, images, scale){
//preact.render(ribbon_set, document.body)
ribbon_set_dom = preact.render(
h(IGRibbonSet, {
data: data || stub_data,
images: images || {},
scale: scale || 1,
}),
document.getElementById('viewer'),
ribbon_set_dom)
}
$(function(){ render() })
</script>
<body>
<div id="viewer"/>
</body>
</html>
<!-- vim:set ts=4 sw=4 : -->