mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-10-30 19:00:09 +00:00 
			
		
		
		
	working on a cleaner CSS3 transform editor, still not done...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									d0d2f108db
								
							
						
					
					
						commit
						32f949769f
					
				| @ -178,6 +178,8 @@ typeof(require) != 'undefined' && require('nw.gui').Window.get().showDevTools() | |||||||
| <script src="ext-lib/jquery.ui.touch-punch.min.js"></script> | <script src="ext-lib/jquery.ui.touch-punch.min.js"></script> | ||||||
| <!--script src="ext-lib/jquery.transit.min.js"></script--> | <!--script src="ext-lib/jquery.transit.min.js"></script--> | ||||||
| 
 | 
 | ||||||
|  | <script src="ext-lib/velocity.min.js"></script> | ||||||
|  | 
 | ||||||
| <script src="ext-lib/gsap/TweenLite.min.js"></script> | <script src="ext-lib/gsap/TweenLite.min.js"></script> | ||||||
| <script src="ext-lib/gsap/jquery.gsap.min.js"></script> | <script src="ext-lib/gsap/jquery.gsap.min.js"></script> | ||||||
| <script src="ext-lib/gsap/utils/Draggable.min.js"></script> | <script src="ext-lib/gsap/utils/Draggable.min.js"></script> | ||||||
|  | |||||||
| @ -156,7 +156,7 @@ Object.keys(_transform_parse).forEach(function(func){ | |||||||
| // 		-> data
 | // 		-> data
 | ||||||
| //
 | //
 | ||||||
| // Supported transformations:
 | // Supported transformations:
 | ||||||
| // 	x/y
 | // 	x/y/z
 | ||||||
| // 	scale
 | // 	scale
 | ||||||
| // 	scaleX/scaleY
 | // 	scaleX/scaleY
 | ||||||
| // 	origin
 | // 	origin
 | ||||||
| @ -164,10 +164,20 @@ Object.keys(_transform_parse).forEach(function(func){ | |||||||
| //
 | //
 | ||||||
| // NOTE: pixel values are converted to numbers and back by default...
 | // NOTE: pixel values are converted to numbers and back by default...
 | ||||||
| //
 | //
 | ||||||
|  | //
 | ||||||
|  | // XXX this should consist of:
 | ||||||
|  | // 		- transform string parser -> functions format
 | ||||||
|  | // 		- functions format generator ***
 | ||||||
|  | // 			- generate single value functions (scaleX(), translateZ(), ...)
 | ||||||
|  | // 			- optionally merge into multivalue funcs (scale(), translate3d(), ...)
 | ||||||
|  | // 		- transform string generator
 | ||||||
|  | //
 | ||||||
|  | // XXX BUG: does not work with empty initial state, i.e. without 
 | ||||||
|  | // 		transforms set...
 | ||||||
| // XXX this will get/set values only on the first element, is this correct???
 | // XXX this will get/set values only on the first element, is this correct???
 | ||||||
| // XXX how do we combine translate(..) and translate3d(..)???
 | // XXX how do we combine translate(..) and translate3d(..)???
 | ||||||
| jQuery.fn.transform = function(){ | jQuery.fn.transform = function(){ | ||||||
| 	var that = this | 	var that = $(this) | ||||||
| 	var args = args2array(arguments) | 	var args = args2array(arguments) | ||||||
| 
 | 
 | ||||||
| 	// XXX get the browser prefix...
 | 	// XXX get the browser prefix...
 | ||||||
| @ -181,8 +191,8 @@ jQuery.fn.transform = function(){ | |||||||
| 		: args | 		: args | ||||||
| 
 | 
 | ||||||
| 	var elem = $(this)[0] | 	var elem = $(this)[0] | ||||||
| 	var origin_str = elem.style[prefix + 'transformOrigin'] | 	var origin_str = elem ? elem.style[prefix + 'transformOrigin'] : '' | ||||||
| 	var transform_str = elem.style[prefix + 'transform'] | 	var transform_str = elem ? elem.style[prefix + 'transform'] : '' | ||||||
| 
 | 
 | ||||||
| 	// origin...
 | 	// origin...
 | ||||||
| 	var origin = origin_str | 	var origin = origin_str | ||||||
| @ -335,6 +345,11 @@ jQuery.fn.transform = function(){ | |||||||
| 	// set data...
 | 	// set data...
 | ||||||
| 	// 	transform -> functions
 | 	// 	transform -> functions
 | ||||||
| 	} else { | 	} else { | ||||||
|  | 		// empty elem...
 | ||||||
|  | 		if(that.length == 0){ | ||||||
|  | 			return that | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		Object.keys(args).forEach(function(arg){ | 		Object.keys(args).forEach(function(arg){ | ||||||
| 			var val = args[arg] | 			var val = args[arg] | ||||||
| 
 | 
 | ||||||
| @ -357,25 +372,37 @@ jQuery.fn.transform = function(){ | |||||||
| 						return typeof(a) != typeof('str') ? a + u : a }) | 						return typeof(a) != typeof('str') ? a + u : a }) | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 			// got an arg...
 | 			// got an arg...
 | ||||||
| 			} else if(arg in attrs){ | 			} else if(arg in attrs){ | ||||||
| 				attrs[arg](val) | 				attrs[arg](val) | ||||||
|  | 
 | ||||||
|  | 			// new arg...
 | ||||||
|  | 			} else if(arg in _transform_parse_func){ | ||||||
|  | 				_transform_parse_func[arg] | ||||||
| 			} | 			} | ||||||
| 		}) | 		}) | ||||||
| 
 | 
 | ||||||
| 		elem.style.transform = Object.keys(functions) | 		var t = Object.keys(functions) | ||||||
| 			.map(function(func){ | 			.map(function(func){ | ||||||
| 				return func +'('+ functions[func].join(', ') + ')' | 				return func +'('+ functions[func].join(', ') + ')' | ||||||
| 			}) | 			}) | ||||||
| 			.join(' ') | 			.join(' ') | ||||||
| 
 | 
 | ||||||
| 		elem.style.transformOrigin = transform['origin'] != '' ? | 		var o = (transform['origin'] && transform['origin'] != '') ? | ||||||
| 			transform['origin'] | 			transform['origin'] | ||||||
| 				.map(function(e){ | 				.map(function(e){ | ||||||
| 					return typeof(e) == typeof('str') ? e : e + 'px' | 					return typeof(e) == typeof('str') ? e : e + 'px' | ||||||
| 				}).join(' ') | 				}).join(' ') | ||||||
| 			: '' | 			: '' | ||||||
|  | 
 | ||||||
|  | 		that.css({ | ||||||
|  | 			'transform-origin': o, | ||||||
|  | 			'transform' : t,  | ||||||
|  | 		}) | ||||||
|  | 		/* | ||||||
|  | 		elem.style.transformOrigin = o | ||||||
|  | 		elem.style.transform = t | ||||||
|  | 		*/ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return $(this) | 	return $(this) | ||||||
| @ -400,6 +427,282 @@ jQuery.fn.origin = function(a, b, c){ | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // convert a transform string to an object...
 | ||||||
|  | //
 | ||||||
|  | // Format:
 | ||||||
|  | // 	{
 | ||||||
|  | // 		<func>: [<arg>, ...],
 | ||||||
|  | // 		...
 | ||||||
|  | // 	}
 | ||||||
|  | //
 | ||||||
|  | // NOTE: this does not care about the semantics of the format, just the 
 | ||||||
|  | // 		general structure...
 | ||||||
|  | var transform2obj = function(str){ | ||||||
|  | 	var res = {} | ||||||
|  | 	// parse the string...
 | ||||||
|  | 	(str || '') | ||||||
|  | 		// split functions...
 | ||||||
|  | 		.split(/(\w+\([^\)]*)\)/) | ||||||
|  | 		// remove empty strings...
 | ||||||
|  | 		.filter(function(e){ return e.trim().length > 0}) | ||||||
|  | 		// split each function...
 | ||||||
|  | 		.map(function(e){ return e | ||||||
|  | 			// split args...
 | ||||||
|  | 			.split(/\s*[\(,\s]\s*/) | ||||||
|  | 			// cleanup...
 | ||||||
|  | 			.filter(function(e){ return e.trim().length > 0 }) }) | ||||||
|  | 		// build the structure...
 | ||||||
|  | 		.forEach(function(data){ | ||||||
|  | 			var func = data.shift()  | ||||||
|  | 			var args = data | ||||||
|  | 
 | ||||||
|  | 			res[func] = data | ||||||
|  | 		}) | ||||||
|  | 	return res | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Convert the object similar in structure to the produced by 
 | ||||||
|  | // transform2obj(..) to a transform string...
 | ||||||
|  | //
 | ||||||
|  | // NOTE: this does not care about the actual semantics of the format, 
 | ||||||
|  | // 		e.g. argument units or function names...
 | ||||||
|  | var obj2transform = function(obj){ | ||||||
|  | 	return Object.keys(obj) | ||||||
|  | 		.map(function(func){ | ||||||
|  | 			return func +'('+ obj[func].join(', ') + ')' | ||||||
|  | 		}) | ||||||
|  | 		.join(' ') | ||||||
|  | }  | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // XXX BUG: passing '' to an alias will clear ALL the aliased functions...
 | ||||||
|  | // 		...should clear only full matches...
 | ||||||
|  | // XXX move the grammar out of this...
 | ||||||
|  | // XXX need:
 | ||||||
|  | // 		- a way to minimize this, i.e. get only full and minimal functions...
 | ||||||
|  | // 		- a way to get what was defined as-is...
 | ||||||
|  | var transformEditor = function(){ | ||||||
|  | 	var editor = { | ||||||
|  | 		// data set...
 | ||||||
|  | 		data: {}, | ||||||
|  | 
 | ||||||
|  | 		// function that directly edit the data...
 | ||||||
|  | 		direct: {}, | ||||||
|  | 	} | ||||||
|  | 	var func = function(name, args){ | ||||||
|  | 		args = args || [] | ||||||
|  | 		editor.direct[name] = function(val){ | ||||||
|  | 			var that = this | ||||||
|  | 			// set...
 | ||||||
|  | 			if(val != null && val != ''){ | ||||||
|  | 				val = val instanceof Array ? val : [val] | ||||||
|  | 				var res = this.data[name] = this.data[name] || [] | ||||||
|  | 				// add units and general processing...
 | ||||||
|  | 				val.map(function(arg, i){ | ||||||
|  | 					// special case, if an arg is undefined do not change it...
 | ||||||
|  | 					if(arg === undefined){ | ||||||
|  | 						return  | ||||||
|  | 					} | ||||||
|  | 					var unit = args[i] || '' | ||||||
|  | 					res[i] = typeof(arg) == typeof(123)  | ||||||
|  | 							|| (typeof(arg) == typeof('str')  | ||||||
|  | 								&& /^[0-9\.]+$/.test(arg)) ? | ||||||
|  | 						arg + unit | ||||||
|  | 						: arg | ||||||
|  | 				}) | ||||||
|  | 				return res | ||||||
|  | 
 | ||||||
|  | 			// delete...
 | ||||||
|  | 			} else if(val == ''){ | ||||||
|  | 				delete this.data[name] | ||||||
|  | 
 | ||||||
|  | 			// get...
 | ||||||
|  | 			} else { | ||||||
|  | 				var res = (this.data[name] || []) | ||||||
|  | 					// remove default unit...
 | ||||||
|  | 					.map(function(arg, i){ | ||||||
|  | 						var unit = args[i] || '' | ||||||
|  | 						return arg.slice(-unit.length) == unit  | ||||||
|  | 								|| /^[0-9\.]+$/.test(arg)? | ||||||
|  | 							parseFloat(arg) | ||||||
|  | 							: arg | ||||||
|  | 					}) | ||||||
|  | 				return res | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	var alias = function(spec){ | ||||||
|  | 		// alias runner...
 | ||||||
|  | 		var handler = function(alias, args){ | ||||||
|  | 			var that = this | ||||||
|  | 			// we only care for the source argument and only it will get
 | ||||||
|  | 			// passed next...
 | ||||||
|  | 			// NOTE: this is the name of the called alias...
 | ||||||
|  | 			var arg = args[spec[alias]] | ||||||
|  | 
 | ||||||
|  | 			return Object.keys(spec).map(function(k){ | ||||||
|  | 					var i = spec[k] | ||||||
|  | 
 | ||||||
|  | 					if(args.length == 0){ | ||||||
|  | 						return k in that.direct ?  | ||||||
|  | 							that.direct[k].call(that)  | ||||||
|  | 							: null | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					var a = [] | ||||||
|  | 					a[i] = arg | ||||||
|  | 
 | ||||||
|  | 					return k in that.direct ? | ||||||
|  | 						that.direct[k].call(that, a)  | ||||||
|  | 						: null | ||||||
|  | 				}) | ||||||
|  | 				.filter(function(e){ return e != null }) | ||||||
|  | 				.slice(-1)[0] | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// setup the aliases...
 | ||||||
|  | 		Object.keys(spec).forEach(function(k){ | ||||||
|  | 			var i = spec[k] | ||||||
|  | 
 | ||||||
|  | 			var func = i instanceof Function ? i : handler | ||||||
|  | 
 | ||||||
|  | 			// NOTE: we will pass the called alias name to the handler 
 | ||||||
|  | 			// 		via 'this'...
 | ||||||
|  | 			var f = editor[k] | ||||||
|  | 			editor[k] = f ?  | ||||||
|  | 				// wrap the original alias...
 | ||||||
|  | 				function(){ | ||||||
|  | 					var args = args2array(arguments) | ||||||
|  | 					if(args.length == 0 && k in this.direct){ | ||||||
|  | 						return this.direct[k].call(this) | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					var a = f.apply(this, args) | ||||||
|  | 					var b = func.call(this, k, args) | ||||||
|  | 
 | ||||||
|  | 					if(k in this.direct){ | ||||||
|  | 						return this.direct[k].call(this) | ||||||
|  | 					} | ||||||
|  | 					return b | ||||||
|  | 				}  | ||||||
|  | 				: function(){  | ||||||
|  | 					var args = args2array(arguments) | ||||||
|  | 					return func.call(this, k, args) } | ||||||
|  | 
 | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// XXX get these from grammar...
 | ||||||
|  | 	func('translate', ['px', 'px']) | ||||||
|  | 	func('translate3d', ['px', 'px', 'px']) | ||||||
|  | 	func('translateX', ['px']) | ||||||
|  | 	func('translateY', ['px']) | ||||||
|  | 	func('translateZ', ['px']) | ||||||
|  | 	alias({ translate3d: 0, translate: 0, translateX: 0, x: 0 }) | ||||||
|  | 	alias({ translate3d: 1, translate: 1, translateY: 0, y: 0, }) | ||||||
|  | 	alias({ translate3d: 2, translateZ: 0, z: 0, })  | ||||||
|  | 
 | ||||||
|  | 	func('scale') | ||||||
|  | 	func('scale3d') | ||||||
|  | 	func('scaleX') | ||||||
|  | 	func('scaleY') | ||||||
|  | 	func('scaleZ') | ||||||
|  | 	alias({ scale: 0, scale3d: 0, scaleX: 0, }) | ||||||
|  | 	alias({ scale: 1, scale3d: 1, scaleY: 0, }) | ||||||
|  | 	alias({ scale3d: 2, scaleZ: 0, }) | ||||||
|  | 	// special case: single arg scale: scale(n) -> scale(n, n)
 | ||||||
|  | 	alias({ scale: function(){ | ||||||
|  | 		if(arguments.length == 1){ | ||||||
|  | 			return this.scale(arguments[0], arguments[0]) | ||||||
|  | 		} | ||||||
|  | 		return this.direct.scale.apply(this) | ||||||
|  | 	} }) | ||||||
|  | 
 | ||||||
|  | 	func('rotate', ['deg']) | ||||||
|  | 	func('rotate3d', ['px', 'px', 'px', 'deg']) | ||||||
|  | 	func('rotateX', ['deg']) | ||||||
|  | 	func('rotateY', ['deg']) | ||||||
|  | 	func('rotateZ', ['deg']) | ||||||
|  | 
 | ||||||
|  | 	func('matrix') | ||||||
|  | 	func('matrix3d') | ||||||
|  | 
 | ||||||
|  | 	func('skew') | ||||||
|  | 	func('skewX') | ||||||
|  | 	func('skewY') | ||||||
|  | 	alias({skewX: 0, skew: 0}) | ||||||
|  | 	alias({skewY: 0, skew: 1}) | ||||||
|  | 
 | ||||||
|  | 	func('perspective') | ||||||
|  | 
 | ||||||
|  | 	// proxy the undefined in aliases functions...
 | ||||||
|  | 	Object.keys(editor.direct).forEach(function(k){ | ||||||
|  | 		if(!(k in editor)){ | ||||||
|  | 			editor[k] = function(){ return editor.direct[k].apply(this, arguments) } | ||||||
|  | 		} | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	return editor | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // XXX STUB: for testing only...
 | ||||||
|  | window.transformEditor = transformEditor | ||||||
|  | 
 | ||||||
|  | var transform = function(){ | ||||||
|  | 	var that = this | ||||||
|  | 	var elem = $(this)[0] | ||||||
|  | 
 | ||||||
|  | 	var args = args2array(arguments) | ||||||
|  | 	// normalize...
 | ||||||
|  | 	args = args.length == 0  | ||||||
|  | 			|| typeof(args[0]) == typeof('str') ? args | ||||||
|  | 		: args[0].constructor === Array  | ||||||
|  | 			|| args.length == 1 ? args[0] | ||||||
|  | 		: args | ||||||
|  | 
 | ||||||
|  | 	// XXX do vendor tags...
 | ||||||
|  | 	var prefix = '' | ||||||
|  | 
 | ||||||
|  | 	// get the current state...
 | ||||||
|  | 	var transform = transform2obj(elem && elem.style[prefix + 'transform']) | ||||||
|  | 	var origin = (elem ? elem.style[prefix + 'transformOrigin'] : '').split(/\s+/) | ||||||
|  | 
 | ||||||
|  | 	/* XXX not critical yet... | ||||||
|  | 	var style = this.style.transformStyle | ||||||
|  | 	var prespective = this.style.prespective | ||||||
|  | 	var prespectiveOrigin = this.style.prespectiveOrigin | ||||||
|  | 	var backfaceVisibility = this.style.backfaceVisibility | ||||||
|  | 	*/ | ||||||
|  | 
 | ||||||
|  | 	// XXX populate transformEditor with current state...
 | ||||||
|  | 	// XXX
 | ||||||
|  | 
 | ||||||
|  | 	// get state...
 | ||||||
|  | 	if(args.constructor === Array){ | ||||||
|  | 		// XXX minimize transformEditor and return
 | ||||||
|  | 		// XXX
 | ||||||
|  | 
 | ||||||
|  | 		// XXX
 | ||||||
|  | 		return | ||||||
|  | 
 | ||||||
|  | 	// set state...
 | ||||||
|  | 	} else { | ||||||
|  | 		// XXX add user inputs...
 | ||||||
|  | 		// XXX
 | ||||||
|  | 
 | ||||||
|  | 		// XXX minimize transformEditor and set...
 | ||||||
|  | 		// XXX
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return $(this) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| /********************************************************************** | /********************************************************************** | ||||||
| * vim:set ts=4 sw=4 :                                                */ | * vim:set ts=4 sw=4 :                                                */ | ||||||
| return module }) | return module }) | ||||||
|  | |||||||
| @ -59,6 +59,33 @@ var RIBBON = '.ribbon:not(.clone)' | |||||||
| //
 | //
 | ||||||
| // NOTE: there can be only one .ribbon-set element.
 | // NOTE: there can be only one .ribbon-set element.
 | ||||||
| //
 | //
 | ||||||
|  | //
 | ||||||
|  | // XXX need to replace soemlegacy CSS API and make this compatible with
 | ||||||
|  | // 		modern libs like velocity.js...
 | ||||||
|  | // 			- jli.getElementOrigin(..)
 | ||||||
|  | // 				<elem>.transform('origin')
 | ||||||
|  | //
 | ||||||
|  | // 			- jli.getElementScale(..)
 | ||||||
|  | // 				<elem>.transform('scale')
 | ||||||
|  | //
 | ||||||
|  | // 			- jli.getRelativeOffset(..)
 | ||||||
|  | // 				XXX offset if x from y...
 | ||||||
|  | //
 | ||||||
|  | // 			- jli.setElementOffset(..)
 | ||||||
|  | // 				<elem>.transform({x: <X>, y: <Y>, z: 0})
 | ||||||
|  | // 				<elem>.velocity({translateX: <X>, translateY: <Y>, translateZ: 0})
 | ||||||
|  | //
 | ||||||
|  | // 			- jli.setElementScale(..)
 | ||||||
|  | // 				<elem>.transform({scale, <scale>})
 | ||||||
|  | // 				<elem>.velocity({scale, <scale>})
 | ||||||
|  | //
 | ||||||
|  | // 			- jli.shiftOriginTo(..)
 | ||||||
|  | // 				XXX this sets origin and compensates for offsets...
 | ||||||
|  | //
 | ||||||
|  | // XXX think if a way to manage animation timings...
 | ||||||
|  | //
 | ||||||
|  | //
 | ||||||
|  | //
 | ||||||
| /*********************************************************************/ | /*********************************************************************/ | ||||||
| 
 | 
 | ||||||
| var RibbonsClassPrototype = { | var RibbonsClassPrototype = { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user