ImageGrid/ui/index.html

414 lines
8.1 KiB
HTML
Raw Normal View History

<html>
<head>
<title>ImageGrid.Viewer</title>
<style>
/*
* XXX move the CSS to a separate file...
* XXX split-off styling/coloring from layout...
*/
.viewer {
position: relative;
width: 800px;
height: 600px;
overflow: hidden;
border: solid blue 1px;
}
.ribbon-set {
position: absolute;
}
.ribbon-set:empty:after {
display: block;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
content: "Empty";
text-align: center;
}
.ribbon {
position: relative;
display: block;
height: auto;
min-width: 0px;
overflow: visible;
white-space: nowrap;
font-size: 0;
margin-top: 20px;
margin-bottom: 20px;
}
.ribbon:empty {
display: none;
}
.ribbon:first-child {
margin-top: 0px;
}
.ribbon:last-child {
margin-bottom: 0px;
}
.image {
position: relative;
display: inline-block;
vertical-align: middle;
text-align;left;
width: 300px;
height: 300px;
font-size: 12pt;
overflow: hidden;
box-sizing: border-box;
color: white;
background: no-repeat 50% black;
background-size: contain;
/* XXX do we need this? */
border: solid black 5px;
}
.current.image {
background: no-repeat 50% black;
background-size: contain;
/* XXX remove this... */
border: solid red 5px;
}
/* dot mark... */
.marked.image:after {
display: block;
position: absolute;
content: "";
font-size: 0pt;
border: none;
width: 15px;
height: 15px;
bottom: 5px;
right: 5px;
border-radius: 50%;
background: blue;
}
/* corner mark... (a-la bookmarks in PortableMag) */
/*
.marked.image:after {
display: block;
position: absolute;
content: "";
font-size: 0pt;
border: none;
width: 30px;
height: 30px;
top: -15px;
right: -15px;
background: blue;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
*/
.marked-only.viewer:after {
display: block;
position: absolute;
content: "Showing marked images only";
font-size: 14pt;
border: none;
color: blue;
width: auto;
height: auto;
top: 10px;
right: 10px;
}
.marked-only .image:not(.marked) {
display: none;
}
.marked-only .marked.image:after {
display: none;
}
.up-indicator,
.down-indicator,
.start-indicator,
.end-indicator {
display: block;
position: absolute;
content: "";
top: 0px;
left: 50%;
height: 50px;
width: 100px;
margin-left: -50px;
overflow: hidden;
cursor: hand;
}
.up-indicator:after,
.down-indicator:after {
display: inline-block;
position: absolute;
content: "";
width: 50px;
height: 50px;
bottom: -25px;
left: 25px;
background: yellow;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
.down-indicator {
top: auto;
bottom: 0px;
}
.down-indicator:after {
top: -25px;
bottom: auto;
}
.start-indicator,
.end-indicator {
left: 0px;
width: 10px;
height: 100%;
margin: 0px;
background: yellow;
}
.end-indicator {
left: auto;
right: 0px;
}
/* default state */
.up-indicator,
.down-indicator,
.start-indicator,
.end-indicator {
display: none;
}
</style>
<script src="jquery.js"></script>
<script src="lib/jli.js"></script>
<script src="lib/keyboard.js"></script>
<script src="ImageGrid.js"></script>
<script src="keybindings3.js"></script>
<script>
// setup...
$(function(){
loadData(DATA)
// NOTE: this is global so as to not to add any extra complexity to
// the internal workings...
$('.viewer')
.click(clickHandler)
$(document)
.keydown(makeKeyboardHandler(
KEYBOARD_CONFIG,
function(k){console.log(k)}))
// dynamic loading...
DYNAMIC_LOADING = true
if(DYNAMIC_LOADING){
// XXX move to a setup function in the lib...
$('.viewer')
// XXX this always reloads everything...
// XXX this causes miss-aligns after shifting and/or zooming...
.on('preCenteringRibbon', function(evt, ribbon, image){
// NOTE: we do not need to worry about centering the ribbon
// here, just ball-park-load the correct batch...
// check if we are in the right range...
var gid = getImageGID(image)
var r = getRibbonIndex(ribbon)
var gr = DATA.ribbons[r]
var img_before = getImageBefore(image, ribbon)
var gid_before = getGIDBefore(gid, r)
// load...
if(gid_before == null || gid_before != getImageGID(img_before)){
loadImages(gid, Math.round((LOAD_SCREENS * 1.5) * getScreenWidthInImages()), ribbon)
// XXX compensate for the changing number of images...
// XXX
}
})
/*
// XXX BUGGY...
.on('centeringRibbon', function(evt, ribbon, image){
// check if we are in the right range...
var gid = getImageGID(image)
var r = getRibbonIndex(ribbon)
var img_before = getImageBefore(image, ribbon)
var gid_before = getGIDBefore(gid, r)
if(img_before.length == 0){
img_before = ribbon.find('.image').first()
}
var head = img_before.prevAll('.image')
var tail = img_before.nextAll('.image')
// get the frame size to load...
var screen_size = getScreenWidthInImages()
// NOTE: if this is greater than the number of images currently
// loaded, it might lead to odd effects...
// XXX need to load additional images and keep track of the
// loaded chunk size...
//var frame_size = screen_size * LOAD_SCREENS
var frame_size = 4
//var threshold = screen_size * LOAD_THRESHOLD
var threshold = 2
// do the loading...
// XXX need to expand/contract the ribbon depending on zoom and speed...
// XXX use extendRibbon, to both roll and expand/contract...
if(tail.length < threshold){
var rolled = rollImages(frame_size, ribbon)
}
if(head.length < threshold){
var rolled = rollImages(-frame_size, ribbon)
}
})
*/
.on('shiftedImage', function(evt, image, from, to){
from = getRibbonIndex(from)
var ribbon = to
to = getRibbonIndex(to)
var gid = getImageGID(image)
var index = DATA.ribbons[from].indexOf(gid)
var img = DATA.ribbons[from].splice(index, 1)
// XXX a bit ugly, revise...
index = ribbon.find('.image')
.index(ribbon.find('[gid='+JSON.stringify(gid)+']'))
DATA.ribbons[to].splice(index, 0, gid)
})
.on('createdRibbon', function(evt, index){
index = getRibbonIndex(index)
DATA.ribbons.splice(index, 0, [])
})
.on('removedRibbon', function(evt, index){
DATA.ribbons.splice(index, 1)
})
.on('requestedFirstImage', function(evt, ribbon){
var r = getRibbonIndex(ribbon)
var gr = DATA.ribbons[r]
rollImages(-gr.length, ribbon)
})
.on('requestedLastImage', function(evt, ribbon){
var r = getRibbonIndex(ribbon)
var gr = DATA.ribbons[r]
rollImages(gr.length, ribbon)
})
// XXX do we need to make this less global?
.on('fittingImages', function(evt, n){
updateImages()
})
.on('focusingImage', function(evt, image){
DATA.current = getImageGID($(image))
})
}
// XXX stub...
centerView(focusImage($('.image').first()), 'css')
updateImages()
})
</script>
</head>
<body>
<!-- This is the basic viewer structure...
Unpopulated
NOTE: there can be only .ribbon-set element.
<div class="viewer">
<div class="ribbon-set"></div>
</div>
Populated
<div class="viewer">
<div class="ribbon-set">
<div class="ribbon">
<div class="image"></div>
<div class="image"></div>
</div>
<div class="ribbon">
<div class="image"></div>
<div class="current image"></div>
<div class="image"></div>
<div class="image"></div>
</div>
</div>
</div>
-->
<div class="viewer">
<div class="ribbon-set"></div>
<!-- XXX should these be here??? -->
<div class="up-indicator"></div>
<div class="down-indicator"></div>
<div class="start-indicator"></div>
<div class="end-indicator"></div>
</div>
<!-- vim:set ts=4 sw=4 spell : -->
</body>
</html>