added partial ribbon loading feature (needs revision) + several tweaks and fixes...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2014-10-29 23:38:27 +03:00
parent 26c9b8db2f
commit e2931cf62a
5 changed files with 166 additions and 46 deletions

View File

@ -1452,8 +1452,6 @@ module.DataPrototype = {
// NOTE: this will not affect the original data object... // NOTE: this will not affect the original data object...
// NOTE: this may result in empty ribbons... // NOTE: this may result in empty ribbons...
// NOTE: this will not crop the .order... // NOTE: this will not crop the .order...
//
// XXX should this link to .root and .parent data???
crop: function(list, flatten){ crop: function(list, flatten){
var crop = this.clone() var crop = this.clone()
list = crop.makeSparseImages(list) list = crop.makeSparseImages(list)

View File

@ -60,7 +60,7 @@
} }
/* basic animation... */ /* basic animation... */
.viewer:not(.no-transitions) .ribbon-set { .viewer:not(.no-transitions) .ribbon-set:not(.no-transitions) {
-webkit-transition: all 0.2s linear, transform 0.2s linear; -webkit-transition: all 0.2s linear, transform 0.2s linear;
-moz-transition: all 0.2s linear, transform 0.2s linear; -moz-transition: all 0.2s linear, transform 0.2s linear;
-ms-transition: all 0.2s linear, transform 0.2s linear; -ms-transition: all 0.2s linear, transform 0.2s linear;
@ -68,7 +68,7 @@
transition: all 0.2s linear, transform 0.2s linear; transition: all 0.2s linear, transform 0.2s linear;
} }
.viewer:not(.no-transitions) .ribbon { .viewer:not(.no-transitions) .ribbon:not(.no-transitions) {
-webkit-transition: all 0.2s ease-out; -webkit-transition: all 0.2s ease-out;
-moz-transition: all 0.2s ease-out; -moz-transition: all 0.2s ease-out;
-ms-transition: all 0.2s ease-out; -ms-transition: all 0.2s ease-out;

View File

@ -127,43 +127,55 @@ module.RibbonsPrototype = {
// Helpers... // Helpers...
// XXX need a better way of doing this... // XXX need a better way of doing this...
preventTransitions: function(){ preventTransitions: function(target){
this.viewer.addClass('no-transitions') target = target || this.viewer
var v = this.viewer[0] target.addClass('no-transitions')
getComputedStyle(v).webkitTransition var t = target[0]
getComputedStyle(v).mozTransition getComputedStyle(t).webkitTransition
getComputedStyle(v).msTransition getComputedStyle(t).mozTransition
getComputedStyle(v).oTransition getComputedStyle(t).msTransition
getComputedStyle(v).transition getComputedStyle(t).oTransition
getComputedStyle(t).transition
return this
}, },
restoreTransitions: function(now){ restoreTransitions: function(target, now){
if(target === true || target === false){
now = target
target = this.viewer
} else {
target = target || this.viewer
}
// sync... // sync...
if(now){ if(now){
this.viewer.removeClass('no-transitions') target.removeClass('no-transitions')
var v = this.viewer[0] var t = target[0]
getComputedStyle(v).webkitTransition getComputedStyle(t).webkitTransition
getComputedStyle(v).mozTransition getComputedStyle(t).mozTransition
getComputedStyle(v).msTransition getComputedStyle(t).msTransition
getComputedStyle(v).oTransition getComputedStyle(t).oTransition
getComputedStyle(v).transition getComputedStyle(t).transition
// on next exec frame... // on next exec frame...
} else { } else {
var that = this var that = this
setTimeout(function(){ setTimeout(function(){
that.viewer.removeClass('no-transitions')}, 0) target.removeClass('no-transitions')}, 0)
var v = that.viewer[0] var t = target[0]
getComputedStyle(v).webkitTransition getComputedStyle(t).webkitTransition
getComputedStyle(v).mozTransition getComputedStyle(t).mozTransition
getComputedStyle(v).msTransition getComputedStyle(t).msTransition
getComputedStyle(v).oTransition getComputedStyle(t).oTransition
getComputedStyle(v).transition getComputedStyle(t).transition
} }
return this
}, },
noTransitions: function(func){ noTransitions: function(func){
this.preventTransitions() this.preventTransitions()
func.apply(this, args2array(arguments).slice(1)) func.apply(this, args2array(arguments).slice(1))
this.restoreTransitions(true) this.restoreTransitions(true)
return this
}, },
@ -927,12 +939,18 @@ module.RibbonsPrototype = {
// This will reuse the images that already exist, thus if updating or // This will reuse the images that already exist, thus if updating or
// adding images to an already loaded set this should be very fast. // adding images to an already loaded set this should be very fast.
// //
// NOTE: gids and ribbon must be .getImage(..) and .getRibbon(..) // If reference is given then this will compensate ribbon offset to
// compatible... // keep the reference image in the same position (XXX ???)
// //
// XXX at this point this expects gids to be a list of gids, need // gids must be a list of gids.
// to make this compatible with jQuery collections... //
updateRibbon: function(gids, ribbon){ // ribbons must be .getRibbon(..) compatible.
//
// reference must be .getImage(..) compatible.
//
// XXX should this compensate for load offset???
// XXX need to make this animation-neutral...
updateRibbon: function(gids, ribbon, reference){
var that = this var that = this
// get/create the ribbon... // get/create the ribbon...
var r = this.getRibbon(ribbon) var r = this.getRibbon(ribbon)
@ -942,17 +960,40 @@ module.RibbonsPrototype = {
} }
var loaded = r.find('.image') var loaded = r.find('.image')
var unload = $()
// compensate for new/removed images...
// XXX need to make this animation-neutral...
if(reference != null){
var ref = this.getImage(reference)
// align only if ref is loaded...
// XXX
if(ref.length > 0){
var gid = this.getElemGID(ref)
var w = ref.outerWidth()
// calculate offset...
// NOTE: this will not work for non-square images...
var dl = loaded.index(ref) - gids.indexOf(gid)
if(dl != 0){
r.css({left: parseFloat(r.css('left')) + dl * w})
}
}
}
// remove all images that we do not need... // remove all images that we do not need...
loaded = loaded loaded = loaded
.filter(function(i, img){ .filter(function(i, img){
// XXX .indexOf(..) will not work for a jQuery collection...
if(gids.indexOf(that.getElemGID($(img))) >= 0){ if(gids.indexOf(that.getElemGID($(img))) >= 0){
return true return true
} }
$(img).remove() unload.push(img)
return false return false
}) })
// remove everything in one go...
unload.remove()
$(gids).each(function(i, gid){ $(gids).each(function(i, gid){
// support for sparse ribbons... // support for sparse ribbons...
@ -990,11 +1031,12 @@ module.RibbonsPrototype = {
that.updateImage(img) that.updateImage(img)
}) })
/*
// remove the rest of the stuff in ribbon... // remove the rest of the stuff in ribbon...
if(loaded.length > gids.length){ if(loaded.length > gids.length){
loaded.eq(gids.length).nextAll().remove() loaded.eq(gids.length-1).nextAll().remove()
loaded.eq(gids.length).remove()
} }
*/
return this return this
}, },

View File

@ -172,6 +172,7 @@ $(function(){
//viewer.RibbonAlignToFirst.setup(a) //viewer.RibbonAlignToFirst.setup(a)
viewer.ShiftAnimation.setup(a) viewer.ShiftAnimation.setup(a)
viewer.BoundsIndicators.setup(a) viewer.BoundsIndicators.setup(a)
viewer.PartialRibbons.setup(a)
// this publishes all the actions... // this publishes all the actions...
//module.GLOBAL_KEYBOARD.__proto__ = a //module.GLOBAL_KEYBOARD.__proto__ = a

View File

@ -540,7 +540,7 @@ actions.Actions(Client, {
: data.getImage(target) : data.getImage(target)
// align current ribbon... // align current ribbon...
ribbons this
.centerRibbon(gid) .centerRibbon(gid)
.centerImage(gid) .centerImage(gid)
@ -565,9 +565,9 @@ actions.Actions(Client, {
if(f == null){ if(f == null){
continue continue
} }
ribbons.centerImage(f, 'before') this.centerImage(f, 'before')
} else { } else {
ribbons.centerImage(t, 'after') this.centerImage(t, 'after')
} }
} }
}], }],
@ -585,7 +585,7 @@ actions.Actions(Client, {
: data.getImage(target) : data.getImage(target)
// align current ribbon... // align current ribbon...
ribbons this
.centerRibbon(gid) .centerRibbon(gid)
.centerImage(gid) .centerImage(gid)
@ -607,20 +607,28 @@ actions.Actions(Client, {
if(f == null){ if(f == null){
continue continue
} }
ribbons.centerImage(f, 'before') this.centerImage(f, 'before')
} }
}], }],
// NOTE: this will align only a single image... // NOTE: this will align only a single image...
centerImage: ['Center image', // XXX do we need these low level primitives here???
centerImage: ['Center an image in ribbon horizontally',
function(target, align){
target = target instanceof jQuery
? this.ribbons.getElemGID(target)
: target
// align current ribbon...
this.ribbons.centerImage(target, align)
}],
centerRibbon: ['Center a ribbon vertically',
function(target){ function(target){
target = target instanceof jQuery target = target instanceof jQuery
? this.ribbons.getElemGID(target) ? this.ribbons.getElemGID(target)
: target : target
// align current ribbon... // align current ribbon...
this.ribbons this.ribbons.centerRibbon(target)
.centerRibbon(target)
.centerImage(target)
}], }],
// XXX skip invisible ribbons (???) // XXX skip invisible ribbons (???)
@ -897,6 +905,73 @@ function Feature(obj){
// XXX revise...
var PartialRibbons =
module.PartialRibbons = Feature({
tag: 'ui-partial-ribbons',
// number of screen widths to load...
size: 5,
// number of screen widths to edge to trigger reload...
threshold: 1,
setup: function(actions){
var feature = this
var updateRibbon = function(target, w){
target = target instanceof jQuery
? this.ribbons.getElemGID(target)
: this.data.getImage(target)
w = w || this.screenwidth
var s = feature.size * w
var t = feature.threshold * w
// next/prev loaded...
var nl = this.ribbons.getImage(target).nextAll('.image').length
var pl = this.ribbons.getImage(target).prevAll('.image').length
// next/prev available...
var na = this.data.getImages(target, s/2, 'after').length - 1
var pa = this.data.getImages(target, s/2, 'before').length - 1
// the target is not loaded...
if(this.ribbons.getImage(target).length == 0
// passed threshold on the right...
|| (nl < t && na > nl)
// passed threshold on the left...
|| (pl < t && pa > pl)
// loaded more than we need by threshold...
|| nl + pl + 1 > s + t){
// localize transition prevention...
// NOTE: we can't get ribbon via target directly here as
// the target might not be loaded...
var r = this.ribbons.getRibbon(this.data.getRibbon(target))
this.ribbons
.preventTransitions(r)
.updateRibbon(
this.data.getImages(target, s),
this.data.getRibbon(target),
target)
.restoreTransitions(r, true)
}
}
return actions
.on('focusImage.pre centerImage.pre', this.tag, function(target){
return updateRibbon.call(this, target)
})
.on('fitImage.pre', this.tag, function(n){
return updateRibbon.call(this, 'current', n || 1)
})
},
})
// XXX need a better name... // XXX need a better name...
// XXX this should also define up/down navigation behavior... // XXX this should also define up/down navigation behavior...
var RibbonAlignToOrder = var RibbonAlignToOrder =
@ -905,6 +980,7 @@ module.RibbonAlignToOrder = Feature({
setup: function(actions){ setup: function(actions){
return actions return actions
// XXX this can be either pre or post...
.on('focusImage.post', this.tag, function(target){ .on('focusImage.post', this.tag, function(target){
this.alignByOrder(target) this.alignByOrder(target)
}) })
@ -921,6 +997,7 @@ module.RibbonAlignToFirst = Feature({
setup: function(actions){ setup: function(actions){
return actions return actions
// XXX this can be either pre or post...
.on('focusImage.post', this.tag, function(target){ .on('focusImage.post', this.tag, function(target){
this.alignByFirst(target) this.alignByFirst(target)
}) })
@ -969,6 +1046,8 @@ module.CurrentIndicator = Feature({
}) })
// XXX should we keep actions in a closure (like it is done here) or get
// them live as in PartialRibbons???
var BoundsIndicators = var BoundsIndicators =
module.BoundsIndicators = Feature({ module.BoundsIndicators = Feature({
tag: 'ui-bounds-indicators', tag: 'ui-bounds-indicators',