mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-11-03 21:00:14 +00:00 
			
		
		
		
	
		
			
	
	
		
			299 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			299 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								/**********************************************************************
							 | 
						||
| 
								 | 
							
								* 
							 | 
						||
| 
								 | 
							
								* This is here for reference...
							 | 
						||
| 
								 | 
							
								*
							 | 
						||
| 
								 | 
							
								*
							 | 
						||
| 
								 | 
							
								**********************************************************************/
							 | 
						||
| 
								 | 
							
								((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define)
							 | 
						||
| 
								 | 
							
								(function(require){ var module={} // make module AMD/node compatible...
							 | 
						||
| 
								 | 
							
								/*********************************************************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var actions = require('lib/actions')
							 | 
						||
| 
								 | 
							
								var features = require('lib/features')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var core = require('features/core')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*********************************************************************/
							 | 
						||
| 
								 | 
							
								// Mouse...
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// XXX add setup/taredown...
							 | 
						||
| 
								 | 
							
								var Clickable = 
							 | 
						||
| 
								 | 
							
								module.Clickable = core.ImageGridFeatures.Feature({
							 | 
						||
| 
								 | 
							
									title: '',
							 | 
						||
| 
								 | 
							
									doc: '',
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									tag: 'ui-clickable',
							 | 
						||
| 
								 | 
							
									depends: ['ui'],
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									config: {
							 | 
						||
| 
								 | 
							
										'click-threshold': {
							 | 
						||
| 
								 | 
							
											t: 100,
							 | 
						||
| 
								 | 
							
											d: 5,
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
									},
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									handlers: [
							 | 
						||
| 
								 | 
							
										// setup click targets...
							 | 
						||
| 
								 | 
							
										// XXX click only if we did not drag...
							 | 
						||
| 
								 | 
							
										['updateImage', 
							 | 
						||
| 
								 | 
							
											function(res, gid){
							 | 
						||
| 
								 | 
							
												var that = this
							 | 
						||
| 
								 | 
							
												var img = this.ribbons.getImage(gid)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												// set the clicker only once...
							 | 
						||
| 
								 | 
							
												if(!img.prop('clickable')){
							 | 
						||
| 
								 | 
							
													var x, y, t, last, threshold
							 | 
						||
| 
								 | 
							
													img
							 | 
						||
| 
								 | 
							
														.prop('clickable', true)
							 | 
						||
| 
								 | 
							
														.on('mousedown touchstart', function(evt){ 
							 | 
						||
| 
								 | 
							
															threshold = that.config['click-threshold']
							 | 
						||
| 
								 | 
							
															x = evt.clientX
							 | 
						||
| 
								 | 
							
															y = evt.clientY
							 | 
						||
| 
								 | 
							
															t = Date.now()
							 | 
						||
| 
								 | 
							
														})
							 | 
						||
| 
								 | 
							
														.on('mouseup touchend', function(evt){ 
							 | 
						||
| 
								 | 
							
															if(that.__control_in_progress){
							 | 
						||
| 
								 | 
							
																return
							 | 
						||
| 
								 | 
							
															}
							 | 
						||
| 
								 | 
							
															// prevent another handler within a timeout...
							 | 
						||
| 
								 | 
							
															// XXX not too sure about this...
							 | 
						||
| 
								 | 
							
															if(t - last < threshold.t){
							 | 
						||
| 
								 | 
							
																return
							 | 
						||
| 
								 | 
							
															}
							 | 
						||
| 
								 | 
							
															// constrain distance between down and up events...
							 | 
						||
| 
								 | 
							
															if(x != null 
							 | 
						||
| 
								 | 
							
																&& Math.max(
							 | 
						||
| 
								 | 
							
																	Math.abs(x - evt.clientX), 
							 | 
						||
| 
								 | 
							
																	Math.abs(y - evt.clientY)) < threshold.d){
							 | 
						||
| 
								 | 
							
																// this will prevent double clicks...
							 | 
						||
| 
								 | 
							
																x = null
							 | 
						||
| 
								 | 
							
																y = null
							 | 
						||
| 
								 | 
							
																that.focusImage(that.ribbons.getElemGID($(this)))
							 | 
						||
| 
								 | 
							
																last = Date.now()
							 | 
						||
| 
								 | 
							
															}
							 | 
						||
| 
								 | 
							
														})
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}],
							 | 
						||
| 
								 | 
							
									],
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*********************************************************************/
							 | 
						||
| 
								 | 
							
								// Touch/Control...
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// XXX add zoom...
							 | 
						||
| 
								 | 
							
								// XXX add vertical pan to ribbon-set...
							 | 
						||
| 
								 | 
							
								var DirectControlHammer = 
							 | 
						||
| 
								 | 
							
								module.DirectControlHammer = core.ImageGridFeatures.Feature({
							 | 
						||
| 
								 | 
							
									title: '',
							 | 
						||
| 
								 | 
							
									doc: '',
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									tag: 'ui-direct-control-hammer',
							 | 
						||
| 
								 | 
							
									exclusive: ['ui-control'],
							 | 
						||
| 
								 | 
							
									depends: [
							 | 
						||
| 
								 | 
							
										'ui',
							 | 
						||
| 
								 | 
							
										// this is only used to trigger reoad...
							 | 
						||
| 
								 | 
							
										//'ui-partial-ribbons',
							 | 
						||
| 
								 | 
							
									],
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									config: {
							 | 
						||
| 
								 | 
							
										// This can be:
							 | 
						||
| 
								 | 
							
										// 	'silent'	- silently focus central image after pan
							 | 
						||
| 
								 | 
							
										// 	true		- focus central image after pan
							 | 
						||
| 
								 | 
							
										// 	null		- do nothing.
							 | 
						||
| 
								 | 
							
										'focus-central-image': 'silent',
							 | 
						||
| 
								 | 
							
									},
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// XXX add setup/taredown...
							 | 
						||
| 
								 | 
							
									// XXX add inertia...
							 | 
						||
| 
								 | 
							
									// XXX hide current image indicator on drag...
							 | 
						||
| 
								 | 
							
									// XXX add swipe up/down control...
							 | 
						||
| 
								 | 
							
									// XXX add mode switching....
							 | 
						||
| 
								 | 
							
									// XXX BUG: after panning and silent focus, marking works correctly 
							 | 
						||
| 
								 | 
							
									// 		but image is not updated -- mark not drawn...
							 | 
						||
| 
								 | 
							
									handlers: [
							 | 
						||
| 
								 | 
							
										// setup ribbon dragging...
							 | 
						||
| 
								 | 
							
										// XXX it is possible to drag over the loaded ribbon section with
							 | 
						||
| 
								 | 
							
										// 		two fingers, need to force update somehow...
							 | 
						||
| 
								 | 
							
										// 		...and need to try and make the update in a single frame...
							 | 
						||
| 
								 | 
							
										// 		Ways to go:
							 | 
						||
| 
								 | 
							
										// 			- update on touchdown
							 | 
						||
| 
								 | 
							
										// 			- update on liftoff
							 | 
						||
| 
								 | 
							
										// XXX drag in single image mode ONLY if image is larger than screen...
							 | 
						||
| 
								 | 
							
										['updateRibbon', 
							 | 
						||
| 
								 | 
							
											function(_, target){
							 | 
						||
| 
								 | 
							
												var that = this
							 | 
						||
| 
								 | 
							
												var r = this.ribbons.getRibbon(target)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												// setup dragging...
							 | 
						||
| 
								 | 
							
												if(r.length > 0 && !r.hasClass('draggable')){
							 | 
						||
| 
								 | 
							
													r
							 | 
						||
| 
								 | 
							
														.addClass('draggable')
							 | 
						||
| 
								 | 
							
														.hammer()
							 | 
						||
| 
								 | 
							
														.on('pan', function(evt){
							 | 
						||
| 
								 | 
							
															//evt.stopPropagation()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
															// XXX stop all previous animations...
							 | 
						||
| 
								 | 
							
															//r.velocity("stop")
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
															var d = that.ribbons.dom
							 | 
						||
| 
								 | 
							
															var s = that.scale
							 | 
						||
| 
								 | 
							
															var g = evt.gesture
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
															var data = r.data('drag-data')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
															// we just started...
							 | 
						||
| 
								 | 
							
															if(!data){
							 | 
						||
| 
								 | 
							
																that.__control_in_progress = (that.__control_in_progress || 0) + 1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
																// hide and remove current image indicator...
							 | 
						||
| 
								 | 
							
																// NOTE: it will be reconstructed on 
							 | 
						||
| 
								 | 
							
																// 		next .focusImage(..)
							 | 
						||
| 
								 | 
							
																var m = that.ribbons.viewer
							 | 
						||
| 
								 | 
							
																	.find('.current-marker')
							 | 
						||
| 
								 | 
							
																		.velocity({opacity: 0}, {
							 | 
						||
| 
								 | 
							
																			duration: 100,
							 | 
						||
| 
								 | 
							
																			complete: function(){
							 | 
						||
| 
								 | 
							
																				m.remove()
							 | 
						||
| 
								 | 
							
																			},
							 | 
						||
| 
								 | 
							
																		})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
																// store initial position...
							 | 
						||
| 
								 | 
							
																var data = {
							 | 
						||
| 
								 | 
							
																	left: d.getOffset(this).left
							 | 
						||
| 
								 | 
							
																}
							 | 
						||
| 
								 | 
							
																r.data('drag-data', data)
							 | 
						||
| 
								 | 
							
															}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
															// do the actual move...
							 | 
						||
| 
								 | 
							
															d.setOffset(this, data.left + (g.deltaX / s))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
															// when done...
							 | 
						||
| 
								 | 
							
															if(g.isFinal){
							 | 
						||
| 
								 | 
							
																r.removeData('drag-data')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
																// XXX this seems to have trouble with off-screen images...
							 | 
						||
| 
								 | 
							
																var central = that.ribbons.getImageByPosition('center', r)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
																// load stuff if needed...
							 | 
						||
| 
								 | 
							
																that.updateRibbon(central)
							 | 
						||
| 
								 | 
							
																
							 | 
						||
| 
								 | 
							
																// XXX add inertia....
							 | 
						||
| 
								 | 
							
																//console.log('!!!!', g.velocityX)
							 | 
						||
| 
								 | 
							
																//r.velocity({
							 | 
						||
| 
								 | 
							
																//	translateX: (data.left + g.deltaX + (g.velocityX * 10)) +'px'
							 | 
						||
| 
								 | 
							
																//}, 'easeInSine')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
																// silently focus central image...
							 | 
						||
| 
								 | 
							
																if(that.config['focus-central-image'] == 'silent'){
							 | 
						||
| 
								 | 
							
																	that.data.current = that.ribbons.getElemGID(central)
							 | 
						||
| 
								 | 
							
																	
							 | 
						||
| 
								 | 
							
																// focus central image in a normal manner...
							 | 
						||
| 
								 | 
							
																} else if(that.config['focus-central-image']){
							 | 
						||
| 
								 | 
							
																	that.focusImage(that.ribbons.getElemGID(central))
							 | 
						||
| 
								 | 
							
																}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
																setTimeout(function(){
							 | 
						||
| 
								 | 
							
																	that.__control_in_progress -= 1
							 | 
						||
| 
								 | 
							
																	if(that.__control_in_progress <= 0){
							 | 
						||
| 
								 | 
							
																		delete that.__control_in_progress
							 | 
						||
| 
								 | 
							
																	}
							 | 
						||
| 
								 | 
							
																}, 50)
							 | 
						||
| 
								 | 
							
															}
							 | 
						||
| 
								 | 
							
														})
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}],
							 | 
						||
| 
								 | 
							
									],
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// XXX try direct control with hammer.js
							 | 
						||
| 
								 | 
							
								// XXX load state from config...
							 | 
						||
| 
								 | 
							
								// XXX sometimes this makes the indicator hang for longer than needed...
							 | 
						||
| 
								 | 
							
								// XXX BUG: this conflicts a bit whith ui-clickable...
							 | 
						||
| 
								 | 
							
								// 		...use this with hammer.js taps instead...
							 | 
						||
| 
								 | 
							
								// XXX might be a good idea to make a universal and extensible control 
							 | 
						||
| 
								 | 
							
								// 		mode toggler...
							 | 
						||
| 
								 | 
							
								// 		...obvious chice would seem to be a meta toggler:
							 | 
						||
| 
								 | 
							
								// 			config['control-mode'] = {
							 | 
						||
| 
								 | 
							
								// 				<mode-name>: <mode-toggler>
							 | 
						||
| 
								 | 
							
								// 			}
							 | 
						||
| 
								 | 
							
								// 			and the action will toggle the given mode on and the previous
							 | 
						||
| 
								 | 
							
								// 			off...
							 | 
						||
| 
								 | 
							
								// 			XXX this seems a bit too complicated...
							 | 
						||
| 
								 | 
							
								var IndirectControl = 
							 | 
						||
| 
								 | 
							
								module.IndirectControl = core.ImageGridFeatures.Feature({
							 | 
						||
| 
								 | 
							
									title: '',
							 | 
						||
| 
								 | 
							
									doc: '',
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									tag: 'ui-indirect-control',
							 | 
						||
| 
								 | 
							
									// XXX is this correct???
							 | 
						||
| 
								 | 
							
									exclusive: ['ui-control'],
							 | 
						||
| 
								 | 
							
									depends: ['ui'],
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									config: {
							 | 
						||
| 
								 | 
							
									},
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									actions: actions.Actions({
							 | 
						||
| 
								 | 
							
										toggleSwipeHandling:['Interface/Toggle indirect control swipe handling',
							 | 
						||
| 
								 | 
							
											toggler.Toggler(null,
							 | 
						||
| 
								 | 
							
												function(_, state){
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													if(state == null){
							 | 
						||
| 
								 | 
							
														return (this.ribbons 
							 | 
						||
| 
								 | 
							
																&& this.ribbons.viewer 
							 | 
						||
| 
								 | 
							
																&& this.ribbons.viewer.data('hammer')) 
							 | 
						||
| 
								 | 
							
															|| 'none'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													// on...
							 | 
						||
| 
								 | 
							
													} else if(state == 'handling-swipes'){
							 | 
						||
| 
								 | 
							
														var that = this
							 | 
						||
| 
								 | 
							
														var viewer = this.ribbons.viewer
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
														// prevent multiple handlers...
							 | 
						||
| 
								 | 
							
														if(viewer.data('hammer') != null){
							 | 
						||
| 
								 | 
							
															return
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
														viewer.hammer()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
														var h = viewer.data('hammer')
							 | 
						||
| 
								 | 
							
														h.get('swipe').set({direction: Hammer.DIRECTION_ALL})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
														viewer
							 | 
						||
| 
								 | 
							
															.on('swipeleft', function(){ that.nextImage() })
							 | 
						||
| 
								 | 
							
															.on('swiperight', function(){ that.prevImage() })
							 | 
						||
| 
								 | 
							
															.on('swipeup', function(){ that.shiftImageUp() })
							 | 
						||
| 
								 | 
							
															.on('swipedown', function(){ that.shiftImageDown() })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													// off...
							 | 
						||
| 
								 | 
							
													} else {
							 | 
						||
| 
								 | 
							
														this.ribbons.viewer
							 | 
						||
| 
								 | 
							
															.off('swipeleft')
							 | 
						||
| 
								 | 
							
															.off('swiperight')
							 | 
						||
| 
								 | 
							
															.off('swipeup')
							 | 
						||
| 
								 | 
							
															.off('swipedown')
							 | 
						||
| 
								 | 
							
															.removeData('hammer')
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												},
							 | 
						||
| 
								 | 
							
												'handling-swipes')],
							 | 
						||
| 
								 | 
							
									}),
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									handlers: [
							 | 
						||
| 
								 | 
							
										['load', 
							 | 
						||
| 
								 | 
							
											function(){ a.toggleSwipeHandling('on') }],
							 | 
						||
| 
								 | 
							
										['stop', 
							 | 
						||
| 
								 | 
							
											function(){ a.toggleSwipeHandling('off') }],
							 | 
						||
| 
								 | 
							
									],
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**********************************************************************
							 | 
						||
| 
								 | 
							
								* vim:set ts=4 sw=4 :                               */ return module })
							 |