mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-30 19:00:09 +00:00
split gallery.html into separate blocks...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
11f8be4a2a
commit
c9a9259d59
47
ui/TODO.otl
Executable file
47
ui/TODO.otl
Executable file
@ -0,0 +1,47 @@
|
|||||||
|
basic structure
|
||||||
|
ribbons DONE
|
||||||
|
images DONE
|
||||||
|
indicators
|
||||||
|
basic control elements
|
||||||
|
touch zones / buttons
|
||||||
|
next DONE
|
||||||
|
prev DONE
|
||||||
|
shift up DONE
|
||||||
|
shift down DONE
|
||||||
|
promote DONE
|
||||||
|
demote DONE
|
||||||
|
zoom in ~ need real zooming...
|
||||||
|
zoom out ~ need real zooming...
|
||||||
|
toggle single image DONE
|
||||||
|
image sorting
|
||||||
|
will affect:
|
||||||
|
promote
|
||||||
|
demote
|
||||||
|
shift up
|
||||||
|
shift down
|
||||||
|
ribbon merging
|
||||||
|
add promote/demote events (to attach structure editors)...
|
||||||
|
add real images...
|
||||||
|
make all the code relative to the current selection (multiple instances on a page support)
|
||||||
|
make this into a jquery plugin...
|
||||||
|
add dynamic loading and unloading for very large sets...
|
||||||
|
gesture support...
|
||||||
|
add basic actions:
|
||||||
|
rotate left
|
||||||
|
rotate right
|
||||||
|
...
|
||||||
|
add info:
|
||||||
|
number of images in ribbon
|
||||||
|
position in ribbon
|
||||||
|
|
||||||
|
|
||||||
|
first stage refactoring:
|
||||||
|
merge almost identical functions...
|
||||||
|
|
||||||
|
multiple groups to promote/demote
|
||||||
|
ways to go:
|
||||||
|
promote/demote and tag
|
||||||
|
|
||||||
|
ISSUES:
|
||||||
|
jumping on focus up/down...
|
||||||
|
demoting a first element (a ribbon is created) positions the field incorrectly (see demoteImage() for details)...
|
||||||
356
ui/gallery-prototype.js
Executable file
356
ui/gallery-prototype.js
Executable file
@ -0,0 +1,356 @@
|
|||||||
|
$(document).ready(function() {
|
||||||
|
// current state...
|
||||||
|
if($('.current-ribbon').length == 0){
|
||||||
|
$('.ribbon').first().addClass('current-ribbon')
|
||||||
|
}
|
||||||
|
if($('.current-image').length == 0){
|
||||||
|
$('.current-ribbon').children('.image').first().addClass('current-image')
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup event handlers...
|
||||||
|
$(document)
|
||||||
|
.keydown(handleKeys)
|
||||||
|
$('.viewer')
|
||||||
|
// XXX does not work on android... (might need to add tap event handling)
|
||||||
|
.gestures({eventHandler: handleGestures})
|
||||||
|
// XXX this is flaky and breaks some of my code...
|
||||||
|
/*.wipetouch({
|
||||||
|
wipeLeft: nextImage,
|
||||||
|
wipeRight: prevImage,
|
||||||
|
wipeUp: demoteImage,
|
||||||
|
wipeDown: promoteImage,
|
||||||
|
|
||||||
|
tapToClick: true
|
||||||
|
})*/
|
||||||
|
/* XXX jquery.mobile handlers... (with this I'm getting way too much bling)
|
||||||
|
.bind('swipeleft', function(e){
|
||||||
|
nextImage()
|
||||||
|
e.preventDefault()
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
.bind('swiperight', function(e){
|
||||||
|
prevImage()
|
||||||
|
e.preventDefault()
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
*/
|
||||||
|
$(".image").click(handleClick)
|
||||||
|
|
||||||
|
// control elements...
|
||||||
|
$('.next-image').click(nextImage)
|
||||||
|
$('.prev-image').click(prevImage)
|
||||||
|
$('.demote').click(demoteImage)
|
||||||
|
$('.promote').click(promoteImage)
|
||||||
|
$('.toggle-wide').click(toggleWideView)
|
||||||
|
$('.toggle-single').click(toggleRibbonView)
|
||||||
|
|
||||||
|
// load images...
|
||||||
|
// XXX not allowed...
|
||||||
|
//$.getJSON('images.js', loadImages})
|
||||||
|
// XXX STUB
|
||||||
|
loadImages(image_list)
|
||||||
|
|
||||||
|
// set the default position and init...
|
||||||
|
$('.current-image').click()
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
function loadImages(json){
|
||||||
|
var images = json.images
|
||||||
|
var ribbon = $('.ribbon').last()
|
||||||
|
|
||||||
|
$('.image').remove()
|
||||||
|
|
||||||
|
for(var i = 0; i < images.length; i++){
|
||||||
|
$('<div class="image"></div>')
|
||||||
|
.css({ 'background-image': 'url('+images[i]+')' })
|
||||||
|
.click(handleClick)
|
||||||
|
.appendTo(ribbon)
|
||||||
|
}
|
||||||
|
ribbon.children().first().click()
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX jquery.gestures handler...
|
||||||
|
function handleGestures(e){
|
||||||
|
switch (e){
|
||||||
|
case 'N':
|
||||||
|
demoteImage()
|
||||||
|
break
|
||||||
|
case 'S':
|
||||||
|
promoteImage()
|
||||||
|
break
|
||||||
|
case 'E':
|
||||||
|
prevImage()
|
||||||
|
break
|
||||||
|
case 'W':
|
||||||
|
nextImage()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function handleClick(e) {
|
||||||
|
|
||||||
|
var cur = $(this)
|
||||||
|
|
||||||
|
// switch classes...
|
||||||
|
cur.parents().siblings().children(".image").removeClass("current-image")
|
||||||
|
cur.siblings(".image").removeClass("current-image")
|
||||||
|
|
||||||
|
cur.siblings().children(".image").removeClass("current-image")
|
||||||
|
cur.parents().siblings(".ribbon").removeClass("current-ribbon")
|
||||||
|
|
||||||
|
cur.addClass("current-image")
|
||||||
|
cur.parents(".ribbon").addClass("current-ribbon")
|
||||||
|
|
||||||
|
|
||||||
|
var container = cur.parents('.container')
|
||||||
|
var field = cur.parents(".field")
|
||||||
|
|
||||||
|
var image_offset = cur.offset()
|
||||||
|
var field_offset = field.offset()
|
||||||
|
|
||||||
|
// center the current image...
|
||||||
|
field.css({
|
||||||
|
left: field_offset.left - image_offset.left + (container.innerWidth() - cur.innerWidth())/2,
|
||||||
|
top: field_offset.top - image_offset.top + (container.innerHeight() - cur.innerHeight())/2
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// XXX do I need this???
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
var keys = {
|
||||||
|
toggleHelpKeys: [72],
|
||||||
|
toggleRibbonView: [32],
|
||||||
|
closeKeys: [27, 88, 67],
|
||||||
|
|
||||||
|
firstKeys: [36],
|
||||||
|
lastKeys: [35],
|
||||||
|
previousKeys: [37, 80],
|
||||||
|
nextKeys: [39, 78],
|
||||||
|
promoteKeys: [40],
|
||||||
|
// XXX add del (46) to demote...
|
||||||
|
demoteKeys: [38],
|
||||||
|
|
||||||
|
ignoreKeys: [16, 17, 18],
|
||||||
|
|
||||||
|
helpShowOnUnknownKey: true
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleKeys(event){
|
||||||
|
var code = event.keyCode, fn = $.inArray;
|
||||||
|
var _ = (fn(code, keys.closeKeys) >= 0) ? function(){}()
|
||||||
|
: (fn(code, keys.firstKeys) >= 0) ? firstImage()
|
||||||
|
: (fn(code, keys.nextKeys) >= 0) ? nextImage()
|
||||||
|
: (fn(code, keys.previousKeys) >= 0) ? prevImage()
|
||||||
|
: (fn(code, keys.lastKeys) >= 0) ? lastImage()
|
||||||
|
: (fn(code, keys.promoteKeys) >= 0) ? function(){
|
||||||
|
if(event.shiftKey){
|
||||||
|
if(event.ctrlKey){
|
||||||
|
createRibbonBelow()
|
||||||
|
}
|
||||||
|
promoteImage()
|
||||||
|
} else {
|
||||||
|
focusBelowRibbon()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
: (fn(code, keys.demoteKeys) >= 0) ? function(){
|
||||||
|
if(event.shiftKey){
|
||||||
|
if(event.ctrlKey){
|
||||||
|
createRibbonAbove()
|
||||||
|
}
|
||||||
|
demoteImage()
|
||||||
|
} else {
|
||||||
|
focusAboveRibbon()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
: (fn(code, keys.toggleRibbonView) >= 0) ? toggleRibbonView()
|
||||||
|
: (fn(code, keys.ignoreKeys) >= 0) ? false
|
||||||
|
// XXX
|
||||||
|
: (keys.helpShowOnUnknownKey) ? function(){alert(code)}()
|
||||||
|
: false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// modes...
|
||||||
|
function showRibbon(){
|
||||||
|
$('.single-image-mode').removeClass('single-image-mode')
|
||||||
|
}
|
||||||
|
function showSingle(){
|
||||||
|
$('.viewer').not('.single-image-mode').addClass('single-image-mode')
|
||||||
|
}
|
||||||
|
function toggleRibbonView(){
|
||||||
|
if($('.single-image-mode').length > 0){
|
||||||
|
showRibbon()
|
||||||
|
} else {
|
||||||
|
showSingle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX need to reposition the whole thing correctly...
|
||||||
|
function toggleWideView(){
|
||||||
|
if($('.wide-view-mode').length > 0){
|
||||||
|
$('.wide-view-mode')
|
||||||
|
.removeClass('wide-view-mode')
|
||||||
|
.one("webkitTransitionEnd oTransitionEnd msTransitionEnd transitionend", function(){
|
||||||
|
$('.current-image').click()
|
||||||
|
return true
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
showRibbon()
|
||||||
|
//$('.container')
|
||||||
|
$('.viewer')
|
||||||
|
.not('.wide-view-mode')
|
||||||
|
.addClass('wide-view-mode')
|
||||||
|
.one("webkitTransitionEnd oTransitionEnd msTransitionEnd transitionend", function(){
|
||||||
|
$('.current-image').click()
|
||||||
|
return true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// basic navigation...
|
||||||
|
function firstImage(){
|
||||||
|
$('.current-ribbon').children('.image').first().click()
|
||||||
|
}
|
||||||
|
|
||||||
|
function prevImage(){
|
||||||
|
$('.current-image').prev('.image').click()
|
||||||
|
}
|
||||||
|
|
||||||
|
function nextImage(){
|
||||||
|
$('.current-image').next('.image').click()
|
||||||
|
}
|
||||||
|
|
||||||
|
function lastImage(){
|
||||||
|
$('.current-ribbon').children('.image').last().click()
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX select appropriate image...
|
||||||
|
function focusAboveRibbon(){
|
||||||
|
$('.current-ribbon').prev('.ribbon').children('.image').first().click()
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX select appropriate image...
|
||||||
|
function focusBelowRibbon(){
|
||||||
|
$('.current-ribbon').next('.ribbon').children('.image').first().click()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// create ribbon above/below helpers...
|
||||||
|
// XXX NOTE: this will shift the content downwards...
|
||||||
|
function createRibbonAbove(){
|
||||||
|
var res = $('<div class="new-ribbon"></div>')
|
||||||
|
.insertBefore('.current-ribbon')
|
||||||
|
// HACK: without this, the class change below will not animate...
|
||||||
|
.show()
|
||||||
|
.addClass('ribbon')
|
||||||
|
.removeClass('new-ribbon')
|
||||||
|
// XXX find a better way to do this...
|
||||||
|
$('.field').css({
|
||||||
|
top: $('.field').position().top - $('.current-ribbon').outerHeight()
|
||||||
|
})
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
function createRibbonBelow(){
|
||||||
|
return $('<div class="new-ribbon"></div>')
|
||||||
|
.insertAfter('.current-ribbon')
|
||||||
|
// HACK: without this, the class change below will not animate...
|
||||||
|
.show()
|
||||||
|
.addClass('ribbon')
|
||||||
|
.removeClass('new-ribbon')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modifiers...
|
||||||
|
|
||||||
|
// XXX sort elements correctly...
|
||||||
|
function mergeRibbonsUp(){
|
||||||
|
$('.current-ribbon')
|
||||||
|
.prev('.ribbon')
|
||||||
|
.children()
|
||||||
|
.detach()
|
||||||
|
.insertAfter('.current-image')
|
||||||
|
$('.current-ribbon')
|
||||||
|
.prev('.ribbon')
|
||||||
|
.slideUp(function(){
|
||||||
|
$(this).remove()
|
||||||
|
$('.current-image').click()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX sort elements correctly...
|
||||||
|
function mergeRibbonsDown(){
|
||||||
|
$('.current-ribbon')
|
||||||
|
.next('.ribbon')
|
||||||
|
.children()
|
||||||
|
.detach()
|
||||||
|
.insertAfter('.current-image')
|
||||||
|
$('.current-ribbon')
|
||||||
|
.next('.ribbon')
|
||||||
|
.slideUp(function(){
|
||||||
|
$(this).remove()
|
||||||
|
$('.current-image').click()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX sort elements correctly...
|
||||||
|
// XXX do animations...
|
||||||
|
function promoteImage(){
|
||||||
|
if($('.current-ribbon').next('.ribbon').length == 0){
|
||||||
|
createRibbonBelow()
|
||||||
|
}
|
||||||
|
// XXX sort elements correctly...
|
||||||
|
if($('.current-ribbon').children('.image').length == 1){
|
||||||
|
// XXX this adds image to the head while the below portion adds it to the tail...
|
||||||
|
mergeRibbonsDown()
|
||||||
|
} else {
|
||||||
|
img = $('.current-image')
|
||||||
|
if(img.next('.image').length == 0){
|
||||||
|
prevImage()
|
||||||
|
} else {
|
||||||
|
nextImage()
|
||||||
|
}
|
||||||
|
img
|
||||||
|
.detach()
|
||||||
|
.appendTo($('.current-ribbon').next('.ribbon'))
|
||||||
|
}
|
||||||
|
$('.current-image').click()
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX sort elements correctly...
|
||||||
|
// XXX do animations...
|
||||||
|
// XXX BUG: when demoting first image (new ribbon created) it gets focused...
|
||||||
|
// REASON: .click() gets called in several places BEFORE the animation is done...
|
||||||
|
// NOTE: this bog does not affect promoteImage -- adding a lower element does not affect current positioning...
|
||||||
|
function demoteImage(){
|
||||||
|
if($('.current-ribbon').prev('.ribbon').length == 0){
|
||||||
|
var new_ribbon = createRibbonAbove()
|
||||||
|
}
|
||||||
|
// XXX sort elements correctly...
|
||||||
|
if($('.current-ribbon').children('.image').length == 1){
|
||||||
|
// XXX this adds image to the head while the below portion adds it to the tail...
|
||||||
|
mergeRibbonsUp()
|
||||||
|
} else {
|
||||||
|
img = $('.current-image')
|
||||||
|
if(img.next('.image').length == 0){
|
||||||
|
// XXX in case when we've just created an empty ribbon, the click in this fires BEFORE it is fully expanded...
|
||||||
|
prevImage()
|
||||||
|
} else {
|
||||||
|
// XXX in case when we've just created an empty ribbon, the click in this fires BEFORE it is fully expanded...
|
||||||
|
nextImage()
|
||||||
|
}
|
||||||
|
img
|
||||||
|
.detach()
|
||||||
|
.appendTo($('.current-ribbon').prev('.ribbon'))
|
||||||
|
}
|
||||||
|
// XXX in case when we've just created an empty ribbon, the click in this fires BEFORE it is fully expanded...
|
||||||
|
$('.current-image').click()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// vim:set ts=4 sw=4 nowrap :
|
||||||
199
ui/gallery.css
Normal file → Executable file
199
ui/gallery.css
Normal file → Executable file
@ -0,0 +1,199 @@
|
|||||||
|
.image {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
width: 350px;
|
||||||
|
height: 350px;
|
||||||
|
|
||||||
|
display: inline-block;
|
||||||
|
background: no-repeat 50% black;
|
||||||
|
background-size: contain;
|
||||||
|
|
||||||
|
opacity: 0.3;
|
||||||
|
|
||||||
|
-webkit-transition: all 0.5s ease;
|
||||||
|
-moz-transition: all 0.5s ease;
|
||||||
|
-o-transition: all 0.5s ease;
|
||||||
|
-ms-transition: all 0.5s ease;
|
||||||
|
transition: all 0.5s ease;
|
||||||
|
|
||||||
|
cursor: hand;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mock-image {
|
||||||
|
background: blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.demo-buttons {
|
||||||
|
margin: 15px
|
||||||
|
border: groove 2px;
|
||||||
|
|
||||||
|
opacity: 0.2;
|
||||||
|
|
||||||
|
-webkit-transition: all 0.5s ease;
|
||||||
|
-moz-transition: all 0.5s ease;
|
||||||
|
-o-transition: all 0.5s ease;
|
||||||
|
-ms-transition: all 0.5s ease;
|
||||||
|
transition: all 0.5s ease;
|
||||||
|
}
|
||||||
|
.demo-buttons:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.viewer {
|
||||||
|
width: 900px;
|
||||||
|
height: 500px;
|
||||||
|
border: solid blue 5px;
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
.controller {
|
||||||
|
height: 500px;
|
||||||
|
width: 50px;
|
||||||
|
background: silver;
|
||||||
|
float: left;
|
||||||
|
|
||||||
|
-webkit-transition: all 0.5s ease;
|
||||||
|
-moz-transition: all 0.5s ease;
|
||||||
|
-o-transition: all 0.5s ease;
|
||||||
|
-ms-transition: all 0.5s ease;
|
||||||
|
transition: all 0.5s ease;
|
||||||
|
}
|
||||||
|
.single-image-mode .controller {
|
||||||
|
opacity: 0.2;
|
||||||
|
}
|
||||||
|
.promote, .next-image, .prev-image, .demote, .toggle-wide, .toggle-single {
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
width: 100%;
|
||||||
|
height: 150px;
|
||||||
|
background: gray;
|
||||||
|
|
||||||
|
-moz-user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-o-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
.next-image, .prev-image, .toggle-wide, .toggle-single {
|
||||||
|
background: silver;
|
||||||
|
}
|
||||||
|
.toggle-wide, .toggle-single {
|
||||||
|
height:50px
|
||||||
|
}
|
||||||
|
.promote {
|
||||||
|
}
|
||||||
|
.next-image {
|
||||||
|
}
|
||||||
|
.prev-image {
|
||||||
|
}
|
||||||
|
.demote {
|
||||||
|
}
|
||||||
|
.toggle-wide {
|
||||||
|
}
|
||||||
|
.toggle-single {
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
float: left;
|
||||||
|
overflow: hidden;
|
||||||
|
width: 800px;
|
||||||
|
height: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field {
|
||||||
|
position: relative;
|
||||||
|
overflow: visible;
|
||||||
|
top: 0px;
|
||||||
|
left: -100px;
|
||||||
|
|
||||||
|
-webkit-transition: all 0.5s ease;
|
||||||
|
-moz-transition: all 0.5s ease;
|
||||||
|
-o-transition: all 0.5s ease;
|
||||||
|
-ms-transition: all 0.5s ease;
|
||||||
|
transition: all 0.5s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ribbon {
|
||||||
|
height: 360px;
|
||||||
|
/* XXX make this expand dynamically */
|
||||||
|
width: 100000px;
|
||||||
|
overflow: visible;
|
||||||
|
padding-top: 2px;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
text-align: center;
|
||||||
|
opacity: 0.2;
|
||||||
|
|
||||||
|
-webkit-transition: all 0.5s ease;
|
||||||
|
-moz-transition: all 0.5s ease;
|
||||||
|
-o-transition: all 0.5s ease;
|
||||||
|
-ms-transition: all 0.5s ease;
|
||||||
|
transition: all 0.5s ease;
|
||||||
|
|
||||||
|
}
|
||||||
|
.new-ribbon {
|
||||||
|
height: 0px;
|
||||||
|
|
||||||
|
-webkit-transition: all 0.5s ease;
|
||||||
|
-moz-transition: all 0.5s ease;
|
||||||
|
-o-transition: all 0.5s ease;
|
||||||
|
-ms-transition: all 0.5s ease;
|
||||||
|
transition: all 0.5s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.current-image {
|
||||||
|
opacity: 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.current-ribbon {
|
||||||
|
padding-top: 20px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
|
||||||
|
opacity: 1.0;
|
||||||
|
|
||||||
|
-webkit-transition: all 0.5s ease;
|
||||||
|
-moz-transition: all 0.5s ease;
|
||||||
|
-o-transition: all 0.5s ease;
|
||||||
|
-ms-transition: all 0.5s ease;
|
||||||
|
transition: all 0.5s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.current-ribbon .image {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* single image theme (start everything with .single-image-mode)
|
||||||
|
*
|
||||||
|
* XXX need to make this touch friendly...
|
||||||
|
*/
|
||||||
|
.single-image-mode .image {
|
||||||
|
opacity: 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.single-image-mode .image:hover {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.single-image-mode .current-image:hover, .single-image-mode .current-image {
|
||||||
|
opacity: 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* wide view mode */
|
||||||
|
|
||||||
|
/* XXX not yet working correctly...
|
||||||
|
.wide-view-mode {
|
||||||
|
transform: scale(0.2,0.2);
|
||||||
|
-ms-transform: scale(0.2,0.2);
|
||||||
|
-webkit-transform: scale(0.2,0.2);
|
||||||
|
-o-transform: scale(0.2,0.2);
|
||||||
|
-moz-transform: scale(0.2,0.2);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
.wide-view-mode .image {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.wide-view-mode .ribbon {
|
||||||
|
height: 60px;
|
||||||
|
}
|
||||||
619
ui/gallery.html
619
ui/gallery.html
@ -1,635 +1,28 @@
|
|||||||
|
|
||||||
<!--
|
<!--
|
||||||
TODO:
|
|
||||||
- basic structure
|
|
||||||
ribbons DONE
|
|
||||||
images DONE
|
|
||||||
indicators
|
|
||||||
- basic control elements
|
|
||||||
touch zones / buttons
|
|
||||||
next DONE
|
|
||||||
prev DONE
|
|
||||||
shift up DONE
|
|
||||||
shift down DONE
|
|
||||||
promote DONE
|
|
||||||
demote DONE
|
|
||||||
zoom in ~ need real zooming...
|
|
||||||
zoom out ~ need real zooming...
|
|
||||||
toggle single image DONE
|
|
||||||
- image sorting
|
|
||||||
- will affect:
|
|
||||||
- promote
|
|
||||||
- demote
|
|
||||||
- shift up
|
|
||||||
- shift down
|
|
||||||
- ribbon merging
|
|
||||||
- add promote/demote events (to attach structure editors)...
|
|
||||||
- add real images...
|
|
||||||
- make all the code relative to the current selection (multiple instances on a page support)
|
|
||||||
- make this into a jquery plugin...
|
|
||||||
- add dynamic loading and unloading for very large sets...
|
|
||||||
- gesture support...
|
|
||||||
- add basic actions:
|
|
||||||
- rotate left
|
|
||||||
- rotate right
|
|
||||||
- ...
|
|
||||||
- add info:
|
|
||||||
- number of images in ribbon
|
|
||||||
- position in ribbon
|
|
||||||
|
|
||||||
|
|
||||||
- first stage refactoring:
|
|
||||||
- merge almost identical functions...
|
|
||||||
|
|
||||||
- multiple groups to promote/demote
|
|
||||||
ways to go:
|
|
||||||
- promote/demote and tag
|
|
||||||
|
|
||||||
ISSUES:
|
|
||||||
- jumping on focus up/down...
|
|
||||||
- demoting a first element (a ribbon is created) positions the field incorrectly (see demoteImage() for details)...
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="gallery.css">
|
||||||
<script src="jquery.js"></script>
|
<script src="jquery.js"></script>
|
||||||
|
|
||||||
<!-- script src="jquery.wipetouch.js"></script-->
|
<!-- script src="jquery.wipetouch.js"></script-->
|
||||||
|
|
||||||
<!-- XXX this does not work on android... -->
|
<!-- XXX this does not work on android... -->
|
||||||
<script src="jquery.gestures.js"></script>
|
<script src="jquery.gestures.js"></script>
|
||||||
|
<!-- XXX need to figure out how to disable all the bling -->
|
||||||
|
<!-- script src="jquery.mobile.js"></script-->
|
||||||
|
|
||||||
<!-- XXX STUB -->
|
<!-- XXX STUB -->
|
||||||
<script src="images.js"></script>
|
<script src="images.js"></script>
|
||||||
|
<script src="gallery-prototype.js"></script>
|
||||||
|
|
||||||
|
<!--script src="gallery.js"></script-->
|
||||||
|
|
||||||
<!-- XXX need to figure out how to disable all the bling -->
|
|
||||||
<!-- script src="jquery.mobile.js"></script-->
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
$(document).ready(function() {
|
|
||||||
// current state...
|
|
||||||
if($('.current-ribbon').length == 0){
|
|
||||||
$('.ribbon').first().addClass('current-ribbon')
|
|
||||||
}
|
|
||||||
if($('.current-image').length == 0){
|
|
||||||
$('.current-ribbon').children('.image').first().addClass('current-image')
|
|
||||||
}
|
|
||||||
|
|
||||||
// setup event handlers...
|
|
||||||
$(document)
|
|
||||||
.keydown(handleKeys)
|
|
||||||
$('.viewer')
|
|
||||||
// XXX this is flaky and breaks some of my code...
|
|
||||||
/*.wipetouch({
|
|
||||||
wipeLeft: nextImage,
|
|
||||||
wipeRight: prevImage,
|
|
||||||
wipeUp: demoteImage,
|
|
||||||
wipeDown: promoteImage,
|
|
||||||
|
|
||||||
tapToClick: true
|
|
||||||
})*/
|
|
||||||
// XXX does not work on android...
|
|
||||||
.gestures({eventHandler: handleGestures})
|
|
||||||
/* XXX jquery.mobile handlers... (with this I'm getting way too much bling)
|
|
||||||
.bind('swipeleft', function(e){
|
|
||||||
nextImage()
|
|
||||||
e.preventDefault()
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
.bind('swiperight', function(e){
|
|
||||||
prevImage()
|
|
||||||
e.preventDefault()
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
*/
|
|
||||||
$(".image").click(handleClick)
|
|
||||||
|
|
||||||
// control elements...
|
|
||||||
$('.next-image').click(nextImage)
|
|
||||||
$('.prev-image').click(prevImage)
|
|
||||||
$('.demote').click(demoteImage)
|
|
||||||
$('.promote').click(promoteImage)
|
|
||||||
$('.toggle-wide').click(toggleWideView)
|
|
||||||
$('.toggle-single').click(toggleRibbonView)
|
|
||||||
|
|
||||||
// load images...
|
|
||||||
// XXX not allowed...
|
|
||||||
//$.getJSON('images.js', loadImages})
|
|
||||||
// XXX STUB
|
|
||||||
loadImages(image_list)
|
|
||||||
|
|
||||||
// set the default position and init...
|
|
||||||
$('.current-image').click()
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
function loadImages(json){
|
|
||||||
var images = json.images
|
|
||||||
var ribbon = $('.ribbon').last()
|
|
||||||
|
|
||||||
$('.image').remove()
|
|
||||||
|
|
||||||
for(var i = 0; i < images.length; i++){
|
|
||||||
$('<div class="image"></div>')
|
|
||||||
.css({
|
|
||||||
'background-image': 'url('+images[i]+')'
|
|
||||||
})
|
|
||||||
.click(handleClick)
|
|
||||||
.appendTo(ribbon)
|
|
||||||
}
|
|
||||||
ribbon.children().first().click()
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX jquery.gestures handler...
|
|
||||||
function handleGestures(e){
|
|
||||||
switch (e){
|
|
||||||
case 'N':
|
|
||||||
demoteImage()
|
|
||||||
break
|
|
||||||
case 'S':
|
|
||||||
promoteImage()
|
|
||||||
break
|
|
||||||
case 'E':
|
|
||||||
prevImage()
|
|
||||||
break
|
|
||||||
case 'W':
|
|
||||||
nextImage()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function handleClick(e) {
|
|
||||||
|
|
||||||
var cur = $(this)
|
|
||||||
|
|
||||||
// switch classes...
|
|
||||||
cur.parents().siblings().children(".image").removeClass("current-image")
|
|
||||||
cur.siblings(".image").removeClass("current-image")
|
|
||||||
|
|
||||||
cur.siblings().children(".image").removeClass("current-image")
|
|
||||||
cur.parents().siblings(".ribbon").removeClass("current-ribbon")
|
|
||||||
|
|
||||||
cur.addClass("current-image")
|
|
||||||
cur.parents(".ribbon").addClass("current-ribbon")
|
|
||||||
|
|
||||||
|
|
||||||
var container = cur.parents('.container')
|
|
||||||
var field = cur.parents(".field")
|
|
||||||
|
|
||||||
var image_offset = cur.offset()
|
|
||||||
var field_offset = field.offset()
|
|
||||||
|
|
||||||
// center the current image...
|
|
||||||
field.css({
|
|
||||||
left: field_offset.left - image_offset.left + (container.innerWidth() - cur.innerWidth())/2,
|
|
||||||
top: field_offset.top - image_offset.top + (container.innerHeight() - cur.innerHeight())/2
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
// XXX do I need this???
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
var keys = {
|
|
||||||
toggleHelpKeys: [72],
|
|
||||||
toggleRibbonView: [32],
|
|
||||||
closeKeys: [27, 88, 67],
|
|
||||||
|
|
||||||
firstKeys: [36],
|
|
||||||
lastKeys: [35],
|
|
||||||
previousKeys: [37, 80],
|
|
||||||
nextKeys: [39, 78],
|
|
||||||
promoteKeys: [40],
|
|
||||||
// XXX add del (46) to demote...
|
|
||||||
demoteKeys: [38],
|
|
||||||
|
|
||||||
ignoreKeys: [16, 17, 18],
|
|
||||||
|
|
||||||
helpShowOnUnknownKey: true
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleKeys(event){
|
|
||||||
var code = event.keyCode, fn = $.inArray;
|
|
||||||
var _ = (fn(code, keys.closeKeys) >= 0) ? function(){}()
|
|
||||||
: (fn(code, keys.firstKeys) >= 0) ? firstImage()
|
|
||||||
: (fn(code, keys.nextKeys) >= 0) ? nextImage()
|
|
||||||
: (fn(code, keys.previousKeys) >= 0) ? prevImage()
|
|
||||||
: (fn(code, keys.lastKeys) >= 0) ? lastImage()
|
|
||||||
: (fn(code, keys.promoteKeys) >= 0) ? function(){
|
|
||||||
if(event.shiftKey){
|
|
||||||
if(event.ctrlKey){
|
|
||||||
createRibbonBelow()
|
|
||||||
}
|
|
||||||
promoteImage()
|
|
||||||
} else {
|
|
||||||
focusBelowRibbon()
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
: (fn(code, keys.demoteKeys) >= 0) ? function(){
|
|
||||||
if(event.shiftKey){
|
|
||||||
if(event.ctrlKey){
|
|
||||||
createRibbonAbove()
|
|
||||||
}
|
|
||||||
demoteImage()
|
|
||||||
} else {
|
|
||||||
focusAboveRibbon()
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
: (fn(code, keys.toggleRibbonView) >= 0) ? toggleRibbonView()
|
|
||||||
: (fn(code, keys.ignoreKeys) >= 0) ? false
|
|
||||||
// XXX
|
|
||||||
: (keys.helpShowOnUnknownKey) ? function(){alert(code)}()
|
|
||||||
: false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// modes...
|
|
||||||
function showRibbon(){
|
|
||||||
$('.single-image-mode').removeClass('single-image-mode')
|
|
||||||
}
|
|
||||||
function showSingle(){
|
|
||||||
$('.viewer').not('.single-image-mode').addClass('single-image-mode')
|
|
||||||
}
|
|
||||||
function toggleRibbonView(){
|
|
||||||
if($('.single-image-mode').length > 0){
|
|
||||||
showRibbon()
|
|
||||||
} else {
|
|
||||||
showSingle()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX need to reposition the whole thing correctly...
|
|
||||||
function toggleWideView(){
|
|
||||||
if($('.wide-view-mode').length > 0){
|
|
||||||
$('.wide-view-mode')
|
|
||||||
.removeClass('wide-view-mode')
|
|
||||||
.one("webkitTransitionEnd oTransitionEnd msTransitionEnd transitionend", function(){
|
|
||||||
$('.current-image').click()
|
|
||||||
return true
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
|
||||||
showRibbon()
|
|
||||||
//$('.container')
|
|
||||||
$('.viewer')
|
|
||||||
.not('.wide-view-mode')
|
|
||||||
.addClass('wide-view-mode')
|
|
||||||
.one("webkitTransitionEnd oTransitionEnd msTransitionEnd transitionend", function(){
|
|
||||||
$('.current-image').click()
|
|
||||||
return true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// basic navigation...
|
|
||||||
function firstImage(){
|
|
||||||
$('.current-ribbon').children('.image').first().click()
|
|
||||||
}
|
|
||||||
|
|
||||||
function prevImage(){
|
|
||||||
$('.current-image').prev('.image').click()
|
|
||||||
}
|
|
||||||
|
|
||||||
function nextImage(){
|
|
||||||
$('.current-image').next('.image').click()
|
|
||||||
}
|
|
||||||
|
|
||||||
function lastImage(){
|
|
||||||
$('.current-ribbon').children('.image').last().click()
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX select appropriate image...
|
|
||||||
function focusAboveRibbon(){
|
|
||||||
$('.current-ribbon').prev('.ribbon').children('.image').first().click()
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX select appropriate image...
|
|
||||||
function focusBelowRibbon(){
|
|
||||||
$('.current-ribbon').next('.ribbon').children('.image').first().click()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// create ribbon above/below helpers...
|
|
||||||
// XXX NOTE: this will shift the content downwards...
|
|
||||||
function createRibbonAbove(){
|
|
||||||
var res = $('<div class="new-ribbon"></div>')
|
|
||||||
.insertBefore('.current-ribbon')
|
|
||||||
// HACK: without this, the class change below will not animate...
|
|
||||||
.show()
|
|
||||||
.addClass('ribbon')
|
|
||||||
.removeClass('new-ribbon')
|
|
||||||
// XXX find a better way to do this...
|
|
||||||
$('.field').css({
|
|
||||||
top: $('.field').position().top - $('.current-ribbon').outerHeight()
|
|
||||||
})
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
function createRibbonBelow(){
|
|
||||||
return $('<div class="new-ribbon"></div>')
|
|
||||||
.insertAfter('.current-ribbon')
|
|
||||||
// HACK: without this, the class change below will not animate...
|
|
||||||
.show()
|
|
||||||
.addClass('ribbon')
|
|
||||||
.removeClass('new-ribbon')
|
|
||||||
}
|
|
||||||
|
|
||||||
// Modifiers...
|
|
||||||
|
|
||||||
// XXX sort elements correctly...
|
|
||||||
function mergeRibbonsUp(){
|
|
||||||
$('.current-ribbon')
|
|
||||||
.prev('.ribbon')
|
|
||||||
.children()
|
|
||||||
.detach()
|
|
||||||
.insertAfter('.current-image')
|
|
||||||
$('.current-ribbon')
|
|
||||||
.prev('.ribbon')
|
|
||||||
.slideUp(function(){
|
|
||||||
$(this).remove()
|
|
||||||
$('.current-image').click()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX sort elements correctly...
|
|
||||||
function mergeRibbonsDown(){
|
|
||||||
$('.current-ribbon')
|
|
||||||
.next('.ribbon')
|
|
||||||
.children()
|
|
||||||
.detach()
|
|
||||||
.insertAfter('.current-image')
|
|
||||||
$('.current-ribbon')
|
|
||||||
.next('.ribbon')
|
|
||||||
.slideUp(function(){
|
|
||||||
$(this).remove()
|
|
||||||
$('.current-image').click()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX sort elements correctly...
|
|
||||||
// XXX do animations...
|
|
||||||
function promoteImage(){
|
|
||||||
if($('.current-ribbon').next('.ribbon').length == 0){
|
|
||||||
createRibbonBelow()
|
|
||||||
}
|
|
||||||
// XXX sort elements correctly...
|
|
||||||
if($('.current-ribbon').children('.image').length == 1){
|
|
||||||
// XXX this adds image to the head while the below portion adds it to the tail...
|
|
||||||
mergeRibbonsDown()
|
|
||||||
} else {
|
|
||||||
img = $('.current-image')
|
|
||||||
if(img.next('.image').length == 0){
|
|
||||||
prevImage()
|
|
||||||
} else {
|
|
||||||
nextImage()
|
|
||||||
}
|
|
||||||
img
|
|
||||||
.detach()
|
|
||||||
.appendTo($('.current-ribbon').next('.ribbon'))
|
|
||||||
}
|
|
||||||
$('.current-image').click()
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX sort elements correctly...
|
|
||||||
// XXX do animations...
|
|
||||||
// XXX BUG: when demoting first image (new ribbon created) it gets focused...
|
|
||||||
// REASON: .click() gets called in several places BEFORE the animation is done...
|
|
||||||
// NOTE: this bog does not affect promoteImage -- adding a lower element does not affect current positioning...
|
|
||||||
function demoteImage(){
|
|
||||||
if($('.current-ribbon').prev('.ribbon').length == 0){
|
|
||||||
var new_ribbon = createRibbonAbove()
|
|
||||||
}
|
|
||||||
// XXX sort elements correctly...
|
|
||||||
if($('.current-ribbon').children('.image').length == 1){
|
|
||||||
// XXX this adds image to the head while the below portion adds it to the tail...
|
|
||||||
mergeRibbonsUp()
|
|
||||||
} else {
|
|
||||||
img = $('.current-image')
|
|
||||||
if(img.next('.image').length == 0){
|
|
||||||
// XXX in case when we've just created an empty ribbon, the click in this fires BEFORE it is fully expanded...
|
|
||||||
prevImage()
|
|
||||||
} else {
|
|
||||||
// XXX in case when we've just created an empty ribbon, the click in this fires BEFORE it is fully expanded...
|
|
||||||
nextImage()
|
|
||||||
}
|
|
||||||
img
|
|
||||||
.detach()
|
|
||||||
.appendTo($('.current-ribbon').prev('.ribbon'))
|
|
||||||
}
|
|
||||||
// XXX in case when we've just created an empty ribbon, the click in this fires BEFORE it is fully expanded...
|
|
||||||
$('.current-image').click()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.image {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
width: 350px;
|
|
||||||
height: 350px;
|
|
||||||
|
|
||||||
display: inline-block;
|
|
||||||
background: no-repeat 50% black;
|
|
||||||
background-size: contain;
|
|
||||||
|
|
||||||
opacity: 0.3;
|
|
||||||
|
|
||||||
-webkit-transition: all 0.5s ease;
|
|
||||||
-moz-transition: all 0.5s ease;
|
|
||||||
-o-transition: all 0.5s ease;
|
|
||||||
-ms-transition: all 0.5s ease;
|
|
||||||
transition: all 0.5s ease;
|
|
||||||
|
|
||||||
cursor: hand;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mock-image {
|
|
||||||
background: blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.demo-buttons {
|
|
||||||
margin: 15px
|
|
||||||
border: groove 2px;
|
|
||||||
|
|
||||||
opacity: 0.2;
|
|
||||||
|
|
||||||
-webkit-transition: all 0.5s ease;
|
|
||||||
-moz-transition: all 0.5s ease;
|
|
||||||
-o-transition: all 0.5s ease;
|
|
||||||
-ms-transition: all 0.5s ease;
|
|
||||||
transition: all 0.5s ease;
|
|
||||||
}
|
|
||||||
.demo-buttons:hover {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.viewer {
|
|
||||||
width: 900px;
|
|
||||||
height: 500px;
|
|
||||||
border: solid blue 5px;
|
|
||||||
margin: 20px;
|
|
||||||
}
|
|
||||||
.controller {
|
|
||||||
height: 500px;
|
|
||||||
width: 50px;
|
|
||||||
background: silver;
|
|
||||||
float: left;
|
|
||||||
|
|
||||||
-webkit-transition: all 0.5s ease;
|
|
||||||
-moz-transition: all 0.5s ease;
|
|
||||||
-o-transition: all 0.5s ease;
|
|
||||||
-ms-transition: all 0.5s ease;
|
|
||||||
transition: all 0.5s ease;
|
|
||||||
}
|
|
||||||
.single-image-mode .controller {
|
|
||||||
opacity: 0.2;
|
|
||||||
}
|
|
||||||
.promote, .next-image, .prev-image, .demote, .toggle-wide, .toggle-single {
|
|
||||||
text-align: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
width: 100%;
|
|
||||||
height: 150px;
|
|
||||||
background: gray;
|
|
||||||
|
|
||||||
-moz-user-select: none;
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-o-user-select: none;
|
|
||||||
-ms-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
.next-image, .prev-image, .toggle-wide, .toggle-single {
|
|
||||||
background: silver;
|
|
||||||
}
|
|
||||||
.toggle-wide, .toggle-single {
|
|
||||||
height:50px
|
|
||||||
}
|
|
||||||
.promote {
|
|
||||||
}
|
|
||||||
.next-image {
|
|
||||||
}
|
|
||||||
.prev-image {
|
|
||||||
}
|
|
||||||
.demote {
|
|
||||||
}
|
|
||||||
.toggle-wide {
|
|
||||||
}
|
|
||||||
.toggle-single {
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
float: left;
|
|
||||||
overflow: hidden;
|
|
||||||
width: 800px;
|
|
||||||
height: 500px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.field {
|
|
||||||
position: relative;
|
|
||||||
overflow: visible;
|
|
||||||
top: 0px;
|
|
||||||
left: -100px;
|
|
||||||
|
|
||||||
-webkit-transition: all 0.5s ease;
|
|
||||||
-moz-transition: all 0.5s ease;
|
|
||||||
-o-transition: all 0.5s ease;
|
|
||||||
-ms-transition: all 0.5s ease;
|
|
||||||
transition: all 0.5s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ribbon {
|
|
||||||
height: 360px;
|
|
||||||
/* XXX make this expand dynamically */
|
|
||||||
width: 100000px;
|
|
||||||
overflow: visible;
|
|
||||||
padding-top: 2px;
|
|
||||||
padding-bottom: 2px;
|
|
||||||
text-align: center;
|
|
||||||
opacity: 0.2;
|
|
||||||
|
|
||||||
-webkit-transition: all 0.5s ease;
|
|
||||||
-moz-transition: all 0.5s ease;
|
|
||||||
-o-transition: all 0.5s ease;
|
|
||||||
-ms-transition: all 0.5s ease;
|
|
||||||
transition: all 0.5s ease;
|
|
||||||
|
|
||||||
}
|
|
||||||
.new-ribbon {
|
|
||||||
height: 0px;
|
|
||||||
|
|
||||||
-webkit-transition: all 0.5s ease;
|
|
||||||
-moz-transition: all 0.5s ease;
|
|
||||||
-o-transition: all 0.5s ease;
|
|
||||||
-ms-transition: all 0.5s ease;
|
|
||||||
transition: all 0.5s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.current-image {
|
|
||||||
opacity: 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.current-ribbon {
|
|
||||||
padding-top: 20px;
|
|
||||||
padding-bottom: 20px;
|
|
||||||
|
|
||||||
opacity: 1.0;
|
|
||||||
|
|
||||||
-webkit-transition: all 0.5s ease;
|
|
||||||
-moz-transition: all 0.5s ease;
|
|
||||||
-o-transition: all 0.5s ease;
|
|
||||||
-ms-transition: all 0.5s ease;
|
|
||||||
transition: all 0.5s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.current-ribbon .image {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* single image theme (start everything with .single-image-mode)
|
|
||||||
*
|
|
||||||
* XXX need to make this touch friendly...
|
|
||||||
*/
|
|
||||||
.single-image-mode .image {
|
|
||||||
opacity: 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.single-image-mode .image:hover {
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.single-image-mode .current-image:hover, .single-image-mode .current-image {
|
|
||||||
opacity: 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* wide view mode */
|
|
||||||
|
|
||||||
/* XXX not yet working correctly...
|
|
||||||
.wide-view-mode {
|
|
||||||
transform: scale(0.2,0.2);
|
|
||||||
-ms-transform: scale(0.2,0.2);
|
|
||||||
-webkit-transform: scale(0.2,0.2);
|
|
||||||
-o-transform: scale(0.2,0.2);
|
|
||||||
-moz-transform: scale(0.2,0.2);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
.wide-view-mode .image {
|
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.wide-view-mode .ribbon {
|
|
||||||
height: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
<div class="viewer">
|
<div class="viewer">
|
||||||
<div class="controller">
|
<div class="controller">
|
||||||
<div class="demote">^</div>
|
<div class="demote">^</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user