mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-11-04 05:10:07 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			258 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			HTML
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			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 : -->
 |