mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-10-30 19:00:09 +00:00 
			
		
		
		
	split gallery.html into separate blocks...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									11f8be4a2a
								
							
						
					
					
						commit
						c9a9259d59
					
				
							
								
								
									
										47
									
								
								ui/TODO.otl
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										47
									
								
								ui/TODO.otl
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,47 @@ | |||||||
|  | basic structure | ||||||
|  | 	ribbons					DONE | ||||||
|  | 	images					DONE | ||||||
|  | 	indicators | ||||||
|  | basic control elements | ||||||
|  | 	touch zones / buttons | ||||||
|  | 		next				DONE | ||||||
|  | 		prev				DONE | ||||||
|  | 		shift up			DONE | ||||||
|  | 		shift down			DONE | ||||||
|  | 		promote				DONE | ||||||
|  | 		demote				DONE | ||||||
|  | 		zoom in				~		need real zooming... | ||||||
|  | 		zoom out			~		need real zooming... | ||||||
|  | 		toggle single image	DONE | ||||||
|  | image sorting | ||||||
|  | 	will affect: | ||||||
|  | 		promote | ||||||
|  | 		demote | ||||||
|  | 		shift up | ||||||
|  | 		shift down | ||||||
|  | 		ribbon merging | ||||||
|  | add promote/demote events (to attach structure editors)... | ||||||
|  | add real images... | ||||||
|  | make all the code relative to the current selection (multiple instances on a page support) | ||||||
|  | make this into a jquery plugin... | ||||||
|  | add dynamic loading and unloading for very large sets... | ||||||
|  | gesture support... | ||||||
|  | add basic actions: | ||||||
|  | 	rotate left | ||||||
|  | 	rotate right | ||||||
|  | 	... | ||||||
|  | add info: | ||||||
|  | 	number of images in ribbon | ||||||
|  | 	position in ribbon | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | first stage refactoring: | ||||||
|  | 	merge almost identical functions... | ||||||
|  | 
 | ||||||
|  | multiple groups to promote/demote | ||||||
|  | 	ways to go: | ||||||
|  | 		promote/demote and tag | ||||||
|  | 
 | ||||||
