mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-10-31 03:10:07 +00:00 
			
		
		
		
	refactoring ribbons...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									60dbd82309
								
							
						
					
					
						commit
						055775fc2b
					
				| @ -73,123 +73,6 @@ var RIBBON = '.ribbon:not(.clone)' | |||||||
| //
 | //
 | ||||||
| //
 | //
 | ||||||
| //
 | //
 | ||||||
| /*********************************************************************/ |  | ||||||
| // Low Level dom access...
 |  | ||||||
| //
 |  | ||||||
| // XXX think if a way to manage animation timings...
 |  | ||||||
| // XXX not sure if this is the right way to go...
 |  | ||||||
| 
 |  | ||||||
| var DOMAdapter = |  | ||||||
| module.DOMAdapter = { |  | ||||||
| 	getOrigin: function(elem){ |  | ||||||
| 		var o = $(elem).origin() || [0, 0]  |  | ||||||
| 		return { left: o[0], top: o[1], } |  | ||||||
| 	}, |  | ||||||
| 	setOrigin: function(elem, left, top){ |  | ||||||
| 		return $(elem).origin(left, top, 0) |  | ||||||
| 	}, |  | ||||||
| 	setOriginSync: function(elem, x, y, z){ |  | ||||||
| 		x = x == null ? '50%' : x |  | ||||||
| 		y = y == null ? '50%' : y |  | ||||||
| 		z = z == null ? '0' : z |  | ||||||
| 		var value = x +' '+ y +' '+ z |  | ||||||
| 
 |  | ||||||
| 		elem = $(elem) |  | ||||||
| 		var e = elem[0] |  | ||||||
| 
 |  | ||||||
| 		e.style.display = 'none' |  | ||||||
| 		// now kick the browser into recognition of our changes NOW ;)
 |  | ||||||
| 		getComputedStyle(e).display |  | ||||||
| 
 |  | ||||||
| 		e.style['-o-transform-origin'] =  value |  | ||||||
| 		e.style['-ms-transform-origin'] =  value |  | ||||||
| 		e.style['-moz-transform-origin'] =  value |  | ||||||
| 		e.style['-webkit-transform-origin'] =  value |  | ||||||
| 		e.style['transform-origin'] = value |  | ||||||
| 
 |  | ||||||
| 		e.style.display = '' |  | ||||||
| 		getComputedStyle(e).display |  | ||||||
| 
 |  | ||||||
| 		return $(elem) |  | ||||||
| 	}, |  | ||||||
| 
 |  | ||||||
| 	getScale: function(elem){  |  | ||||||
| 		return $(elem).scale() || 1 }, |  | ||||||
| 	setScale: function(elem, scale){ |  | ||||||
| 		return $(elem).scale(scale || 1) }, |  | ||||||
| 
 |  | ||||||
| 	getOffset: function(elem){ |  | ||||||
| 		var o = $(elem).transform('x', 'y')  |  | ||||||
| 		return { left: o.x, top: o.y, } |  | ||||||
| 	}, |  | ||||||
| 	setOffset: function(elem, left, top){ |  | ||||||
| 		return $(elem).transform({x: left || 0, y: top || 0, z: 0})  |  | ||||||
| 	}, |  | ||||||
| 
 |  | ||||||
| 	shiftOrigin: function(elem, left, top, scale){ |  | ||||||
| 		var o = this.getOrigin(elem) |  | ||||||
| 		var scale = scale || this.getScale(elem) |  | ||||||
| 		var offset = this.getOffset(elem) |  | ||||||
| 
 |  | ||||||
| 		// calculate the offset change and compensate...
 |  | ||||||
| 		var cl = offset.left + ((o.left - o.left*scale) - (left - left*scale)) |  | ||||||
| 		var ct = offset.top + ((o.top - o.top*scale) - (top - top*scale)) |  | ||||||
| 
 |  | ||||||
| 		this.setOffset(elem, cl, ct) |  | ||||||
| 
 |  | ||||||
| 		return this.setOriginSync(elem, left+'px', top+'px') |  | ||||||
| 	}, |  | ||||||
| 	// see docs in jli.js
 |  | ||||||
| 	relativeOffset: function(container, block, point){ |  | ||||||
| 		point = point == null ? {} : point |  | ||||||
| 		var l = point.left |  | ||||||
| 		var t = point.top |  | ||||||
| 		var scale = point.scale |  | ||||||
| 
 |  | ||||||
| 		// get the input data...
 |  | ||||||
| 		var s = this.getScale(block) || 1 |  | ||||||
| 		var o = this.getOrigin(block) |  | ||||||
| 		// get only the value we need...
 |  | ||||||
| 		var W = container.width() |  | ||||||
| 		var H = container.height() |  | ||||||
| 		// we need this to make everything relative to the container...
 |  | ||||||
| 		var co = container.offset() |  | ||||||
| 		var offset = this.getOffset(block) |  | ||||||
| 		var bo = block.offset() |  | ||||||
| 
 |  | ||||||
| 		scale = scale == 'screen' ? 1  |  | ||||||
| 			: scale == 'elem' ? s |  | ||||||
| 			: scale == null ? s |  | ||||||
| 			: scale |  | ||||||
| 
 |  | ||||||
| 		// normalize the l,t to element scale...
 |  | ||||||
| 		if(l != null && t != null){ |  | ||||||
| 
 |  | ||||||
| 			// get only the value we need...
 |  | ||||||
| 			// NOTE: width and height are used to calculate the correction
 |  | ||||||
| 			//		due to origin/scale...
 |  | ||||||
| 			var w = block.width() |  | ||||||
| 			var h = block.height() |  | ||||||
| 			o = { |  | ||||||
| 				// target offset scale...
 |  | ||||||
| 				top: t*scale  |  | ||||||
| 					// set origin to top left corner of element (compensate
 |  | ||||||
| 					// for scaling)...
 |  | ||||||
| 					+ (h - h*s) / (h / o.top),  |  | ||||||
| 				left: l*scale  |  | ||||||
| 					+ (w - w*s) / (w / o.left), |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		return { |  | ||||||
| 			top: offset.top + (H/2 - offset.top) - o.top, |  | ||||||
| 			left: offset.left + (W/2 - offset.left) - o.left, |  | ||||||
| 		} |  | ||||||
| 	}, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /*********************************************************************/ | /*********************************************************************/ | ||||||
| 
 | 
 | ||||||
| var RibbonsClassPrototype = { | var RibbonsClassPrototype = { | ||||||
| @ -278,8 +161,10 @@ var RibbonsClassPrototype = { | |||||||
| }  | }  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| // NOTE: this is a low level interface, not a set of actions...
 | 
 | ||||||
| var RibbonsPrototype = { | //---------------------------------------------------------------------
 | ||||||
|  | 	 | ||||||
|  | var IntrospectiveRibbonsPrototype = { | ||||||
| 	//
 | 	//
 | ||||||
| 	//	.viewer (jQuery object)
 | 	//	.viewer (jQuery object)
 | ||||||
| 	//
 | 	//
 | ||||||
| @ -292,23 +177,6 @@ var RibbonsPrototype = { | |||||||
| 		this.images = images | 		this.images = images | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	// XXX
 |  | ||||||
| 	clone: function(){ |  | ||||||
| 		var o = new this.constructor() |  | ||||||
| 		if(this.viewer){ |  | ||||||
| 			// XXX does this completely detach from the orriginal???
 |  | ||||||
| 			// XXX do we need to reattach something???
 |  | ||||||
| 			o.viewer = this.viewer.clone() |  | ||||||
| 		} |  | ||||||
| 		if(this.images){ |  | ||||||
| 			o.images = this.images.clone() |  | ||||||
| 		} |  | ||||||
| 		return o |  | ||||||
| 	}, |  | ||||||
| 
 |  | ||||||
| 	// DOM Adapter...
 |  | ||||||
| 	dom: DOMAdapter, |  | ||||||
| 	 |  | ||||||
| 	// utils...
 | 	// utils...
 | ||||||
| 	px2v: RibbonsClassPrototype.px2v, | 	px2v: RibbonsClassPrototype.px2v, | ||||||
| 	px2vw: RibbonsClassPrototype.px2vw, | 	px2vw: RibbonsClassPrototype.px2vw, | ||||||
| @ -316,11 +184,6 @@ var RibbonsPrototype = { | |||||||
| 	px2vmin: RibbonsClassPrototype.px2vmin, | 	px2vmin: RibbonsClassPrototype.px2vmin, | ||||||
| 	px2vmax: RibbonsClassPrototype.px2vmax, | 	px2vmax: RibbonsClassPrototype.px2vmax, | ||||||
| 
 | 
 | ||||||
| 	// Constructors...
 |  | ||||||
| 	createViewer: RibbonsClassPrototype.createViewer, |  | ||||||
| 	createRibbon: RibbonsClassPrototype.createRibbon, |  | ||||||
| 	createImage: RibbonsClassPrototype.createImage, |  | ||||||
| 	createMark: RibbonsClassPrototype.createMark, |  | ||||||
| 
 | 
 | ||||||
| 	// Generic getters...
 | 	// Generic getters...
 | ||||||
| 	elemGID: RibbonsClassPrototype.elemGID, | 	elemGID: RibbonsClassPrototype.elemGID, | ||||||
| @ -351,151 +214,6 @@ var RibbonsPrototype = { | |||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	// Helpers...
 |  | ||||||
| 
 |  | ||||||
| 	// Prevent CSS transitions...
 |  | ||||||
| 	//
 |  | ||||||
| 	// 	Prevent transitions globally (.viewer):
 |  | ||||||
| 	// 	.preventTransitions()
 |  | ||||||
| 	// 		-> data
 |  | ||||||
| 	//
 |  | ||||||
| 	// 	Prevent transitions on elem:
 |  | ||||||
| 	// 	.preventTransitions(elem)
 |  | ||||||
| 	// 		-> data
 |  | ||||||
| 	//
 |  | ||||||
| 	//
 |  | ||||||
| 	// NOTE: this will set a .no-transitions CSS class and force 
 |  | ||||||
| 	// 		recalculation on the given element
 |  | ||||||
| 	// NOTE: for this to have effect proper CSS configuration is needed.
 |  | ||||||
| 	preventTransitions: function(target){ |  | ||||||
| 		target = target || this.viewer |  | ||||||
| 		//prevent_nested = prevent_nested || false
 |  | ||||||
| 		if(target.length == 0){ |  | ||||||
| 			return this |  | ||||||
| 		} |  | ||||||
| 		var t = target[0] |  | ||||||
| 
 |  | ||||||
| 		// handle nesting...
 |  | ||||||
| 		var l = t.getAttribute('__prevent_transitions') |  | ||||||
| 		if(l != null){ |  | ||||||
| 			t.setAttribute('__prevent_transitions', parseInt(l)+1) |  | ||||||
| 			return this |  | ||||||
| 		} |  | ||||||
| 		t.setAttribute('__prevent_transitions', 0) |  | ||||||
| 
 |  | ||||||
| 		target.addClass('no-transitions') |  | ||||||
| 
 |  | ||||||
| 		var s = getComputedStyle(t) |  | ||||||
| 		s.webkitTransition |  | ||||||
| 		s.mozTransition |  | ||||||
| 		s.msTransition |  | ||||||
| 		s.oTransition |  | ||||||
| 		s.transition |  | ||||||
| 
 |  | ||||||
| 		return this |  | ||||||
| 	}, |  | ||||||
| 
 |  | ||||||
| 	// Restore CSS transitions...
 |  | ||||||
| 	//
 |  | ||||||
| 	// This is a companion to .preventTransitions(..)
 |  | ||||||
| 	//
 |  | ||||||
| 	// 	Restore transitions globally (.viewer):
 |  | ||||||
| 	// 	.restoreTransitions()
 |  | ||||||
| 	// 		-> data
 |  | ||||||
| 	//
 |  | ||||||
| 	// 	Restore transitions on elem: 
 |  | ||||||
| 	// 	.restoreTransitions(elem)
 |  | ||||||
| 	// 		-> data
 |  | ||||||
| 	//
 |  | ||||||
| 	// 	Restore transitions on elem (force sync): 
 |  | ||||||
| 	// 	.restoreTransitions(elem, true)
 |  | ||||||
| 	// 		-> data
 |  | ||||||
| 	//
 |  | ||||||
| 	// 	Force restore transitions: 
 |  | ||||||
| 	// 	.restoreTransitions(.., .., true)
 |  | ||||||
| 	// 		-> data
 |  | ||||||
| 	//
 |  | ||||||
| 	// When at least one .preventTransitions(..) is called with 
 |  | ||||||
| 	// prevent_nested set to true, this will be a no-op on all nested
 |  | ||||||
| 	// levels.
 |  | ||||||
| 	// This can be overridden via setting the force to true.
 |  | ||||||
| 	//
 |  | ||||||
| 	// NOTE: the implementation of this method might seem ugly, but the 
 |  | ||||||
| 	// 		code is speed-critical, thus we access the DOM directly and
 |  | ||||||
| 	// 		the two branches are unrolled...
 |  | ||||||
| 	restoreTransitions: function(target, now, force){ |  | ||||||
| 		if(target === true || target === false){ |  | ||||||
| 			now = target |  | ||||||
| 			target = this.viewer |  | ||||||
| 		} else { |  | ||||||
| 			target = target || this.viewer |  | ||||||
| 		} |  | ||||||
| 		if(target.length == 0){ |  | ||||||
| 			return this |  | ||||||
| 		} |  | ||||||
| 		var t = target[0] |  | ||||||
| 
 |  | ||||||
| 		// sync...
 |  | ||||||
| 		if(now){ |  | ||||||
| 			// handle nesting...
 |  | ||||||
| 			var l = t.getAttribute('__prevent_transitions') |  | ||||||
| 			if(l != null && !force && l != '0'){ |  | ||||||
| 				t.setAttribute('__prevent_transitions', parseInt(l)-1) |  | ||||||
| 				return this |  | ||||||
| 			} |  | ||||||
| 			t.removeAttribute('__prevent_transitions') |  | ||||||
| 
 |  | ||||||
| 			target.removeClass('no-transitions') |  | ||||||
| 
 |  | ||||||
| 			var s = getComputedStyle(t) |  | ||||||
| 			s.webkitTransition |  | ||||||
| 			s.mozTransition |  | ||||||
| 			s.msTransition |  | ||||||
| 			s.oTransition |  | ||||||
| 			s.transition |  | ||||||
| 
 |  | ||||||
| 		// on next exec frame...
 |  | ||||||
| 		} else { |  | ||||||
| 			var that = this |  | ||||||
| 			setTimeout(function(){ |  | ||||||
| 				// handle nesting...
 |  | ||||||
| 				var l = t.getAttribute('__prevent_transitions') |  | ||||||
| 				if(l != null && !force && l != '0'){ |  | ||||||
| 					t.setAttribute('__prevent_transitions', l-1) |  | ||||||
| 					return this |  | ||||||
| 				} |  | ||||||
| 				t.removeAttribute('__prevent_transitions') |  | ||||||
| 
 |  | ||||||
| 				target.removeClass('no-transitions') |  | ||||||
| 
 |  | ||||||
| 				var s = getComputedStyle(t) |  | ||||||
| 				s.webkitTransition |  | ||||||
| 				s.mozTransition |  | ||||||
| 				s.msTransition |  | ||||||
| 				s.oTransition |  | ||||||
| 				s.transition |  | ||||||
| 			}, 0) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		return this |  | ||||||
| 	}, |  | ||||||
| 
 |  | ||||||
| 	// Shorthand wrappers of the above...
 |  | ||||||
| 	//
 |  | ||||||
| 	// XXX do we need custom target support here???
 |  | ||||||
| 	noTransitions: function(func){ |  | ||||||
| 		this.preventTransitions() |  | ||||||
| 		func.apply(this, args2array(arguments).slice(1)) |  | ||||||
| 		this.restoreTransitions(true) |  | ||||||
| 		return this |  | ||||||
| 	}, |  | ||||||
| 	noTransitionsDeep: function(func){ |  | ||||||
| 		this.preventTransitions(null, true) |  | ||||||
| 		func.apply(this, args2array(arguments).slice(1)) |  | ||||||
| 		this.restoreTransitions(true) |  | ||||||
| 		return this |  | ||||||
| 	}, |  | ||||||
| 
 |  | ||||||
| 	// Scale...
 | 	// Scale...
 | ||||||
| 	//
 | 	//
 | ||||||
| 	// 	Get scale...
 | 	// 	Get scale...
 | ||||||
| @ -512,7 +230,7 @@ var RibbonsPrototype = { | |||||||
| 	scale: function(scale){ | 	scale: function(scale){ | ||||||
| 		// get...
 | 		// get...
 | ||||||
| 		if(arguments.length == 0){ | 		if(arguments.length == 0){ | ||||||
| 			return this.dom.getScale(this.getRibbonSet()) || 1 | 			return this.getRibbonSet().scale() || 1 | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// set...
 | 		// set...
 | ||||||
| @ -522,52 +240,11 @@ var RibbonsPrototype = { | |||||||
| 			return this | 			return this | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		this.dom.setScale(ribbon_set, scale) | 		ribbon_set.scale(scale) | ||||||
| 
 | 
 | ||||||
| 		return this | 		return this | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	// Rotate...
 |  | ||||||
| 	//
 |  | ||||||
| 	//	Get ribbon rotation angle...
 |  | ||||||
| 	//	.rotate()
 |  | ||||||
| 	//		-> angle
 |  | ||||||
| 	//
 |  | ||||||
| 	//	Rotate to angle...
 |  | ||||||
| 	//	.rotate(20)
 |  | ||||||
| 	//	.rotate(-10)
 |  | ||||||
| 	//		-> ribbons
 |  | ||||||
| 	//
 |  | ||||||
| 	//	Rotate by angle...
 |  | ||||||
| 	//	.rotate('-=20')
 |  | ||||||
| 	//	.rotate('+=30')
 |  | ||||||
| 	//		-> ribbons
 |  | ||||||
| 	//
 |  | ||||||
| 	// NOTE: the angles are not base 360 normalised...
 |  | ||||||
| 	// NOTE: units are ignored and the final angle is always in deg.
 |  | ||||||
| 	rotate: function(angle){ |  | ||||||
| 		// get...
 |  | ||||||
| 		if(arguments.length == 0){ |  | ||||||
| 			return this.getRibbonSet().rotate() |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		// set...
 |  | ||||||
| 		var ribbon_set = this.getRibbonSet()   |  | ||||||
| 
 |  | ||||||
| 		if(ribbon_set.length == 0){ |  | ||||||
| 			return this |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		angle = typeof(angle) == typeof('str') |  | ||||||
| 			? (/^\+=/.test(angle) ? (ribbon_set.rotate() || 0) + parseFloat(angle.slice(2)) |  | ||||||
| 				:/^\-=/.test(angle) ? (ribbon_set.rotate() || 0) - parseFloat(angle.slice(2)) |  | ||||||
| 				: parseFloat(angle)) |  | ||||||
| 			: angle |  | ||||||
| 
 |  | ||||||
| 		ribbon_set.rotate(angle) |  | ||||||
| 
 |  | ||||||
| 		return this |  | ||||||
| 	}, |  | ||||||
| 
 | 
 | ||||||
| 	// Get visible image tile size...
 | 	// Get visible image tile size...
 | ||||||
| 	//
 | 	//
 | ||||||
| @ -667,154 +344,6 @@ var RibbonsPrototype = { | |||||||
| 		return H/h | 		return H/h | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	// Make a "shadow" image for use with image oriented animations...
 |  | ||||||
| 	//
 |  | ||||||
| 	//	.makeShadow([<image>][, <animate>][, <delay>])
 |  | ||||||
| 	//		-> <finalize>
 |  | ||||||
| 	//
 |  | ||||||
| 	// A shadow is a clone of <image> placed directly above it while it 
 |  | ||||||
| 	// is hidden (transparent), calling <finalize> will remove the shadwo
 |  | ||||||
| 	// and restore the original image, if <animate> is set then the shadow
 |  | ||||||
| 	// will be moved to the image location, and <delay> sets the time delay
 |  | ||||||
| 	// to provision for shadow animations.
 |  | ||||||
| 	//
 |  | ||||||
| 	// <finalize> is a function, that when called will remove the shadow
 |  | ||||||
| 	// and restore image state.
 |  | ||||||
| 	//
 |  | ||||||
| 	// <image> is the target image to clone
 |  | ||||||
| 	//
 |  | ||||||
| 	// <animate> if is set, <finalize> will shift the shadow to target 
 |  | ||||||
| 	// image offset before removing it (default: false).
 |  | ||||||
| 	//
 |  | ||||||
| 	// <delay> sets the delay before the shadow is removed and the target 
 |  | ||||||
| 	// state is restored (default: 200).
 |  | ||||||
| 	//
 |  | ||||||
| 	//
 |  | ||||||
| 	// NOTE: if a previous shadow if the same image exists this will recycle
 |  | ||||||
| 	// 		the existing shadow and cancel it's removal.
 |  | ||||||
| 	// 		...this is useful for when a second consecutive action with
 |  | ||||||
| 	// 		the same image is issued before the previous has time to
 |  | ||||||
| 	// 		complete, recycling the shadow will enable a single flowing 
 |  | ||||||
| 	// 		animation for such series of commands.
 |  | ||||||
| 	// 		Example: several fast consecutive horizontal shifts will result
 |  | ||||||
| 	// 			in a single shadow "flowing" through the ribbon.
 |  | ||||||
| 	// NOTE: multiple shadows of different images are supported...
 |  | ||||||
| 	// NOTE: the .shadow element is essentially a ribbon.
 |  | ||||||
| 	//
 |  | ||||||
| 	// XXX add duration configuration...
 |  | ||||||
| 	// XXX should we also have a ribbon shadow???
 |  | ||||||
| 	// XXX when this cant find a target it will return an empty function,
 |  | ||||||
| 	// 		not sure if this is correct...
 |  | ||||||
| 	// XXX should we use transforms instead of css positions???
 |  | ||||||
| 	makeShadow: function(target, animate, delay, start_delay){ |  | ||||||
| 		delay = delay || 200 |  | ||||||
| 		start_delay = start_delay || 10 |  | ||||||
| 
 |  | ||||||
| 		var img = this.getImage(target) |  | ||||||
| 
 |  | ||||||
| 		if(img.length == 0){ |  | ||||||
| 			// XXX is this correct???
 |  | ||||||
| 			return function(){} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		var gid = this.elemGID(img) |  | ||||||
| 		var s = this.scale() |  | ||||||
| 		var vo = this.viewer.offset() |  | ||||||
| 		var io = img.offset() |  | ||||||
| 
 |  | ||||||
| 		// get the shadow if it exists...
 |  | ||||||
| 		var shadow = this.viewer.find('.shadow[gid="'+gid+'"]') |  | ||||||
| 
 |  | ||||||
| 		// recycle the shadow...
 |  | ||||||
| 		if(shadow.length > 0){ |  | ||||||
| 			// cancel previous shadow removal ticket...
 |  | ||||||
| 			var ticket = shadow.attr('ticket') + 1 |  | ||||||
| 			shadow |  | ||||||
| 				// reset ticket...
 |  | ||||||
| 				// NOTE: this is a possible race condition... (XXX)
 |  | ||||||
| 				.attr('ticket', ticket) |  | ||||||
| 				// place it over the current image...
 |  | ||||||
| 				.css({ |  | ||||||
| 					top: io.top - vo.top, |  | ||||||
| 					left: io.left - vo.left, |  | ||||||
| 				}) |  | ||||||
| 
 |  | ||||||
| 		// create a new shadow...
 |  | ||||||
| 		} else { |  | ||||||
| 			// removal ticket...
 |  | ||||||
| 			var ticket = 0 |  | ||||||
| 
 |  | ||||||
| 			// make a shadow element...
 |  | ||||||
| 			// ...we need to scale it to the current scale...
 |  | ||||||
| 			var shadow = this.dom.setScale( |  | ||||||
| 				$('<div>') |  | ||||||
| 					.addClass('shadow ribbon clone') |  | ||||||
| 					.attr({ |  | ||||||
| 						gid: gid, |  | ||||||
| 						ticket: ticket, |  | ||||||
| 					}) |  | ||||||
| 					.append( |  | ||||||
| 						// clone the target into the shadow..
 |  | ||||||
| 						img |  | ||||||
| 							.clone() |  | ||||||
| 							.addClass('clone') |  | ||||||
| 							.removeClass('current') |  | ||||||
| 							.attr('gid', null)), |  | ||||||
| 					s) |  | ||||||
| 				// place it over the current image...
 |  | ||||||
| 				.css({ |  | ||||||
| 					top: io.top - vo.top, |  | ||||||
| 					left: io.left - vo.left, |  | ||||||
| 				}) |  | ||||||
| 				.append(this.getImageMarks(img) |  | ||||||
| 						.clone() |  | ||||||
| 						.attr('gid', null)) |  | ||||||
| 				// place in the viewer...
 |  | ||||||
| 				// NOTE: placing the shadow in the viewer is a compromise that
 |  | ||||||
| 				// 		lets us do simpler positioning 
 |  | ||||||
| 				.appendTo(this.viewer) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		img.addClass('moving') |  | ||||||
| 		var that = this |  | ||||||
| 
 |  | ||||||
| 		// function to clear the shadow...
 |  | ||||||
| 		return function(){ |  | ||||||
| 			// remove only the item with the correct ticket...
 |  | ||||||
| 			if(ticket == shadow.attr('ticket')){ |  | ||||||
| 				var s = that.scale() |  | ||||||
| 				var img = that.getImage(gid) |  | ||||||
| 				var vo = that.viewer.offset() |  | ||||||
| 				var io = img.offset() |  | ||||||
| 				if(animate){ |  | ||||||
| 					if(start_delay){ |  | ||||||
| 						setTimeout(function(){ |  | ||||||
| 							shadow.css({ |  | ||||||
| 								top: io.top - vo.top, |  | ||||||
| 								left: io.left - vo.left, |  | ||||||
| 							}) |  | ||||||
| 						}, start_delay) |  | ||||||
| 
 |  | ||||||
| 					} else { |  | ||||||
| 						shadow.css({ |  | ||||||
| 							top: io.top - vo.top, |  | ||||||
| 							left: io.left - vo.left, |  | ||||||
| 						}) |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 				setTimeout(function(){ |  | ||||||
| 					// remove only the item with the correct ticket...
 |  | ||||||
| 					if(ticket == shadow.attr('ticket')){ |  | ||||||
| 						img.removeClass('moving') |  | ||||||
| 						shadow.remove() |  | ||||||
| 					} |  | ||||||
| 				}, delay) |  | ||||||
| 			} |  | ||||||
| 			return img |  | ||||||
| 		} |  | ||||||
| 	}, |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 	// Contextual getters...
 | 	// Contextual getters...
 | ||||||
| 	 | 	 | ||||||
| 	// Get ribbon-set...
 | 	// Get ribbon-set...
 | ||||||
| @ -1139,6 +668,383 @@ var RibbonsPrototype = { | |||||||
| 		return this.viewer.find(RIBBON).index(this.getRibbon(target)) }, | 		return this.viewer.find(RIBBON).index(this.getRibbon(target)) }, | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | 	getImageRotation: function(target){ | ||||||
|  | 		return (this.getImage(target).attr('orientation') || 0)*1 }, | ||||||
|  | 	getImageFlip: function(target){ | ||||||
|  | 		return (this.getImage(target).attr('flipped') || '') | ||||||
|  | 			.split(',') | ||||||
|  | 			.map(function(e){ return e.trim() }) | ||||||
|  | 			.filter(function(e){ return e != '' }) | ||||||
|  | 	}, | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | var IntrospectiveRibbons =  | ||||||
|  | module.IntrospectiveRibbons =  | ||||||
|  | object.makeConstructor('IntrospectiveRibbons',  | ||||||
|  | 		RibbonsClassPrototype,  | ||||||
|  | 		IntrospectiveRibbonsPrototype) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------
 | ||||||
|  | 
 | ||||||
|  | // NOTE: this is a low level interface, not a set of actions...
 | ||||||
|  | var RibbonsPrototype = { | ||||||
|  | 	// XXX
 | ||||||
|  | 	clone: function(){ | ||||||
|  | 		var o = new this.constructor() | ||||||
|  | 		if(this.viewer){ | ||||||
|  | 			// XXX does this completely detach from the orriginal???
 | ||||||
|  | 			// XXX do we need to reattach something???
 | ||||||
|  | 			o.viewer = this.viewer.clone() | ||||||
|  | 		} | ||||||
|  | 		if(this.images){ | ||||||
|  | 			o.images = this.images.clone() | ||||||
|  | 		} | ||||||
|  | 		return o | ||||||
|  | 	}, | ||||||
|  | 
 | ||||||
|  | 	// Constructors...
 | ||||||
|  | 	createViewer: RibbonsClassPrototype.createViewer, | ||||||
|  | 	createRibbon: RibbonsClassPrototype.createRibbon, | ||||||
|  | 	createImage: RibbonsClassPrototype.createImage, | ||||||
|  | 	createMark: RibbonsClassPrototype.createMark, | ||||||
|  | 
 | ||||||
|  | 	// Helpers...
 | ||||||
|  | 
 | ||||||
|  | 	// Prevent CSS transitions...
 | ||||||
|  | 	//
 | ||||||
|  | 	// 	Prevent transitions globally (.viewer):
 | ||||||
|  | 	// 	.preventTransitions()
 | ||||||
|  | 	// 		-> data
 | ||||||
|  | 	//
 | ||||||
|  | 	// 	Prevent transitions on elem:
 | ||||||
|  | 	// 	.preventTransitions(elem)
 | ||||||
|  | 	// 		-> data
 | ||||||
|  | 	//
 | ||||||
|  | 	//
 | ||||||
|  | 	// NOTE: this will set a .no-transitions CSS class and force 
 | ||||||
|  | 	// 		recalculation on the given element
 | ||||||
|  | 	// NOTE: for this to have effect proper CSS configuration is needed.
 | ||||||
|  | 	preventTransitions: function(target){ | ||||||
|  | 		target = target || this.viewer | ||||||
|  | 		//prevent_nested = prevent_nested || false
 | ||||||
|  | 		if(target.length == 0){ | ||||||
|  | 			return this | ||||||
|  | 		} | ||||||
|  | 		var t = target[0] | ||||||
|  | 
 | ||||||
|  | 		// handle nesting...
 | ||||||
|  | 		var l = t.getAttribute('__prevent_transitions') | ||||||
|  | 		if(l != null){ | ||||||
|  | 			t.setAttribute('__prevent_transitions', parseInt(l)+1) | ||||||
|  | 			return this | ||||||
|  | 		} | ||||||
|  | 		t.setAttribute('__prevent_transitions', 0) | ||||||
|  | 
 | ||||||
|  | 		target.addClass('no-transitions') | ||||||
|  | 
 | ||||||
|  | 		var s = getComputedStyle(t) | ||||||
|  | 		s.webkitTransition | ||||||
|  | 		s.mozTransition | ||||||
|  | 		s.msTransition | ||||||
|  | 		s.oTransition | ||||||
|  | 		s.transition | ||||||
|  | 
 | ||||||
|  | 		return this | ||||||
|  | 	}, | ||||||
|  | 
 | ||||||
|  | 	// Restore CSS transitions...
 | ||||||
|  | 	//
 | ||||||
|  | 	// This is a companion to .preventTransitions(..)
 | ||||||
|  | 	//
 | ||||||
|  | 	// 	Restore transitions globally (.viewer):
 | ||||||
|  | 	// 	.restoreTransitions()
 | ||||||
|  | 	// 		-> data
 | ||||||
|  | 	//
 | ||||||
|  | 	// 	Restore transitions on elem: 
 | ||||||
|  | 	// 	.restoreTransitions(elem)
 | ||||||
|  | 	// 		-> data
 | ||||||
|  | 	//
 | ||||||
|  | 	// 	Restore transitions on elem (force sync): 
 | ||||||
|  | 	// 	.restoreTransitions(elem, true)
 | ||||||
|  | 	// 		-> data
 | ||||||
|  | 	//
 | ||||||
|  | 	// 	Force restore transitions: 
 | ||||||
|  | 	// 	.restoreTransitions(.., .., true)
 | ||||||
|  | 	// 		-> data
 | ||||||
|  | 	//
 | ||||||
|  | 	// When at least one .preventTransitions(..) is called with 
 | ||||||
|  | 	// prevent_nested set to true, this will be a no-op on all nested
 | ||||||
|  | 	// levels.
 | ||||||
|  | 	// This can be overridden via setting the force to true.
 | ||||||
|  | 	//
 | ||||||
|  | 	// NOTE: the implementation of this method might seem ugly, but the 
 | ||||||
|  | 	// 		code is speed-critical, thus we access the DOM directly and
 | ||||||
|  | 	// 		the two branches are unrolled...
 | ||||||
|  | 	restoreTransitions: function(target, now, force){ | ||||||
|  | 		if(target === true || target === false){ | ||||||
|  | 			now = target | ||||||
|  | 			target = this.viewer | ||||||
|  | 		} else { | ||||||
|  | 			target = target || this.viewer | ||||||
|  | 		} | ||||||
|  | 		if(target.length == 0){ | ||||||
|  | 			return this | ||||||
|  | 		} | ||||||
|  | 		var t = target[0] | ||||||
|  | 
 | ||||||
|  | 		// sync...
 | ||||||
|  | 		if(now){ | ||||||
|  | 			// handle nesting...
 | ||||||
|  | 			var l = t.getAttribute('__prevent_transitions') | ||||||
|  | 			if(l != null && !force && l != '0'){ | ||||||
|  | 				t.setAttribute('__prevent_transitions', parseInt(l)-1) | ||||||
|  | 				return this | ||||||
|  | 			} | ||||||
|  | 			t.removeAttribute('__prevent_transitions') | ||||||
|  | 
 | ||||||
|  | 			target.removeClass('no-transitions') | ||||||
|  | 
 | ||||||
|  | 			var s = getComputedStyle(t) | ||||||
|  | 			s.webkitTransition | ||||||
|  | 			s.mozTransition | ||||||
|  | 			s.msTransition | ||||||
|  | 			s.oTransition | ||||||
|  | 			s.transition | ||||||
|  | 
 | ||||||
|  | 		// on next exec frame...
 | ||||||
|  | 		} else { | ||||||
|  | 			var that = this | ||||||
|  | 			setTimeout(function(){ | ||||||
|  | 				// handle nesting...
 | ||||||
|  | 				var l = t.getAttribute('__prevent_transitions') | ||||||
|  | 				if(l != null && !force && l != '0'){ | ||||||
|  | 					t.setAttribute('__prevent_transitions', l-1) | ||||||
|  | 					return this | ||||||
|  | 				} | ||||||
|  | 				t.removeAttribute('__prevent_transitions') | ||||||
|  | 
 | ||||||
|  | 				target.removeClass('no-transitions') | ||||||
|  | 
 | ||||||
|  | 				var s = getComputedStyle(t) | ||||||
|  | 				s.webkitTransition | ||||||
|  | 				s.mozTransition | ||||||
|  | 				s.msTransition | ||||||
|  | 				s.oTransition | ||||||
|  | 				s.transition | ||||||
|  | 			}, 0) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return this | ||||||
|  | 	}, | ||||||
|  | 
 | ||||||
|  | 	// Shorthand wrappers of the above...
 | ||||||
|  | 	//
 | ||||||
|  | 	// XXX do we need custom target support here???
 | ||||||
|  | 	noTransitions: function(func){ | ||||||
|  | 		this.preventTransitions() | ||||||
|  | 		func.apply(this, args2array(arguments).slice(1)) | ||||||
|  | 		this.restoreTransitions(true) | ||||||
|  | 		return this | ||||||
|  | 	}, | ||||||
|  | 	noTransitionsDeep: function(func){ | ||||||
|  | 		this.preventTransitions(null, true) | ||||||
|  | 		func.apply(this, args2array(arguments).slice(1)) | ||||||
|  | 		this.restoreTransitions(true) | ||||||
|  | 		return this | ||||||
|  | 	}, | ||||||
|  | 
 | ||||||
|  | 	// Rotate...
 | ||||||
|  | 	//
 | ||||||
|  | 	//	Get ribbon rotation angle...
 | ||||||
|  | 	//	.rotate()
 | ||||||
|  | 	//		-> angle
 | ||||||
|  | 	//
 | ||||||
|  | 	//	Rotate to angle...
 | ||||||
|  | 	//	.rotate(20)
 | ||||||
|  | 	//	.rotate(-10)
 | ||||||
|  | 	//		-> ribbons
 | ||||||
|  | 	//
 | ||||||
|  | 	//	Rotate by angle...
 | ||||||
|  | 	//	.rotate('-=20')
 | ||||||
|  | 	//	.rotate('+=30')
 | ||||||
|  | 	//		-> ribbons
 | ||||||
|  | 	//
 | ||||||
|  | 	// NOTE: the angles are not base 360 normalised...
 | ||||||
|  | 	// NOTE: units are ignored and the final angle is always in deg.
 | ||||||
|  | 	rotate: function(angle){ | ||||||
|  | 		// get...
 | ||||||
|  | 		if(arguments.length == 0){ | ||||||
|  | 			return this.getRibbonSet().rotate() | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// set...
 | ||||||
|  | 		var ribbon_set = this.getRibbonSet()   | ||||||
|  | 
 | ||||||
|  | 		if(ribbon_set.length == 0){ | ||||||
|  | 			return this | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		angle = typeof(angle) == typeof('str') | ||||||
|  | 			? (/^\+=/.test(angle) ? (ribbon_set.rotate() || 0) + parseFloat(angle.slice(2)) | ||||||
|  | 				:/^\-=/.test(angle) ? (ribbon_set.rotate() || 0) - parseFloat(angle.slice(2)) | ||||||
|  | 				: parseFloat(angle)) | ||||||
|  | 			: angle | ||||||
|  | 
 | ||||||
|  | 		ribbon_set.rotate(angle) | ||||||
|  | 
 | ||||||
|  | 		return this | ||||||
|  | 	}, | ||||||
|  | 	 | ||||||
|  | 	// Make a "shadow" image for use with image oriented animations...
 | ||||||
|  | 	//
 | ||||||
|  | 	//	.makeShadow([<image>][, <animate>][, <delay>])
 | ||||||
|  | 	//		-> <finalize>
 | ||||||
|  | 	//
 | ||||||
|  | 	// A shadow is a clone of <image> placed directly above it while it 
 | ||||||
|  | 	// is hidden (transparent), calling <finalize> will remove the shadwo
 | ||||||
|  | 	// and restore the original image, if <animate> is set then the shadow
 | ||||||
|  | 	// will be moved to the image location, and <delay> sets the time delay
 | ||||||
|  | 	// to provision for shadow animations.
 | ||||||
|  | 	//
 | ||||||
|  | 	// <finalize> is a function, that when called will remove the shadow
 | ||||||
|  | 	// and restore image state.
 | ||||||
|  | 	//
 | ||||||
|  | 	// <image> is the target image to clone
 | ||||||
|  | 	//
 | ||||||
|  | 	// <animate> if is set, <finalize> will shift the shadow to target 
 | ||||||
|  | 	// image offset before removing it (default: false).
 | ||||||
|  | 	//
 | ||||||
|  | 	// <delay> sets the delay before the shadow is removed and the target 
 | ||||||
|  | 	// state is restored (default: 200).
 | ||||||
|  | 	//
 | ||||||
|  | 	//
 | ||||||
|  | 	// NOTE: if a previous shadow if the same image exists this will recycle
 | ||||||
|  | 	// 		the existing shadow and cancel it's removal.
 | ||||||
|  | 	// 		...this is useful for when a second consecutive action with
 | ||||||
|  | 	// 		the same image is issued before the previous has time to
 | ||||||
|  | 	// 		complete, recycling the shadow will enable a single flowing 
 | ||||||
|  | 	// 		animation for such series of commands.
 | ||||||
|  | 	// 		Example: several fast consecutive horizontal shifts will result
 | ||||||
|  | 	// 			in a single shadow "flowing" through the ribbon.
 | ||||||
|  | 	// NOTE: multiple shadows of different images are supported...
 | ||||||
|  | 	// NOTE: the .shadow element is essentially a ribbon.
 | ||||||
|  | 	//
 | ||||||
|  | 	// XXX add duration configuration...
 | ||||||
|  | 	// XXX should we also have a ribbon shadow???
 | ||||||
|  | 	// XXX when this cant find a target it will return an empty function,
 | ||||||
|  | 	// 		not sure if this is correct...
 | ||||||
|  | 	// XXX should we use transforms instead of css positions???
 | ||||||
|  | 	makeShadow: function(target, animate, delay, start_delay){ | ||||||
|  | 		delay = delay || 200 | ||||||
|  | 		start_delay = start_delay || 10 | ||||||
|  | 
 | ||||||
|  | 		var img = this.getImage(target) | ||||||
|  | 
 | ||||||
|  | 		if(img.length == 0){ | ||||||
|  | 			// XXX is this correct???
 | ||||||
|  | 			return function(){} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		var gid = this.elemGID(img) | ||||||
|  | 		var s = this.scale() | ||||||
|  | 		var vo = this.viewer.offset() | ||||||
|  | 		var io = img.offset() | ||||||
|  | 
 | ||||||
|  | 		// get the shadow if it exists...
 | ||||||
|  | 		var shadow = this.viewer.find('.shadow[gid="'+gid+'"]') | ||||||
|  | 
 | ||||||
|  | 		// recycle the shadow...
 | ||||||
|  | 		if(shadow.length > 0){ | ||||||
|  | 			// cancel previous shadow removal ticket...
 | ||||||
|  | 			var ticket = shadow.attr('ticket') + 1 | ||||||
|  | 			shadow | ||||||
|  | 				// reset ticket...
 | ||||||
|  | 				// NOTE: this is a possible race condition... (XXX)
 | ||||||
|  | 				.attr('ticket', ticket) | ||||||
|  | 				// place it over the current image...
 | ||||||
|  | 				.css({ | ||||||
|  | 					top: io.top - vo.top, | ||||||
|  | 					left: io.left - vo.left, | ||||||
|  | 				}) | ||||||
|  | 
 | ||||||
|  | 		// create a new shadow...
 | ||||||
|  | 		} else { | ||||||
|  | 			// removal ticket...
 | ||||||
|  | 			var ticket = 0 | ||||||
|  | 
 | ||||||
|  | 			// make a shadow element...
 | ||||||
|  | 			// ...we need to scale it to the current scale...
 | ||||||
|  | 			var shadow = $('<div>') | ||||||
|  | 				.addClass('shadow ribbon clone') | ||||||
|  | 				.attr({ | ||||||
|  | 					gid: gid, | ||||||
|  | 					ticket: ticket, | ||||||
|  | 				}) | ||||||
|  | 				.append( | ||||||
|  | 					// clone the target into the shadow..
 | ||||||
|  | 					img | ||||||
|  | 						.clone() | ||||||
|  | 						.addClass('clone') | ||||||
|  | 						.removeClass('current') | ||||||
|  | 						.attr('gid', null)) | ||||||
|  | 				.scale(s) | ||||||
|  | 				// place it over the current image...
 | ||||||
|  | 				.css({ | ||||||
|  | 					top: io.top - vo.top, | ||||||
|  | 					left: io.left - vo.left, | ||||||
|  | 				}) | ||||||
|  | 				.append(this.getImageMarks(img) | ||||||
|  | 						.clone() | ||||||
|  | 						.attr('gid', null)) | ||||||
|  | 				// place in the viewer...
 | ||||||
|  | 				// NOTE: placing the shadow in the viewer is a compromise that
 | ||||||
|  | 				// 		lets us do simpler positioning 
 | ||||||
|  | 				.appendTo(this.viewer) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		img.addClass('moving') | ||||||
|  | 		var that = this | ||||||
|  | 
 | ||||||
|  | 		// function to clear the shadow...
 | ||||||
|  | 		return function(){ | ||||||
|  | 			// remove only the item with the correct ticket...
 | ||||||
|  | 			if(ticket == shadow.attr('ticket')){ | ||||||
|  | 				var s = that.scale() | ||||||
|  | 				var img = that.getImage(gid) | ||||||
|  | 				var vo = that.viewer.offset() | ||||||
|  | 				var io = img.offset() | ||||||
|  | 				if(animate){ | ||||||
|  | 					if(start_delay){ | ||||||
|  | 						setTimeout(function(){ | ||||||
|  | 							shadow.css({ | ||||||
|  | 								top: io.top - vo.top, | ||||||
|  | 								left: io.left - vo.left, | ||||||
|  | 							}) | ||||||
|  | 						}, start_delay) | ||||||
|  | 
 | ||||||
|  | 					} else { | ||||||
|  | 						shadow.css({ | ||||||
|  | 							top: io.top - vo.top, | ||||||
|  | 							left: io.left - vo.left, | ||||||
|  | 						}) | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 				setTimeout(function(){ | ||||||
|  | 					// remove only the item with the correct ticket...
 | ||||||
|  | 					if(ticket == shadow.attr('ticket')){ | ||||||
|  | 						img.removeClass('moving') | ||||||
|  | 						shadow.remove() | ||||||
|  | 					} | ||||||
|  | 				}, delay) | ||||||
|  | 			} | ||||||
|  | 			return img | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 	// Basic manipulation...
 | 	// Basic manipulation...
 | ||||||
| 
 | 
 | ||||||
| 	// Place a ribbon...
 | 	// Place a ribbon...
 | ||||||
| @ -1945,8 +1851,6 @@ var RibbonsPrototype = { | |||||||
| 					.css('background-image', 'none') | 					.css('background-image', 'none') | ||||||
| 
 | 
 | ||||||
| 				// compensate for the offset...
 | 				// compensate for the offset...
 | ||||||
| 				//that.dom.setOffset(ribbon, that.dom.getOffset(ribbon).left + l)
 |  | ||||||
| 
 |  | ||||||
| 				var b = images[-left].offsetLeft | 				var b = images[-left].offsetLeft | ||||||
| 				var d = ((a - b) / W) * 100 | 				var d = ((a - b) / W) * 100 | ||||||
| 				var x = parseFloat((ribbon.transform('translate3d') || [0])[0]) + d | 				var x = parseFloat((ribbon.transform('translate3d') || [0])[0]) + d | ||||||
| @ -2024,8 +1928,6 @@ var RibbonsPrototype = { | |||||||
| 				}) | 				}) | ||||||
| 
 | 
 | ||||||
| 				// compensate for the offset...
 | 				// compensate for the offset...
 | ||||||
| 				//that.dom.setOffset(ribbon, that.dom.getOffset(ribbon).left - l)
 |  | ||||||
| 
 |  | ||||||
| 				// XXX is this the correct reference item -- can it be deleted above???
 | 				// XXX is this the correct reference item -- can it be deleted above???
 | ||||||
| 				var b = images[0].offsetLeft | 				var b = images[0].offsetLeft | ||||||
| 				var d = ((a - b) / W) * 100 | 				var d = ((a - b) / W) * 100 | ||||||
| @ -2307,10 +2209,6 @@ var RibbonsPrototype = { | |||||||
| 		return image | 		return image | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	// Get image rotation...
 |  | ||||||
| 	//
 |  | ||||||
| 	getImageRotation: function(target){ |  | ||||||
| 		return (this.getImage(target).attr('orientation') || 0)*1 }, |  | ||||||
| 	// Rotate an image...
 | 	// Rotate an image...
 | ||||||
| 	//
 | 	//
 | ||||||
| 	// Rotate image clockwise:
 | 	// Rotate image clockwise:
 | ||||||
| @ -2359,14 +2257,6 @@ var RibbonsPrototype = { | |||||||
| 		return this | 		return this | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	// Get image flip...
 |  | ||||||
| 	//
 |  | ||||||
| 	getImageFlip: function(target){ |  | ||||||
| 		return (this.getImage(target).attr('flipped') || '') |  | ||||||
| 			.split(',') |  | ||||||
| 			.map(function(e){ return e.trim() }) |  | ||||||
| 			.filter(function(e){ return e != '' }) |  | ||||||
| 	}, |  | ||||||
| 	// Flip an image...
 | 	// Flip an image...
 | ||||||
| 	//
 | 	//
 | ||||||
| 	// Flip image relative to view:
 | 	// Flip image relative to view:
 | ||||||
| @ -2650,10 +2540,9 @@ var RibbonsPrototype = { | |||||||
| 	}, | 	}, | ||||||
| }  | }  | ||||||
| 
 | 
 | ||||||
|  | RibbonsPrototype.__proto__ = IntrospectiveRibbonsPrototype | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /*********************************************************************/ |  | ||||||
| 
 |  | ||||||
| var Ribbons =  | var Ribbons =  | ||||||
| module.Ribbons =  | module.Ribbons =  | ||||||
| object.makeConstructor('Ribbons',  | object.makeConstructor('Ribbons',  | ||||||
| @ -2662,5 +2551,6 @@ object.makeConstructor('Ribbons', | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| /********************************************************************** | /********************************************************************** | ||||||
| * vim:set ts=4 sw=4 :                               */ return module }) | * vim:set ts=4 sw=4 :                               */ return module }) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user