mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 10:20:08 +00:00
added global transition toggle, some code cleanup and refactoring...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
a105db3161
commit
46df972ac1
@ -1,5 +1,5 @@
|
||||
Priority work
|
||||
[_] 79% Preview II
|
||||
[_] 84% Preview II
|
||||
[X] 100% sorted images in ribbons
|
||||
[X] 100% stage I: position the promoted/demoted image correctly
|
||||
| and correct positioning on promote/demote
|
||||
@ -100,13 +100,15 @@ Priority work
|
||||
[X] 100% actions
|
||||
[X] bug: shifting up to new ribbon pushes the current row down...
|
||||
| before starting on a fix, need to cleanup the code from old hacks and workarounds...
|
||||
[_] 16% native client
|
||||
[_] 41% native client
|
||||
[_] 33% Windows (CEF / CEFPython)
|
||||
[X] basic test
|
||||
[_] basic wrapper
|
||||
| hook-in os-specific API
|
||||
[_] package a portable exe
|
||||
[_] 0% Android (PhoneGap)
|
||||
[_] 50% Android (PhoneGap)
|
||||
[X] basic test
|
||||
[X] disable transitions...
|
||||
[_] restrict layout to horizontal
|
||||
| leave doing a different vertical layout for later versions...
|
||||
[_] basic wrapper
|
||||
|
||||
@ -50,6 +50,7 @@ function setup(){
|
||||
|
||||
// XXX
|
||||
setBackgroundMode('dark')
|
||||
enableTransitions()
|
||||
|
||||
// setup event handlers...
|
||||
setupEvents()
|
||||
|
||||
@ -5,8 +5,9 @@
|
||||
// XXX need to make this handle modifiers gracefully...
|
||||
var keys = {
|
||||
toggleHelp: [72], // ???
|
||||
toggleSingleImageMode: [70, 13], // ???, Enter
|
||||
toggleSingleImageMode: [70, 13], // f, Enter
|
||||
toggleSingleImageModeTransitions: [84], // t
|
||||
toggleTransitions: [65], // a
|
||||
toggleBackgroundModes: [66], // b
|
||||
toggleControls: [9], // tab
|
||||
close: [27, 88, 67], // ???
|
||||
@ -66,6 +67,160 @@ var MOVE_DELTA = 50
|
||||
|
||||
|
||||
|
||||
|
||||
/********************************************************** Helpers **/
|
||||
|
||||
|
||||
// this will create a function that will add/remove a css_class to elem
|
||||
// calling the callbacks before and/or after.
|
||||
// NOTE: of only one callback is given then it will be called after the
|
||||
// class change...
|
||||
// a way around this is to pass an empty function as callback_b
|
||||
function createCSSClassToggler(elem, css_class, callback_a, callback_b){
|
||||
// prepare the pre/post callbacks...
|
||||
if(callback_b == null){
|
||||
var callback_pre = null
|
||||
var callback_post = callback_a
|
||||
} else {
|
||||
var callback_pre = callback_a
|
||||
var callback_post = callback_b
|
||||
}
|
||||
return function(action){
|
||||
if(action == null){
|
||||
action = 'on'
|
||||
// get current state...
|
||||
if( $(elem).hasClass(css_class) ){
|
||||
action = 'off'
|
||||
}
|
||||
}
|
||||
if(callback_pre != null){
|
||||
callback_pre(action)
|
||||
}
|
||||
// play with the class...
|
||||
if(state == 'on'){
|
||||
$(elem).addClass(css_class)
|
||||
} else {
|
||||
$(elem).removeClass(css_class)
|
||||
}
|
||||
if(callback_post != null){
|
||||
callback_post(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// disable transitions on obj, call func then enable transitions back...
|
||||
function doWithoutTransitions(obj, func){
|
||||
obj
|
||||
.addClass('unanimated')
|
||||
.one("webkitTransitionEnd oTransitionEnd msTransitionEnd transitionend", function(){
|
||||
func()
|
||||
$('.viewer')
|
||||
.one("webkitTransitionEnd oTransitionEnd msTransitionEnd transitionend", function(){
|
||||
obj.removeClass('unanimated')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
// find an image object after which to position image ID...
|
||||
// used for two main tasks:
|
||||
// - positioning promoted/demoted images
|
||||
// - centering ribbons
|
||||
// returns:
|
||||
// - null - empty ribbon or no element greater id should be first
|
||||
// - element
|
||||
// XXX do we need to make ids numbers for this to work?
|
||||
function getImageBefore_lin(id, ribbon){
|
||||
// walk the ribbon till we find two images one with an ID less and
|
||||
// another greater that id...
|
||||
id = parseInt(id)
|
||||
var images = ribbon.children('.image')
|
||||
var prev = null
|
||||
for(var i=0; i < images.length; i++){
|
||||
if(parseInt($(images[i]).attr('id')) > id){
|
||||
return prev
|
||||
}
|
||||
prev = $(images[i])
|
||||
}
|
||||
return prev
|
||||
}
|
||||
|
||||
|
||||
// generic binery search for element just before the id...
|
||||
// NOTE: if id is in lst, this will return the element just before it.
|
||||
// NOTE: lst must be sorted.
|
||||
function binarySearch(id, lst, get){
|
||||
if(get == null){
|
||||
get = function(o){return o}
|
||||
}
|
||||
|
||||
// empty list...
|
||||
if(lst.length == 0){
|
||||
return null
|
||||
}
|
||||
|
||||
// current section length
|
||||
var l = Math.round((lst.length-1)/2)
|
||||
// current position...
|
||||
var i = l
|
||||
|
||||
while(true){
|
||||
var i_id = get(lst[i])
|
||||
// beginning of the array...
|
||||
if(i == 0){
|
||||
if(id > i_id){
|
||||
return i
|
||||
}
|
||||
return null
|
||||
}
|
||||
// we got a hit...
|
||||
if(i_id == id){
|
||||
return i-1
|
||||
}
|
||||
// we are at the end...
|
||||
if(i == lst.length-1 && id > i_id){
|
||||
return i
|
||||
}
|
||||
var ii_id = get(lst[i+1])
|
||||
// test if id is between i and i+1...
|
||||
if( i_id < id && id < ii_id ){
|
||||
return i
|
||||
}
|
||||
// prepare for next iteration...
|
||||
// NOTE: we saturate the values so we will never get out of bounds.
|
||||
l = Math.round(l/2)
|
||||
if(id < i_id){
|
||||
// lower half...
|
||||
i = Math.max(0, i-l)
|
||||
} else {
|
||||
// upper half...
|
||||
i = Math.min(i+l, lst.length-1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// wrapper around binarySearch.
|
||||
// this is here to make binarySearch simpler to test and debug...
|
||||
function getImageBefore_bin(id, ribbon){
|
||||
var images = ribbon.children('.image')
|
||||
var i = binarySearch(
|
||||
parseInt(id),
|
||||
images,
|
||||
function(o){return parseInt($(o).attr('id'))})
|
||||
if(i == null){
|
||||
return null
|
||||
}
|
||||
return $(images[i])
|
||||
}
|
||||
|
||||
// set the default search...
|
||||
var getImageBefore = getImageBefore_bin
|
||||
|
||||
|
||||
|
||||
|
||||
/************************************************** Setup Functions **/
|
||||
// XXX is this a correct place for these?
|
||||
|
||||
@ -107,6 +262,7 @@ function setupControlElements(){
|
||||
// buttons...
|
||||
$('.screen-button.next-image').click(nextImage)
|
||||
$('.screen-button.prev-image').click(prevImage)
|
||||
// XXX rename classes to "shift-image-up" and "shift-image-down"...
|
||||
$('.screen-button.demote').click(shiftImageUp)
|
||||
$('.screen-button.promote').click(shiftImageDown)
|
||||
|
||||
@ -253,6 +409,7 @@ function handleKeys(event){
|
||||
|
||||
: (fn(code, keys.toggleSingleImageMode) >= 0) ? toggleSingleImageMode()
|
||||
: (fn(code, keys.toggleSingleImageModeTransitions) >= 0) ? toggleSingleImageModeTransitions()
|
||||
: (fn(code, keys.toggleTransitions) >= 0) ? toggleTransitions()
|
||||
|
||||
: (fn(code, keys.toggleBackgroundModes) >= 0) ? toggleBackgroundModes()
|
||||
: (fn(code, keys.toggleControls) >= 0) ? toggleControls()
|
||||
@ -273,23 +430,6 @@ function handleKeys(event){
|
||||
|
||||
/************************************************************ Modes **/
|
||||
|
||||
// mode switchers...
|
||||
function unsetViewerMode(mode){
|
||||
$('.' + mode)
|
||||
.removeClass(mode)
|
||||
clickAfterTransitionsDone()
|
||||
}
|
||||
|
||||
|
||||
|
||||
function setViewerMode(mode){
|
||||
$('.viewer').not('.' + mode)
|
||||
.addClass(mode)
|
||||
clickAfterTransitionsDone()
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ribbon/single view modes...
|
||||
// global: stores the scale before we went into single image mode...
|
||||
// XXX HACK
|
||||
@ -303,48 +443,38 @@ var ORIGINAL_FIELD_SCALE = 1
|
||||
var NORMAL_MODE_BG = null
|
||||
var SINGLE_IMAGE_MODE_BG = BACKGROUND_MODES[BACKGROUND_MODES.length-1]
|
||||
|
||||
|
||||
function toggleSingleImageMode(){
|
||||
// go to normal mode...
|
||||
if($('.single-image-mode').length > 0){
|
||||
SINGLE_IMAGE_MODE_BG = getBackgroundMode()
|
||||
unsetViewerMode('single-image-mode')
|
||||
setContainerScale(ORIGINAL_FIELD_SCALE)
|
||||
setBackgroundMode(NORMAL_MODE_BG)
|
||||
// go to single image mode...
|
||||
} else {
|
||||
var toggleSingleImageMode = createCSSClassToggler('.viewer', 'single-image-mode',
|
||||
// pre...
|
||||
function(action){
|
||||
if(action == 'on'){
|
||||
NORMAL_MODE_BG = getBackgroundMode()
|
||||
setViewerMode('single-image-mode')
|
||||
ORIGINAL_FIELD_SCALE = getElementScale($('.field'))
|
||||
} else {
|
||||
SINGLE_IMAGE_MODE_BG = getBackgroundMode()
|
||||
}
|
||||
},
|
||||
// post...
|
||||
function(action){
|
||||
if(action == 'on'){
|
||||
fitImage()
|
||||
setBackgroundMode(SINGLE_IMAGE_MODE_BG)
|
||||
} else {
|
||||
setContainerScale(ORIGINAL_FIELD_SCALE)
|
||||
setBackgroundMode(NORMAL_MODE_BG)
|
||||
}
|
||||
}
|
||||
|
||||
clickAfterTransitionsDone()
|
||||
})
|
||||
|
||||
|
||||
// wide view mode toggle...
|
||||
function toggleWideView(){
|
||||
if($('.wide-view-mode').length > 0){
|
||||
setContainerScale(ORIGINAL_FIELD_SCALE)
|
||||
$('.viewer').removeClass('wide-view-mode')
|
||||
} else {
|
||||
var toggleWideView = createCSSClassToggler('.viewer', 'wide-view-mode', function(action){
|
||||
if(action == 'on'){
|
||||
ORIGINAL_FIELD_SCALE = getElementScale($('.field'))
|
||||
setContainerScale(0.1)
|
||||
$('.viewer').addClass('wide-view-mode')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function toggleSingleImageModeTransitions(){
|
||||
if( $('.no-single-image-transitions').length > 0 ){
|
||||
$('.no-single-image-transitions').removeClass('no-single-image-transitions')
|
||||
} else {
|
||||
$('.viewer').addClass('no-single-image-transitions')
|
||||
setContainerScale(ORIGINAL_FIELD_SCALE)
|
||||
}
|
||||
}
|
||||
|
||||
}, function(){})
|
||||
|
||||
|
||||
|
||||
@ -404,26 +534,17 @@ function toggleBackgroundModes(){
|
||||
|
||||
|
||||
|
||||
function showControls(){
|
||||
$('.hidden-controls').removeClass('hidden-controls')
|
||||
}
|
||||
var toggleSingleImageModeTransitions = createCSSClassToggler('.viewer', 'no-single-image-transitions')
|
||||
|
||||
|
||||
|
||||
function hideControls(){
|
||||
$('.viewer').addClass('hidden-controls')
|
||||
}
|
||||
var toggleControls = createCSSClassToggler('.viewer', 'hidden-controls')
|
||||
var showControls = function(){toggleControls('on')}
|
||||
var hideControls = function(){toggleControls('off')}
|
||||
|
||||
|
||||
|
||||
function toggleControls(){
|
||||
if( $('.hidden-controls').length > 0 ){
|
||||
showControls()
|
||||
} else {
|
||||
hideControls()
|
||||
}
|
||||
}
|
||||
|
||||
var toggleTransitions = createCSSClassToggler('.viewer', 'transitions-enabled')
|
||||
var enableTransitions = function(){toggleTransitions('on')}
|
||||
var disableTransitions = function(){toggleTransitions('off')}
|
||||
|
||||
|
||||
|
||||
@ -497,116 +618,6 @@ function focusBelowRibbon(){
|
||||
|
||||
|
||||
|
||||
/********************************************************** Helpers **/
|
||||
|
||||
function doWithoutTransitions(obj, func){
|
||||
obj
|
||||
.addClass('unanimated')
|
||||
.one("webkitTransitionEnd oTransitionEnd msTransitionEnd transitionend", function(){
|
||||
func()
|
||||
$('.viewer')
|
||||
.one("webkitTransitionEnd oTransitionEnd msTransitionEnd transitionend", function(){
|
||||
obj.removeClass('unanimated')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// find an image object after which to position image ID...
|
||||
// used for two main tasks:
|
||||
// - positioning promoted/demoted images
|
||||
// - centering ribbons
|
||||
// returns:
|
||||
// - null - empty ribbon or no element greater id should be first
|
||||
// - element
|
||||
// XXX do we need to make ids numbers for this to work?
|
||||
function getImageBefore_lin(id, ribbon){
|
||||
// walk the ribbon till we find two images one with an ID less and
|
||||
// another greater that id...
|
||||
id = parseInt(id)
|
||||
var images = ribbon.children('.image')
|
||||
var prev = null
|
||||
for(var i=0; i < images.length; i++){
|
||||
if(parseInt($(images[i]).attr('id')) > id){
|
||||
return prev
|
||||
}
|
||||
prev = $(images[i])
|
||||
}
|
||||
return prev
|
||||
}
|
||||
|
||||
|
||||
// generic binery search for element just before the id...
|
||||
// NOTE: if id is in lst, this will return the element just before it.
|
||||
// NOTE: lst must be sorted.
|
||||
function binarySearch(id, lst, get){
|
||||
if(get == null){
|
||||
get = function(o){return o}
|
||||
}
|
||||
|
||||
// empty list...
|
||||
if(lst.length == 0){
|
||||
return null
|
||||
}
|
||||
|
||||
// current section length
|
||||
var l = Math.round((lst.length-1)/2)
|
||||
// current position...
|
||||
var i = l
|
||||
|
||||
while(true){
|
||||
var i_id = get(lst[i])
|
||||
// beginning of the array...
|
||||
if(i == 0){
|
||||
if(id > i_id){
|
||||
return i
|
||||
}
|
||||
return null
|
||||
}
|
||||
// we got a hit...
|
||||
if(i_id == id){
|
||||
return i-1
|
||||
}
|
||||
// we are at the end...
|
||||
if(i == lst.length-1 && id > i_id){
|
||||
return i
|
||||
}
|
||||
var ii_id = get(lst[i+1])
|
||||
// test if id is between i and i+1...
|
||||
if( i_id < id && id < ii_id ){
|
||||
return i
|
||||
}
|
||||
// prepare for next iteration...
|
||||
// NOTE: we saturate the values so we will never get out of bounds.
|
||||
l = Math.round(l/2)
|
||||
if(id < i_id){
|
||||
// lower half...
|
||||
i = Math.max(0, i-l)
|
||||
} else {
|
||||
// upper half...
|
||||
i = Math.min(i+l, lst.length-1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// wrapper around binarySearch.
|
||||
// this is here to make binarySearch simpler to test and debug...
|
||||
function getImageBefore_bin(id, ribbon){
|
||||
var images = ribbon.children('.image')
|
||||
var i = binarySearch(
|
||||
parseInt(id),
|
||||
images,
|
||||
function(o){return parseInt($(o).attr('id'))})
|
||||
if(i == null){
|
||||
return null
|
||||
}
|
||||
return $(images[i])
|
||||
}
|
||||
|
||||
// set the default search...
|
||||
var getImageBefore = getImageBefore_bin
|
||||
|
||||
|
||||
|
||||
/********************************************************** Actions **/
|
||||
// basic actions...
|
||||
// NOTE: below 'direction' argument is meant in the html sence,
|
||||
@ -670,7 +681,6 @@ function mergeRibbons(direction){
|
||||
.insertAfter(prev_elem)
|
||||
}
|
||||
}
|
||||
|
||||
// animate...
|
||||
$('.current.ribbon')[direction]('.ribbon')
|
||||
.slideUp(function(){
|
||||
|
||||
@ -13,12 +13,12 @@
|
||||
z-index: 9000;
|
||||
}
|
||||
|
||||
|
||||
.loading * {
|
||||
color: gray;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.image {
|
||||
float: left;
|
||||
|
||||
|
||||
@ -47,6 +47,7 @@ function setup(){
|
||||
|
||||
// XXX
|
||||
setBackgroundMode('dark')
|
||||
enableTransitions()
|
||||
|
||||
// setup event handlers...
|
||||
setupEvents()
|
||||
|
||||
@ -1,11 +1,3 @@
|
||||
.animated {
|
||||
-webkit-transition: all 0.2s ease;
|
||||
-moz-transition: all 0.2s ease;
|
||||
-o-transition: all 0.2s ease;
|
||||
-ms-transition: all 0.2s ease;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.unanimated {
|
||||
-webkit-transition: none;
|
||||
-moz-transition: none;
|
||||
@ -14,74 +6,19 @@
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.image {
|
||||
-webkit-transition: all 0.2s ease;
|
||||
-moz-transition: all 0.2s ease;
|
||||
-o-transition: all 0.2s ease;
|
||||
-ms-transition: all 0.2s ease;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.demo-buttons {
|
||||
-webkit-transition: all 0.2s ease;
|
||||
-moz-transition: all 0.2s ease;
|
||||
-o-transition: all 0.2s ease;
|
||||
-ms-transition: all 0.2s ease;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.viewer {
|
||||
.animated,
|
||||
/* mostly to animate the background... */
|
||||
-webkit-transition: all 0.2s ease;
|
||||
-moz-transition: all 0.2s ease;
|
||||
-o-transition: all 0.2s ease;
|
||||
-ms-transition: all 0.2s ease;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
|
||||
.controller, .controller-mini {
|
||||
-webkit-transition: all 0.2s ease;
|
||||
-moz-transition: all 0.2s ease;
|
||||
-o-transition: all 0.2s ease;
|
||||
-ms-transition: all 0.2s ease;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.container {
|
||||
-webkit-transition: all 0.2s ease;
|
||||
-moz-transition: all 0.2s ease;
|
||||
-o-transition: all 0.2s ease;
|
||||
-ms-transition: all 0.2s ease;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
|
||||
.field {
|
||||
-webkit-transition: all 0.2s ease;
|
||||
-moz-transition: all 0.2s ease;
|
||||
-o-transition: all 0.2s ease;
|
||||
-ms-transition: all 0.2s ease;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.ribbon {
|
||||
-webkit-transition: all 0.2s ease;
|
||||
-moz-transition: all 0.2s ease;
|
||||
-o-transition: all 0.2s ease;
|
||||
-ms-transition: all 0.2s ease;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.new-ribbon {
|
||||
-webkit-transition: all 0.2s ease;
|
||||
-moz-transition: all 0.2s ease;
|
||||
-o-transition: all 0.2s ease;
|
||||
-ms-transition: all 0.2s ease;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.current.ribbon {
|
||||
.transitions-enabled.viewer,
|
||||
/* now the normal stuff */
|
||||
.transitions-enabled .image,
|
||||
.transitions-enabled .demo-buttons,
|
||||
.transitions-enabled .controller,
|
||||
.transitions-enabled .controller-mini,
|
||||
.transitions-enabled .container,
|
||||
.transitions-enabled .field,
|
||||
.transitions-enabled .ribbon,
|
||||
.transitions-enabled .new-ribbon,
|
||||
.transitions-enabled .current.ribbon {
|
||||
-webkit-transition: all 0.2s ease;
|
||||
-moz-transition: all 0.2s ease;
|
||||
-o-transition: all 0.2s ease;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user