mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-10-31 03:10:07 +00:00 
			
		
		
		
	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:
		
							parent
							
								
									26c9b8db2f
								
							
						
					
					
						commit
						e2931cf62a
					
				| @ -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) | ||||||
|  | |||||||
| @ -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; | ||||||
|  | |||||||
| @ -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 | ||||||
| 	}, | 	}, | ||||||
|  | |||||||
| @ -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
 | ||||||
|  | |||||||
| @ -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', | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user