|  | ISSUES: | ||||||
|  | 	jumping on focus up/down... | ||||||
|  | 	demoting a first element (a ribbon is created) positions the field incorrectly (see demoteImage() for details)... | ||||||
							
								
								
									
										356
									
								
								ui/gallery-prototype.js
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										356
									
								
								ui/gallery-prototype.js
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,356 @@ | |||||||
|  | $(document).ready(function() { | ||||||
|  | 	// current state...
 | ||||||
|  | 	if($('.current-ribbon').length == 0){ | ||||||
|  | 		$('.ribbon').first().addClass('current-ribbon') | ||||||
|  | 	} | ||||||
|  | 	if($('.current-image').length == 0){ | ||||||
|  | 		$('.current-ribbon').children('.image').first().addClass('current-image') | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// setup event handlers...
 | ||||||
|  | 	$(document) | ||||||
|  | 		.keydown(handleKeys) | ||||||
|  | 	$('.viewer') | ||||||
|  | 		// XXX does not work on android... (might need to add tap event handling)
 | ||||||
|  | 		.gestures({eventHandler: handleGestures}) | ||||||
|  | 		// XXX this is flaky and breaks some of my code...
 | ||||||
|  | 		/*.wipetouch({ | ||||||
|  | 			wipeLeft: nextImage, | ||||||
|  | 			wipeRight: prevImage, | ||||||
|  | 			wipeUp: demoteImage, | ||||||
|  | 			wipeDown: promoteImage, | ||||||
|  | 
 | ||||||
|  | 			tapToClick: true | ||||||
|  | 		})*/ | ||||||
|  | 		/* XXX jquery.mobile handlers... (with this I'm getting way too much bling) | ||||||
|  | 		.bind('swipeleft', function(e){ | ||||||
|  | 			nextImage() | ||||||
|  | 			e.preventDefault() | ||||||
|  | 			return false | ||||||
|  | 		}) | ||||||
|  | 		.bind('swiperight', function(e){ | ||||||
|  | 			prevImage() | ||||||
|  | 			e.preventDefault() | ||||||
|  | 			return false | ||||||
|  | 		}) | ||||||
|  | 		*/ | ||||||
|  | 	$(".image").click(handleClick) | ||||||
|  | 
 | ||||||
|  | 	// control elements...
 | ||||||
|  | 	$('.next-image').click(nextImage) | ||||||
|  | 	$('.prev-image').click(prevImage) | ||||||
|  | 	$('.demote').click(demoteImage) | ||||||
|  | 	$('.promote').click(promoteImage) | ||||||
|  | 	$('.toggle-wide').click(toggleWideView) | ||||||
|  | 	$('.toggle-single').click(toggleRibbonView) | ||||||
|  | 
 | ||||||
|  | 	// load images...
 | ||||||
|  | 	// XXX not allowed...
 | ||||||
|  | 	//$.getJSON('images.js', loadImages})
 | ||||||
|  | 	// XXX STUB
 | ||||||
|  | 	loadImages(image_list) | ||||||
|  | 
 | ||||||
|  | 	// set the default position and init...
 | ||||||
|  | 	$('.current-image').click() | ||||||
|  | 
 | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | function loadImages(json){ | ||||||
|  | 	var images = json.images | ||||||
|  | 	var ribbon = $('.ribbon').last() | ||||||
|  | 
 | ||||||
|  | 	$('.image').remove() | ||||||
|  | 
 | ||||||
|  | 	for(var i = 0; i < images.length; i++){ | ||||||
|  | 		$('<div class="image"></div>') | ||||||
|  | 			.css({ 'background-image': 'url('+images[i]+')' }) | ||||||
|  | 			.click(handleClick) | ||||||
|  | 			.appendTo(ribbon) | ||||||
|  | 	} | ||||||
|  | 	ribbon.children().first().click() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // XXX jquery.gestures handler...
 | ||||||
|  | function handleGestures(e){ | ||||||
|  | 	switch (e){ | ||||||
|  | 		case 'N': | ||||||
|  | 			demoteImage() | ||||||
|  | 			break | ||||||
|  | 		case 'S': | ||||||
|  | 			promoteImage() | ||||||
|  | 			break | ||||||
|  | 		case 'E': | ||||||
|  | 			prevImage() | ||||||
|  | 			break | ||||||
|  | 		case 'W': | ||||||
|  | 			nextImage() | ||||||
|  | 			break | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | function handleClick(e) { | ||||||
|  | 
 | ||||||
|  | 	var cur = $(this) | ||||||
|  | 
 | ||||||
|  | 	// switch classes...
 | ||||||
|  | 	cur.parents().siblings().children(".image").removeClass("current-image") | ||||||
|  | 	cur.siblings(".image").removeClass("current-image") | ||||||
|  | 
 | ||||||
|  | 	cur.siblings().children(".image").removeClass("current-image") | ||||||
|  | 	cur.parents().siblings(".ribbon").removeClass("current-ribbon") | ||||||
|  | 
 | ||||||
|  | 	cur.addClass("current-image") | ||||||
|  | 	cur.parents(".ribbon").addClass("current-ribbon") | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	var container = cur.parents('.container') | ||||||
|  | 	var field = cur.parents(".field") | ||||||
|  | 
 | ||||||
|  | 	var image_offset = cur.offset() | ||||||
|  | 	var field_offset = field.offset() | ||||||
|  | 
 | ||||||
|  | 	// center the current image...
 | ||||||
|  | 	field.css({ | ||||||
|  | 		left: field_offset.left - image_offset.left + (container.innerWidth() - cur.innerWidth())/2,  | ||||||
|  | 		top: field_offset.top - image_offset.top + (container.innerHeight() - cur.innerHeight())/2  | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	// XXX do I need this???
 | ||||||
|  | 	e.preventDefault(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | var keys = { | ||||||
|  | 	toggleHelpKeys: [72], | ||||||
|  | 	toggleRibbonView: [32], | ||||||
|  | 	closeKeys: [27, 88, 67], | ||||||
|  | 
 | ||||||
|  | 	firstKeys: [36], | ||||||
|  | 	lastKeys: [35], | ||||||
|  | 	previousKeys: [37, 80], | ||||||
|  | 	nextKeys: [39, 78], | ||||||
|  | 	promoteKeys: [40], | ||||||
|  | 	// XXX add del (46) to demote...
 | ||||||
|  | 	demoteKeys: [38], | ||||||
|  | 
 | ||||||
|  | 	ignoreKeys: [16, 17, 18], | ||||||
|  | 
 | ||||||
|  | 	helpShowOnUnknownKey: true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function handleKeys(event){ | ||||||
|  | 	var code = event.keyCode, fn = $.inArray; | ||||||
|  | 	var _ = (fn(code, keys.closeKeys) >= 0) ? function(){}() | ||||||
|  | 		: (fn(code, keys.firstKeys) >= 0) ? firstImage() | ||||||
|  | 		: (fn(code, keys.nextKeys) >= 0) ? nextImage() | ||||||
|  | 		: (fn(code, keys.previousKeys) >= 0) ? prevImage() | ||||||
|  | 		: (fn(code, keys.lastKeys) >= 0) ? lastImage() | ||||||
|  | 		: (fn(code, keys.promoteKeys) >= 0) ? function(){ | ||||||
|  | 			if(event.shiftKey){ | ||||||
|  | 				if(event.ctrlKey){ | ||||||
|  | 					createRibbonBelow() | ||||||
|  | 				} | ||||||
|  | 				promoteImage() | ||||||
|  | 			} else { | ||||||
|  | 				focusBelowRibbon() | ||||||
|  | 			} | ||||||
|  | 		}() | ||||||
|  | 		: (fn(code, keys.demoteKeys) >= 0) ? function(){ | ||||||
|  | 			if(event.shiftKey){ | ||||||
|  | 				if(event.ctrlKey){ | ||||||
|  | 					createRibbonAbove() | ||||||
|  | 				} | ||||||
|  | 				demoteImage() | ||||||
|  | 			} else { | ||||||
|  | 				focusAboveRibbon() | ||||||
|  | 			} | ||||||
|  | 		}() | ||||||
|  | 		: (fn(code, keys.toggleRibbonView) >= 0) ? toggleRibbonView() | ||||||
|  | 		: (fn(code, keys.ignoreKeys) >= 0) ? false | ||||||
|  | 		// XXX
 | ||||||
|  | 		: (keys.helpShowOnUnknownKey) ? function(){alert(code)}() | ||||||
|  | 		: false; | ||||||
|  | 	return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // modes...
 | ||||||
|  | function showRibbon(){ | ||||||
|  | 	$('.single-image-mode').removeClass('single-image-mode') | ||||||
|  | } | ||||||
|  | function showSingle(){ | ||||||
|  | 	$('.viewer').not('.single-image-mode').addClass('single-image-mode') | ||||||
|  | } | ||||||
|  | function toggleRibbonView(){ | ||||||
|  | 	if($('.single-image-mode').length > 0){ | ||||||
|  | 		showRibbon() | ||||||
|  | 	} else { | ||||||
|  | 		showSingle() | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // XXX need to reposition the whole thing correctly...
 | ||||||
|  | function toggleWideView(){ | ||||||
|  | 	if($('.wide-view-mode').length > 0){ | ||||||
|  | 		$('.wide-view-mode') | ||||||
|  | 			.removeClass('wide-view-mode') | ||||||
|  | 			.one("webkitTransitionEnd oTransitionEnd msTransitionEnd transitionend", function(){ | ||||||
|  | 				$('.current-image').click() | ||||||
|  | 				return true | ||||||
|  | 			}); | ||||||
|  | 		 | ||||||
|  | 	} else { | ||||||
|  | 		showRibbon() | ||||||
|  | 		//$('.container')
 | ||||||
|  | 		$('.viewer') | ||||||
|  | 			.not('.wide-view-mode') | ||||||
|  | 				.addClass('wide-view-mode') | ||||||
|  | 				.one("webkitTransitionEnd oTransitionEnd msTransitionEnd transitionend", function(){ | ||||||
|  | 					$('.current-image').click() | ||||||
|  | 					return true | ||||||
|  | 				}); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // basic navigation...
 | ||||||
|  | function firstImage(){ | ||||||
|  | 	$('.current-ribbon').children('.image').first().click() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function prevImage(){ | ||||||
|  | 	$('.current-image').prev('.image').click() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function nextImage(){ | ||||||
|  | 	$('.current-image').next('.image').click() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function lastImage(){ | ||||||
|  | 	$('.current-ribbon').children('.image').last().click() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // XXX select appropriate image...
 | ||||||
|  | function focusAboveRibbon(){ | ||||||
|  | 	$('.current-ribbon').prev('.ribbon').children('.image').first().click() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // XXX select appropriate image...
 | ||||||
|  | function focusBelowRibbon(){ | ||||||
|  | 	$('.current-ribbon').next('.ribbon').children('.image').first().click() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // create ribbon above/below helpers...
 | ||||||
|  | // XXX NOTE: this will shift the content downwards...
 | ||||||
|  | function createRibbonAbove(){ | ||||||
|  | 	var res = $('<div class="new-ribbon"></div>') | ||||||
|  | 		.insertBefore('.current-ribbon') | ||||||
|  | 		// HACK: without this, the class change below will not animate...
 | ||||||
|  | 		.show() | ||||||
|  | 		.addClass('ribbon') | ||||||
|  | 		.removeClass('new-ribbon') | ||||||
|  | 	// XXX find a better way to do this...
 | ||||||
|  | 	$('.field').css({ | ||||||
|  | 		top: $('.field').position().top - $('.current-ribbon').outerHeight() | ||||||
|  | 	}) | ||||||
|  | 	return res | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function createRibbonBelow(){ | ||||||
|  | 	return $('<div class="new-ribbon"></div>') | ||||||
|  | 		.insertAfter('.current-ribbon') | ||||||
|  | 		// HACK: without this, the class change below will not animate...
 | ||||||
|  | 		.show() | ||||||
|  | 		.addClass('ribbon') | ||||||
|  | 		.removeClass('new-ribbon') | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Modifiers...
 | ||||||
|  | 
 | ||||||
|  | // XXX sort elements correctly...
 | ||||||
|  | function mergeRibbonsUp(){ | ||||||
|  | 	$('.current-ribbon') | ||||||
|  | 		.prev('.ribbon') | ||||||
|  | 			.children() | ||||||
|  | 				.detach() | ||||||
|  | 				.insertAfter('.current-image') | ||||||
|  | 	$('.current-ribbon') | ||||||
|  | 		.prev('.ribbon') | ||||||
|  | 			.slideUp(function(){ | ||||||
|  | 				$(this).remove() | ||||||
|  | 				$('.current-image').click() | ||||||
|  | 			}) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // XXX sort elements correctly...
 | ||||||
|  | function mergeRibbonsDown(){ | ||||||
|  | 	$('.current-ribbon') | ||||||
|  | 		.next('.ribbon') | ||||||
|  | 			.children() | ||||||
|  | 				.detach() | ||||||
|  | 				.insertAfter('.current-image') | ||||||
|  | 	$('.current-ribbon') | ||||||
|  | 		.next('.ribbon') | ||||||
|  | 			.slideUp(function(){ | ||||||
|  | 				$(this).remove() | ||||||
|  | 				$('.current-image').click() | ||||||
|  | 			}) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // XXX sort elements correctly...
 | ||||||
|  | // XXX do animations...
 | ||||||
|  | function promoteImage(){ | ||||||
|  | 	if($('.current-ribbon').next('.ribbon').length == 0){ | ||||||
|  | 		createRibbonBelow() | ||||||
|  | 	} | ||||||
|  | 	// XXX sort elements correctly...
 | ||||||
|  | 	if($('.current-ribbon').children('.image').length == 1){ | ||||||
|  | 		// XXX this adds image to the head while the below portion adds it to the tail...
 | ||||||
|  | 		mergeRibbonsDown() | ||||||
|  | 	} else { | ||||||
|  | 		img = $('.current-image') | ||||||
|  | 		if(img.next('.image').length == 0){ | ||||||
|  | 			prevImage() | ||||||
|  | 		} else { | ||||||
|  | 			nextImage() | ||||||
|  | 		} | ||||||
|  | 		img | ||||||
|  | 			.detach() | ||||||
|  | 			.appendTo($('.current-ribbon').next('.ribbon')) | ||||||
|  | 	} | ||||||
|  | 	$('.current-image').click() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // XXX sort elements correctly...
 | ||||||
|  | // XXX do animations...
 | ||||||
|  | // XXX BUG: when demoting first image (new ribbon created) it gets focused...
 | ||||||
|  | //		REASON: .click() gets called in several places BEFORE the animation is done...
 | ||||||
|  | //		NOTE: this bog does not affect promoteImage -- adding a lower element does not affect current positioning...
 | ||||||
|  | function demoteImage(){ | ||||||
|  | 	if($('.current-ribbon').prev('.ribbon').length == 0){ | ||||||
|  | 		var new_ribbon = createRibbonAbove() | ||||||
|  | 	} | ||||||
|  | 	// XXX sort elements correctly...
 | ||||||
|  | 	if($('.current-ribbon').children('.image').length == 1){ | ||||||
|  | 		// XXX this adds image to the head while the below portion adds it to the tail...
 | ||||||
|  | 		mergeRibbonsUp() | ||||||
|  | 	} else { | ||||||
|  | 		img = $('.current-image') | ||||||
|  | 		if(img.next('.image').length == 0){ | ||||||
|  | 			// XXX in case when we've just created an empty ribbon, the click in this fires BEFORE it is fully expanded...
 | ||||||
|  | 			prevImage() | ||||||
|  | 		} else { | ||||||
|  | 			// XXX in case when we've just created an empty ribbon, the click in this fires BEFORE it is fully expanded...
 | ||||||
|  | 			nextImage() | ||||||
|  | 		} | ||||||
|  | 		img | ||||||
|  | 			.detach() | ||||||
|  | 			.appendTo($('.current-ribbon').prev('.ribbon')) | ||||||
|  | 	} | ||||||
|  | 	// XXX in case when we've just created an empty ribbon, the click in this fires BEFORE it is fully expanded...
 | ||||||
|  | 	$('.current-image').click() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // vim:set ts=4 sw=4 nowrap :
 | ||||||
							
								
								
									
										199
									
								
								ui/gallery.css
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										199
									
								
								ui/gallery.css
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @ -0,0 +1,199 @@ | |||||||
|  | .image { | ||||||
|  | 	position: relative; | ||||||
|  | 
 | ||||||
|  | 	width: 350px; | ||||||
|  | 	height: 350px; | ||||||
|  | 
 | ||||||
|  | 	display: inline-block; | ||||||
|  | 	background: no-repeat 50% black; | ||||||
|  | 	background-size: contain; | ||||||
|  | 
 | ||||||
|  | 	opacity: 0.3; | ||||||
|  | 
 | ||||||
|  | 	-webkit-transition: all 0.5s ease; | ||||||
|  | 	-moz-transition: all 0.5s ease; | ||||||
|  | 	-o-transition: all 0.5s ease; | ||||||
|  | 	-ms-transition: all 0.5s ease;	 | ||||||
|  | 	transition: all 0.5s ease; | ||||||
|  | 
 | ||||||
|  | 	cursor: hand; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .mock-image { | ||||||
|  | 	background: blue; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .demo-buttons { | ||||||
|  | 	margin: 15px | ||||||
|  | 	border: groove 2px; | ||||||
|  | 	 | ||||||
|  | 	opacity: 0.2; | ||||||
|  | 
 | ||||||
|  | 	-webkit-transition: all 0.5s ease; | ||||||
|  | 	-moz-transition: all 0.5s ease; | ||||||
|  | 	-o-transition: all 0.5s ease; | ||||||
|  | 	-ms-transition: all 0.5s ease;	 | ||||||
|  | 	transition: all 0.5s ease; | ||||||
|  | } | ||||||
|  | .demo-buttons:hover { | ||||||
|  | 	opacity: 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .viewer { | ||||||
|  | 	width: 900px; | ||||||
|  | 	height: 500px; | ||||||
|  | 	border: solid blue 5px; | ||||||
|  | 	margin: 20px;  | ||||||
|  | } | ||||||
|  | .controller { | ||||||
|  | 	height: 500px; | ||||||
|  | 	width: 50px; | ||||||
|  | 	background: silver; | ||||||
|  | 	float: left; | ||||||
|  | 
 | ||||||
|  | 	-webkit-transition: all 0.5s ease; | ||||||
|  | 	-moz-transition: all 0.5s ease; | ||||||
|  | 	-o-transition: all 0.5s ease; | ||||||
|  | 	-ms-transition: all 0.5s ease;	 | ||||||
|  | 	transition: all 0.5s ease; | ||||||
|  | } | ||||||
|  | .single-image-mode .controller { | ||||||
|  | 	opacity: 0.2; | ||||||
|  | } | ||||||
|  | .promote, .next-image, .prev-image, .demote, .toggle-wide, .toggle-single { | ||||||
|  | 	text-align: center; | ||||||
|  | 	vertical-align: middle; | ||||||
|  | 	width: 100%; | ||||||
|  | 	height: 150px;  | ||||||
|  | 	background: gray; | ||||||
|  | 
 | ||||||
|  |    -moz-user-select: none; | ||||||
|  |    -webkit-user-select: none; | ||||||
|  |    -o-user-select: none; | ||||||
|  |    -ms-user-select: none; | ||||||
|  |    user-select: none; | ||||||
|  | } | ||||||
|  | .next-image, .prev-image, .toggle-wide, .toggle-single { | ||||||
|  | 	background: silver; | ||||||
|  | } | ||||||
|  | .toggle-wide, .toggle-single { | ||||||
|  | 	height:50px | ||||||
|  | } | ||||||
|  | .promote { | ||||||
|  | } | ||||||
|  | .next-image { | ||||||
|  | } | ||||||
|  | .prev-image { | ||||||
|  | } | ||||||
|  | .demote { | ||||||
|  | } | ||||||
|  | .toggle-wide { | ||||||
|  | } | ||||||
|  | .toggle-single { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .container { | ||||||
|  | 	float: left; | ||||||
|  | 	overflow: hidden; | ||||||
|  | 	width: 800px; | ||||||
|  | 	height: 500px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .field { | ||||||
|  | 	position: relative; | ||||||
|  | 	overflow: visible; | ||||||
|  | 	top: 0px; | ||||||
|  | 	left: -100px; | ||||||
|  | 
 | ||||||
|  | 	-webkit-transition: all 0.5s ease; | ||||||
|  | 	-moz-transition: all 0.5s ease; | ||||||
|  | 	-o-transition: all 0.5s ease; | ||||||
|  | 	-ms-transition: all 0.5s ease;	 | ||||||
|  | 	transition: all 0.5s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .ribbon { | ||||||
|  | 	height: 360px; | ||||||
|  | 	/* XXX make this expand dynamically */ | ||||||
|  | 	width: 100000px; | ||||||
|  | 	overflow: visible; | ||||||
|  | 	padding-top: 2px; | ||||||
|  | 	padding-bottom: 2px; | ||||||
|  | 	text-align: center; | ||||||
|  | 	opacity: 0.2; | ||||||
|  | 
 | ||||||
|  | 	-webkit-transition: all 0.5s ease; | ||||||
|  | 	-moz-transition: all 0.5s ease; | ||||||
|  | 	-o-transition: all 0.5s ease; | ||||||
|  | 	-ms-transition: all 0.5s ease;	 | ||||||
|  | 	transition: all 0.5s ease; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | .new-ribbon { | ||||||
|  | 	height: 0px; | ||||||
|  | 
 | ||||||
|  | 	-webkit-transition: all 0.5s ease; | ||||||
|  | 	-moz-transition: all 0.5s ease; | ||||||
|  | 	-o-transition: all 0.5s ease; | ||||||
|  | 	-ms-transition: all 0.5s ease;	 | ||||||
|  | 	transition: all 0.5s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .current-image { | ||||||
|  | 	opacity: 1.0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .current-ribbon { | ||||||
|  | 	padding-top: 20px; | ||||||
|  | 	padding-bottom: 20px; | ||||||
|  | 
 | ||||||
|  | 	opacity: 1.0; | ||||||
|  | 
 | ||||||
|  | 	-webkit-transition: all 0.5s ease; | ||||||
|  | 	-moz-transition: all 0.5s ease; | ||||||
|  | 	-o-transition: all 0.5s ease; | ||||||
|  | 	-ms-transition: all 0.5s ease;	 | ||||||
|  | 	transition: all 0.5s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .current-ribbon .image { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* single image theme (start everything with .single-image-mode)  | ||||||
|  |  * | ||||||
|  |  * XXX need to make this touch friendly... | ||||||
|  |  */ | ||||||
|  | .single-image-mode .image { | ||||||
|  | 	opacity: 0.0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .single-image-mode .image:hover { | ||||||
|  | 	opacity: 0.5; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .single-image-mode .current-image:hover, .single-image-mode .current-image { | ||||||
|  | 	opacity: 1.0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* wide view mode */ | ||||||
|  | 
 | ||||||
|  | /* XXX not yet working correctly... | ||||||
|  | .wide-view-mode { | ||||||
|  | 	transform: scale(0.2,0.2); | ||||||
|  | 	-ms-transform: scale(0.2,0.2); | ||||||
|  | 	-webkit-transform: scale(0.2,0.2); | ||||||
|  | 	-o-transform: scale(0.2,0.2); | ||||||
|  | 	-moz-transform: scale(0.2,0.2); | ||||||
|  | } | ||||||
|  | */ | ||||||
|  | .wide-view-mode .image { | ||||||
|  | 	width: 50px; | ||||||
|  | 	height: 50px; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .wide-view-mode .ribbon { | ||||||
|  | 	height: 60px; | ||||||
|  | } | ||||||
							
								
								
									
										619
									
								
								ui/gallery.html
									
									
									
									
									
								
							
							
						
						
									
										619
									
								
								ui/gallery.html
									
									
									
									
									
								
							| @ -1,635 +1,28 @@ | |||||||
| 
 | 
 | ||||||
| <!-- | <!-- | ||||||
| TODO: |  | ||||||
| - basic structure |  | ||||||
| 	ribbons					DONE |  | ||||||
| 	images					DONE |  | ||||||
| 	indicators |  | ||||||
| - basic control elements |  | ||||||
| 	touch zones / buttons |  | ||||||
| 		next				DONE |  | ||||||
| 		prev				DONE |  | ||||||
| 		shift up			DONE |  | ||||||
| 		shift down			DONE |  | ||||||
| 		promote				DONE |  | ||||||
| 		demote				DONE |  | ||||||
| 		zoom in				~		need real zooming... |  | ||||||
| 		zoom out			~		need real zooming... |  | ||||||
| 		toggle single image	DONE |  | ||||||
| - image sorting |  | ||||||
| 	- will affect: |  | ||||||
| 		- promote |  | ||||||
| 		- demote |  | ||||||
| 		- shift up |  | ||||||
| 		- shift down |  | ||||||
| 		- ribbon merging |  | ||||||
| - add promote/demote events (to attach structure editors)... |  | ||||||
| - add real images... |  | ||||||
| - make all the code relative to the current selection (multiple instances on a page support) |  | ||||||
| - make this into a jquery plugin... |  | ||||||
| - add dynamic loading and unloading for very large sets... |  | ||||||
| - gesture support... |  | ||||||
| - add basic actions: |  | ||||||
| 	- rotate left |  | ||||||
| 	- rotate right |  | ||||||
| 	- ... |  | ||||||
| - add info: |  | ||||||
| 	- number of images in ribbon |  | ||||||
| 	- position in ribbon |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| - first stage refactoring: |  | ||||||
| 	- merge almost identical functions... |  | ||||||
| 
 |  | ||||||
| - multiple groups to promote/demote |  | ||||||
| 	ways to go: |  | ||||||
| 		- promote/demote and tag |  | ||||||
| 
 |  | ||||||
| ISSUES: |  | ||||||
| 	- jumping on focus up/down... |  | ||||||
| 	- demoting a first element (a ribbon is created) positions the field incorrectly (see demoteImage() for details)... |  | ||||||
| --> | --> | ||||||
| 
 | 
 | ||||||
|  | <link rel="stylesheet" href="gallery.css"> | ||||||
| <script src="jquery.js"></script> | <script src="jquery.js"></script> | ||||||
| 
 | 
 | ||||||
| <!-- script src="jquery.wipetouch.js"></script--> | <!-- script src="jquery.wipetouch.js"></script--> | ||||||
| 
 |  | ||||||
| <!-- XXX this does not work on android... -->  | <!-- XXX this does not work on android... -->  | ||||||
| <script src="jquery.gestures.js"></script> | <script src="jquery.gestures.js"></script> | ||||||
|  | <!-- XXX need to figure out how to disable all the bling --> | ||||||
|  | <!-- script src="jquery.mobile.js"></script--> | ||||||
| 
 | 
 | ||||||
| <!-- XXX STUB --> | <!-- XXX STUB --> | ||||||
| <script src="images.js"></script> | <script src="images.js"></script> | ||||||
|  | <script src="gallery-prototype.js"></script> | ||||||
|  | 
 | ||||||
|  | <!--script src="gallery.js"></script--> | ||||||
| 
 | 
 | ||||||
| <!-- XXX need to figure out how to disable all the bling --> |  | ||||||
| <!-- script src="jquery.mobile.js"></script--> |  | ||||||
| <script> | <script> | ||||||
| 
 |  | ||||||
| $(document).ready(function() { |  | ||||||
| 	// current state... |  | ||||||
| 	if($('.current-ribbon').length == 0){ |  | ||||||
| 		$('.ribbon').first().addClass('current-ribbon') |  | ||||||
| 	} |  | ||||||
| 	if($('.current-image').length == 0){ |  | ||||||
| 		$('.current-ribbon').children('.image').first().addClass('current-image') |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// setup event handlers... |  | ||||||
| 	$(document) |  | ||||||
| 		.keydown(handleKeys) |  | ||||||
| 	$('.viewer') |  | ||||||
| 		// XXX this is flaky and breaks some of my code... |  | ||||||
| 		/*.wipetouch({ |  | ||||||
| 			wipeLeft: nextImage, |  | ||||||
| 			wipeRight: prevImage, |  | ||||||
| 			wipeUp: demoteImage, |  | ||||||
| 			wipeDown: promoteImage, |  | ||||||
| 
 |  | ||||||
| 			tapToClick: true |  | ||||||
| 		})*/ |  | ||||||
| 		// XXX does not work on android... |  | ||||||
| 		.gestures({eventHandler: handleGestures}) |  | ||||||
| 		/* XXX jquery.mobile handlers... (with this I'm getting way too much bling) |  | ||||||
| 		.bind('swipeleft', function(e){ |  | ||||||
| 			nextImage() |  | ||||||
| 			e.preventDefault() |  | ||||||
| 			return false |  | ||||||
| 		}) |  | ||||||
| 		.bind('swiperight', function(e){ |  | ||||||
| 			prevImage() |  | ||||||
| 			e.preventDefault() |  | ||||||
| 			return false |  | ||||||
| 		}) |  | ||||||
| 		*/ |  | ||||||
| 	$(".image").click(handleClick) |  | ||||||
| 
 |  | ||||||
| 	// control elements... |  | ||||||
| 	$('.next-image').click(nextImage) |  | ||||||
| 	$('.prev-image').click(prevImage) |  | ||||||
| 	$('.demote').click(demoteImage) |  | ||||||
| 	$('.promote').click(promoteImage) |  | ||||||
| 	$('.toggle-wide').click(toggleWideView) |  | ||||||
| 	$('.toggle-single').click(toggleRibbonView) |  | ||||||
| 
 |  | ||||||
| 	// load images... |  | ||||||
| 	// XXX not allowed... |  | ||||||
| 	//$.getJSON('images.js', loadImages}) |  | ||||||
| 	// XXX STUB |  | ||||||
| 	loadImages(image_list) |  | ||||||
| 
 |  | ||||||
| 	// set the default position and init... |  | ||||||
| 	$('.current-image').click() |  | ||||||
| 
 |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| function loadImages(json){ |  | ||||||
| 	var images = json.images |  | ||||||
| 	var ribbon = $('.ribbon').last() |  | ||||||
| 
 |  | ||||||
| 	$('.image').remove() |  | ||||||
| 
 |  | ||||||
| 	for(var i = 0; i < images.length; i++){ |  | ||||||
| 		$('<div class="image"></div>') |  | ||||||
| 			.css({ |  | ||||||
| 				'background-image': 'url('+images[i]+')' |  | ||||||
| 			}) |  | ||||||
| 			.click(handleClick) |  | ||||||
| 			.appendTo(ribbon) |  | ||||||
| 	} |  | ||||||
| 	ribbon.children().first().click() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // XXX jquery.gestures handler... |  | ||||||
| function handleGestures(e){ |  | ||||||
| 	switch (e){ |  | ||||||
| 		case 'N': |  | ||||||
| 			demoteImage() |  | ||||||
| 			break |  | ||||||
| 		case 'S': |  | ||||||
| 			promoteImage() |  | ||||||
| 			break |  | ||||||
| 		case 'E': |  | ||||||
| 			prevImage() |  | ||||||
| 			break |  | ||||||
| 		case 'W': |  | ||||||
| 			nextImage() |  | ||||||
| 			break |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| function handleClick(e) { |  | ||||||
| 
 |  | ||||||
| 	var cur = $(this) |  | ||||||
| 
 |  | ||||||
| 	// switch classes... |  | ||||||
| 	cur.parents().siblings().children(".image").removeClass("current-image") |  | ||||||
| 	cur.siblings(".image").removeClass("current-image") |  | ||||||
| 
 |  | ||||||
| 	cur.siblings().children(".image").removeClass("current-image") |  | ||||||
| 	cur.parents().siblings(".ribbon").removeClass("current-ribbon") |  | ||||||
| 
 |  | ||||||
| 	cur.addClass("current-image") |  | ||||||
| 	cur.parents(".ribbon").addClass("current-ribbon") |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 	var container = cur.parents('.container') |  | ||||||
| 	var field = cur.parents(".field") |  | ||||||
| 
 |  | ||||||
| 	var image_offset = cur.offset() |  | ||||||
| 	var field_offset = field.offset() |  | ||||||
| 
 |  | ||||||
| 	// center the current image... |  | ||||||
| 	field.css({ |  | ||||||
| 		left: field_offset.left - image_offset.left + (container.innerWidth() - cur.innerWidth())/2,  |  | ||||||
| 		top: field_offset.top - image_offset.top + (container.innerHeight() - cur.innerHeight())/2  |  | ||||||
| 	}) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 	// XXX do I need this??? |  | ||||||
| 	e.preventDefault(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var keys = { |  | ||||||
| 	toggleHelpKeys: [72], |  | ||||||
| 	toggleRibbonView: [32], |  | ||||||
| 	closeKeys: [27, 88, 67], |  | ||||||
| 
 |  | ||||||
| 	firstKeys: [36], |  | ||||||
| 	lastKeys: [35], |  | ||||||
| 	previousKeys: [37, 80], |  | ||||||
| 	nextKeys: [39, 78], |  | ||||||
| 	promoteKeys: [40], |  | ||||||
| 	// XXX add del (46) to demote... |  | ||||||
| 	demoteKeys: [38], |  | ||||||
| 
 |  | ||||||
| 	ignoreKeys: [16, 17, 18], |  | ||||||
| 
 |  | ||||||
| 	helpShowOnUnknownKey: true |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function handleKeys(event){ |  | ||||||
| 	var code = event.keyCode, fn = $.inArray; |  | ||||||
| 	var _ = (fn(code, keys.closeKeys) >= 0) ? function(){}() |  | ||||||
| 		: (fn(code, keys.firstKeys) >= 0) ? firstImage() |  | ||||||
| 		: (fn(code, keys.nextKeys) >= 0) ? nextImage() |  | ||||||
| 		: (fn(code, keys.previousKeys) >= 0) ? prevImage() |  | ||||||
| 		: (fn(code, keys.lastKeys) >= 0) ? lastImage() |  | ||||||
| 		: (fn(code, keys.promoteKeys) >= 0) ? function(){ |  | ||||||
| 			if(event.shiftKey){ |  | ||||||
| 				if(event.ctrlKey){ |  | ||||||
| 					createRibbonBelow() |  | ||||||
| 				} |  | ||||||
| 				promoteImage() |  | ||||||
| 			} else { |  | ||||||
| 				focusBelowRibbon() |  | ||||||
| 			} |  | ||||||
| 		}() |  | ||||||
| 		: (fn(code, keys.demoteKeys) >= 0) ? function(){ |  | ||||||
| 			if(event.shiftKey){ |  | ||||||
| 				if(event.ctrlKey){ |  | ||||||
| 					createRibbonAbove() |  | ||||||
| 				} |  | ||||||
| 				demoteImage() |  | ||||||
| 			} else { |  | ||||||
| 				focusAboveRibbon() |  | ||||||
| 			} |  | ||||||
| 		}() |  | ||||||
| 		: (fn(code, keys.toggleRibbonView) >= 0) ? toggleRibbonView() |  | ||||||
| 		: (fn(code, keys.ignoreKeys) >= 0) ? false |  | ||||||
| 		// XXX |  | ||||||
| 		: (keys.helpShowOnUnknownKey) ? function(){alert(code)}() |  | ||||||
| 		: false; |  | ||||||
| 	return false; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| // modes... |  | ||||||
| function showRibbon(){ |  | ||||||
| 	$('.single-image-mode').removeClass('single-image-mode') |  | ||||||
| } |  | ||||||
| function showSingle(){ |  | ||||||
| 	$('.viewer').not('.single-image-mode').addClass('single-image-mode') |  | ||||||
| } |  | ||||||
| function toggleRibbonView(){ |  | ||||||
| 	if($('.single-image-mode').length > 0){ |  | ||||||
| 		showRibbon() |  | ||||||
| 	} else { |  | ||||||
| 		showSingle() |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // XXX need to reposition the whole thing correctly... |  | ||||||
| function toggleWideView(){ |  | ||||||
| 	if($('.wide-view-mode').length > 0){ |  | ||||||
| 		$('.wide-view-mode') |  | ||||||
| 			.removeClass('wide-view-mode') |  | ||||||
| 			.one("webkitTransitionEnd oTransitionEnd msTransitionEnd transitionend", function(){ |  | ||||||
| 				$('.current-image').click() |  | ||||||
| 				return true |  | ||||||
| 			}); |  | ||||||
| 		 |  | ||||||
| 	} else { |  | ||||||
| 		showRibbon() |  | ||||||
| 		//$('.container') |  | ||||||
| 		$('.viewer') |  | ||||||
| 			.not('.wide-view-mode') |  | ||||||
| 				.addClass('wide-view-mode') |  | ||||||
| 				.one("webkitTransitionEnd oTransitionEnd msTransitionEnd transitionend", function(){ |  | ||||||
| 					$('.current-image').click() |  | ||||||
| 					return true |  | ||||||
| 				}); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // basic navigation... |  | ||||||
| function firstImage(){ |  | ||||||
| 	$('.current-ribbon').children('.image').first().click() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function prevImage(){ |  | ||||||
| 	$('.current-image').prev('.image').click() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function nextImage(){ |  | ||||||
| 	$('.current-image').next('.image').click() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function lastImage(){ |  | ||||||
| 	$('.current-ribbon').children('.image').last().click() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // XXX select appropriate image... |  | ||||||
| function focusAboveRibbon(){ |  | ||||||
| 	$('.current-ribbon').prev('.ribbon').children('.image').first().click() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // XXX select appropriate image... |  | ||||||
| function focusBelowRibbon(){ |  | ||||||
| 	$('.current-ribbon').next('.ribbon').children('.image').first().click() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| // create ribbon above/below helpers... |  | ||||||
| // XXX NOTE: this will shift the content downwards... |  | ||||||
| function createRibbonAbove(){ |  | ||||||
| 	var res = $('<div class="new-ribbon"></div>') |  | ||||||
| 		.insertBefore('.current-ribbon') |  | ||||||
| 		// HACK: without this, the class change below will not animate... |  | ||||||
| 		.show() |  | ||||||
| 		.addClass('ribbon') |  | ||||||
| 		.removeClass('new-ribbon') |  | ||||||
| 	// XXX find a better way to do this... |  | ||||||
| 	$('.field').css({ |  | ||||||
| 		top: $('.field').position().top - $('.current-ribbon').outerHeight() |  | ||||||
| 	}) |  | ||||||
| 	return res |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function createRibbonBelow(){ |  | ||||||
| 	return $('<div class="new-ribbon"></div>') |  | ||||||
| 		.insertAfter('.current-ribbon') |  | ||||||
| 		// HACK: without this, the class change below will not animate... |  | ||||||
| 		.show() |  | ||||||
| 		.addClass('ribbon') |  | ||||||
| 		.removeClass('new-ribbon') |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Modifiers... |  | ||||||
| 
 |  | ||||||
| // XXX sort elements correctly... |  | ||||||
| function mergeRibbonsUp(){ |  | ||||||
| 	$('.current-ribbon') |  | ||||||
| 		.prev('.ribbon') |  | ||||||
| 			.children() |  | ||||||
| 				.detach() |  | ||||||
| 				.insertAfter('.current-image') |  | ||||||
| 	$('.current-ribbon') |  | ||||||
| 		.prev('.ribbon') |  | ||||||
| 			.slideUp(function(){ |  | ||||||
| 				$(this).remove() |  | ||||||
| 				$('.current-image').click() |  | ||||||
| 			}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // XXX sort elements correctly... |  | ||||||
| function mergeRibbonsDown(){ |  | ||||||
| 	$('.current-ribbon') |  | ||||||
| 		.next('.ribbon') |  | ||||||
| 			.children() |  | ||||||
| 				.detach() |  | ||||||
| 				.insertAfter('.current-image') |  | ||||||
| 	$('.current-ribbon') |  | ||||||
| 		.next('.ribbon') |  | ||||||
| 			.slideUp(function(){ |  | ||||||
| 				$(this).remove() |  | ||||||
| 				$('.current-image').click() |  | ||||||
| 			}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // XXX sort elements correctly... |  | ||||||
| // XXX do animations... |  | ||||||
| function promoteImage(){ |  | ||||||
| 	if($('.current-ribbon').next('.ribbon').length == 0){ |  | ||||||
| 		createRibbonBelow() |  | ||||||
| 	} |  | ||||||
| 	// XXX sort elements correctly... |  | ||||||
| 	if($('.current-ribbon').children('.image').length == 1){ |  | ||||||
| 		// XXX this adds image to the head while the below portion adds it to the tail... |  | ||||||
| 		mergeRibbonsDown() |  | ||||||
| 	} else { |  | ||||||
| 		img = $('.current-image') |  | ||||||
| 		if(img.next('.image').length == 0){ |  | ||||||
| 			prevImage() |  | ||||||
| 		} else { |  | ||||||
| 			nextImage() |  | ||||||
| 		} |  | ||||||
| 		img |  | ||||||
| 			.detach() |  | ||||||
| 			.appendTo($('.current-ribbon').next('.ribbon')) |  | ||||||
| 	} |  | ||||||
| 	$('.current-image').click() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // XXX sort elements correctly... |  | ||||||
| // XXX do animations... |  | ||||||
| // XXX BUG: when demoting first image (new ribbon created) it gets focused... |  | ||||||
| //		REASON: .click() gets called in several places BEFORE the animation is done... |  | ||||||
| //		NOTE: this bog does not affect promoteImage -- adding a lower element does not affect current positioning... |  | ||||||
| function demoteImage(){ |  | ||||||
| 	if($('.current-ribbon').prev('.ribbon').length == 0){ |  | ||||||
| 		var new_ribbon = createRibbonAbove() |  | ||||||
| 	} |  | ||||||
| 	// XXX sort elements correctly... |  | ||||||
| 	if($('.current-ribbon').children('.image').length == 1){ |  | ||||||
| 		// XXX this adds image to the head while the below portion adds it to the tail... |  | ||||||
| 		mergeRibbonsUp() |  | ||||||
| 	} else { |  | ||||||
| 		img = $('.current-image') |  | ||||||
| 		if(img.next('.image').length == 0){ |  | ||||||
| 			// XXX in case when we've just created an empty ribbon, the click in this fires BEFORE it is fully expanded... |  | ||||||
| 			prevImage() |  | ||||||
| 		} else { |  | ||||||
| 			// XXX in case when we've just created an empty ribbon, the click in this fires BEFORE it is fully expanded... |  | ||||||
| 			nextImage() |  | ||||||
| 		} |  | ||||||
| 		img |  | ||||||
| 			.detach() |  | ||||||
| 			.appendTo($('.current-ribbon').prev('.ribbon')) |  | ||||||
| 	} |  | ||||||
| 	// XXX in case when we've just created an empty ribbon, the click in this fires BEFORE it is fully expanded... |  | ||||||
| 	$('.current-image').click() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <style> | <style> | ||||||
| 	.image { |  | ||||||
| 		position: relative; |  | ||||||
| 
 |  | ||||||
| 		width: 350px; |  | ||||||
| 		height: 350px; |  | ||||||
| 
 |  | ||||||
| 		display: inline-block; |  | ||||||
| 		background: no-repeat 50% black; |  | ||||||
| 		background-size: contain; |  | ||||||
| 
 |  | ||||||
| 		opacity: 0.3; |  | ||||||
| 
 |  | ||||||
| 		-webkit-transition: all 0.5s ease; |  | ||||||
| 		-moz-transition: all 0.5s ease; |  | ||||||
| 		-o-transition: all 0.5s ease; |  | ||||||
| 		-ms-transition: all 0.5s ease;	 |  | ||||||
| 		transition: all 0.5s ease; |  | ||||||
| 
 |  | ||||||
| 		cursor: hand; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	.mock-image { |  | ||||||
| 		background: blue; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	.demo-buttons { |  | ||||||
| 		margin: 15px |  | ||||||
| 		border: groove 2px; |  | ||||||
| 		 |  | ||||||
| 		opacity: 0.2; |  | ||||||
| 
 |  | ||||||
| 		-webkit-transition: all 0.5s ease; |  | ||||||
| 		-moz-transition: all 0.5s ease; |  | ||||||
| 		-o-transition: all 0.5s ease; |  | ||||||
| 		-ms-transition: all 0.5s ease;	 |  | ||||||
| 		transition: all 0.5s ease; |  | ||||||
| 	} |  | ||||||
| 	.demo-buttons:hover { |  | ||||||
| 		opacity: 1; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	.viewer { |  | ||||||
| 		width: 900px; |  | ||||||
| 		height: 500px; |  | ||||||
| 		border: solid blue 5px; |  | ||||||
| 		margin: 20px;  |  | ||||||
| 	} |  | ||||||
| 	.controller { |  | ||||||
| 		height: 500px; |  | ||||||
| 		width: 50px; |  | ||||||
| 		background: silver; |  | ||||||
| 		float: left; |  | ||||||
| 
 |  | ||||||
| 		-webkit-transition: all 0.5s ease; |  | ||||||
| 		-moz-transition: all 0.5s ease; |  | ||||||
| 		-o-transition: all 0.5s ease; |  | ||||||
| 		-ms-transition: all 0.5s ease;	 |  | ||||||
| 		transition: all 0.5s ease; |  | ||||||
| 	} |  | ||||||
| 	.single-image-mode .controller { |  | ||||||
| 		opacity: 0.2; |  | ||||||
| 	} |  | ||||||
| 	.promote, .next-image, .prev-image, .demote, .toggle-wide, .toggle-single { |  | ||||||
| 		text-align: center; |  | ||||||
| 		vertical-align: middle; |  | ||||||
| 		width: 100%; |  | ||||||
| 		height: 150px;  |  | ||||||
| 		background: gray; |  | ||||||
| 
 |  | ||||||
| 	   -moz-user-select: none; |  | ||||||
| 	   -webkit-user-select: none; |  | ||||||
| 	   -o-user-select: none; |  | ||||||
| 	   -ms-user-select: none; |  | ||||||
| 	   user-select: none; |  | ||||||
| 	} |  | ||||||
| 	.next-image, .prev-image, .toggle-wide, .toggle-single { |  | ||||||
| 		background: silver; |  | ||||||
| 	} |  | ||||||
| 	.toggle-wide, .toggle-single { |  | ||||||
| 		height:50px |  | ||||||
| 	} |  | ||||||
| 	.promote { |  | ||||||
| 	} |  | ||||||
| 	.next-image { |  | ||||||
| 	} |  | ||||||
| 	.prev-image { |  | ||||||
| 	} |  | ||||||
| 	.demote { |  | ||||||
| 	} |  | ||||||
| 	.toggle-wide { |  | ||||||
| 	} |  | ||||||
| 	.toggle-single { |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	.container { |  | ||||||
| 		float: left; |  | ||||||
| 		overflow: hidden; |  | ||||||
| 		width: 800px; |  | ||||||
| 		height: 500px; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	.field { |  | ||||||
| 		position: relative; |  | ||||||
| 		overflow: visible; |  | ||||||
| 		top: 0px; |  | ||||||
| 		left: -100px; |  | ||||||
| 
 |  | ||||||
| 		-webkit-transition: all 0.5s ease; |  | ||||||
| 		-moz-transition: all 0.5s ease; |  | ||||||
| 		-o-transition: all 0.5s ease; |  | ||||||
| 		-ms-transition: all 0.5s ease;	 |  | ||||||
| 		transition: all 0.5s ease; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	.ribbon { |  | ||||||
| 		height: 360px; |  | ||||||
| 		/* XXX make this expand dynamically */ |  | ||||||
| 		width: 100000px; |  | ||||||
| 		overflow: visible; |  | ||||||
| 		padding-top: 2px; |  | ||||||
| 		padding-bottom: 2px; |  | ||||||
| 		text-align: center; |  | ||||||
| 		opacity: 0.2; |  | ||||||
| 
 |  | ||||||
| 		-webkit-transition: all 0.5s ease; |  | ||||||
| 		-moz-transition: all 0.5s ease; |  | ||||||
| 		-o-transition: all 0.5s ease; |  | ||||||
| 		-ms-transition: all 0.5s ease;	 |  | ||||||
| 		transition: all 0.5s ease; |  | ||||||
| 
 |  | ||||||
| 	} |  | ||||||
| 	.new-ribbon { |  | ||||||
| 		height: 0px; |  | ||||||
| 
 |  | ||||||
| 		-webkit-transition: all 0.5s ease; |  | ||||||
| 		-moz-transition: all 0.5s ease; |  | ||||||
| 		-o-transition: all 0.5s ease; |  | ||||||
| 		-ms-transition: all 0.5s ease;	 |  | ||||||
| 		transition: all 0.5s ease; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	.current-image { |  | ||||||
| 		opacity: 1.0; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	.current-ribbon { |  | ||||||
| 		padding-top: 20px; |  | ||||||
| 		padding-bottom: 20px; |  | ||||||
| 
 |  | ||||||
| 		opacity: 1.0; |  | ||||||
| 
 |  | ||||||
| 		-webkit-transition: all 0.5s ease; |  | ||||||
| 		-moz-transition: all 0.5s ease; |  | ||||||
| 		-o-transition: all 0.5s ease; |  | ||||||
| 		-ms-transition: all 0.5s ease;	 |  | ||||||
| 		transition: all 0.5s ease; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	.current-ribbon .image { |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 	/* single image theme (start everything with .single-image-mode)  |  | ||||||
| 	 * |  | ||||||
| 	 * XXX need to make this touch friendly... |  | ||||||
| 	 */ |  | ||||||
| 	.single-image-mode .image { |  | ||||||
| 		opacity: 0.0; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	.single-image-mode .image:hover { |  | ||||||
| 		opacity: 0.5; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	.single-image-mode .current-image:hover, .single-image-mode .current-image { |  | ||||||
| 		opacity: 1.0; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 	/* wide view mode */ |  | ||||||
| 
 |  | ||||||
| 	/* XXX not yet working correctly... |  | ||||||
| 	.wide-view-mode { |  | ||||||
| 		transform: scale(0.2,0.2); |  | ||||||
| 		-ms-transform: scale(0.2,0.2); |  | ||||||
| 		-webkit-transform: scale(0.2,0.2); |  | ||||||
| 		-o-transform: scale(0.2,0.2); |  | ||||||
| 		-moz-transform: scale(0.2,0.2); |  | ||||||
| 	} |  | ||||||
| 	*/ |  | ||||||
| 	.wide-view-mode .image { |  | ||||||
| 		width: 50px; |  | ||||||
| 		height: 50px; |  | ||||||
| 
 |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	.wide-view-mode .ribbon { |  | ||||||
| 		height: 60px; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| </style> | </style> | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| <div class="viewer"> | <div class="viewer"> | ||||||
| 	<div class="controller"> | 	<div class="controller"> | ||||||
| 		<div class="demote">^</div> | 		<div class="demote">^</div> | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user