mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-10-29 18:30:09 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			370 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			HTML
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			370 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			HTML
		
	
	
		
			Executable File
		
	
	
	
	
| <!DOCTYPE html>
 | |
| <html>
 | |
| <!--
 | |
| //---------------------------------------------------------------------
 | |
| // Experiment: use native scroll for ribbons and view...
 | |
| // 	Factors:
 | |
| // 		+ the browser will do all the heavy lifting and do it faster 
 | |
| // 			than we can ever hope to do it in JS (assumption)
 | |
| // 		- will require us to add an extra container per ribbon 
 | |
| //
 | |
| // 	Experiment result:
 | |
| // 		- more uniform and fast across browsers 
 | |
| // 			(except FF - can't disable scrollbars, need to cheat)
 | |
| // 		- less controllable (inertia, gestures, ...)
 | |
| // 		- is affected by scaling in a bad way - paralax...
 | |
| //
 | |
| // 	Conclusion:
 | |
| // 		- this again brings us to using code to control the scroll
 | |
| // 		  which in turn defeats the original purpose of avoiding
 | |
| // 		  extra complexity...
 | |
| //
 | |
| // 	See: 
 | |
| // 		experiments/native-scroll-ribbon.html
 | |
| //
 | |
| 
 | |
| -->
 | |
| 
 | |
| <style>
 | |
| .mark-center:after {
 | |
| 	position: absolute;
 | |
| 	display: block;
 | |
| 	content: "";
 | |
| 	width: 5px;
 | |
| 	height: 5px;
 | |
| 	left: 50%;
 | |
| 	top: 50%;
 | |
| 	border-left: solid 2px red;
 | |
| 	border-top: solid 2px red;
 | |
| 	margin-left: -1px;
 | |
| 	margin-top: -1px;
 | |
| 	opacity: 0.8;
 | |
| 	z-index: 1;
 | |
| }
 | |
| .mark-center:before {
 | |
| 	position: absolute;
 | |
| 	display: block;
 | |
| 	content: "";
 | |
| 	width: 5px;
 | |
| 	height: 5px;
 | |
| 	right: 50%;
 | |
| 	bottom: 50%;
 | |
| 	border-bottom: solid 2px red;
 | |
| 	border-right: solid 2px red;
 | |
| 	margin-bottom: -1px;
 | |
| 	margin-right: -1px;
 | |
| 	opacity: 0.8;
 | |
| 	z-index: 1;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* XXX appears that there is no way to hide the scrollbar on FF...
 | |
| *	...one way around this is to use something like iScroll/Scrolly
 | |
| *	on FF or where more control is needed...
 | |
| */
 | |
| .viewer {
 | |
| 	position: relative;
 | |
| 	display: inline-block;
 | |
| 	border: solid 1px gray;
 | |
| 
 | |
| 	width: 600px;
 | |
| 	height: 500px;
 | |
| 
 | |
| 	overflow: hidden;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| .scaler {
 | |
| 	position: relative;
 | |
| 	width: 100%;
 | |
| 	height: 100%;
 | |
| 
 | |
| 	top: 50%;
 | |
| 	left: 50%;
 | |
| 	margin-top: -50%;
 | |
| 	margin-left: -50%;
 | |
| 
 | |
| 	transform-origin: 50% 50%;
 | |
| 
 | |
| 	overflow-x: hidden;
 | |
| 	overflow-y: scroll;
 | |
| 
 | |
| 	-ms-overflow-style: none;
 | |
| }
 | |
| .scaler::-webkit-scrollbar { 
 | |
|     display: none; 
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| /* This is to be used for:
 | |
| *	- vrtical positioning
 | |
| *	- scaling
 | |
| *	  (update width to fit viewer)
 | |
| */
 | |
| .ribbon-set {
 | |
| 	position: relative;
 | |
| 	display: inline-block;
 | |
| 
 | |
| 	/* This allways needs to be of viewer width, this mostly applies
 | |
| 	* to scaling...
 | |
| 	*/
 | |
| 	width: 100%;
 | |
| 
 | |
| 	padding-top: 50%;
 | |
| 	padding-bottom: 50%;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| .ribbon-container {
 | |
| 	position: relative;
 | |
| 
 | |
| 	height: 120px;
 | |
| 	width: 100%;
 | |
| 
 | |
| 	overflow-x: scroll;
 | |
| 	overflow-y: hidden;
 | |
| 
 | |
| 	-ms-overflow-style: none;
 | |
| }
 | |
| .ribbon-container::-webkit-scrollbar { 
 | |
|     display: none; 
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| .ribbon {
 | |
| 	position: relative;
 | |
| 	display: inline-block;
 | |
| 
 | |
| 	height: 100px;
 | |
| 	width: 1000px;
 | |
| 
 | |
| 	background: silver;
 | |
| 	/*box-shadow: 0px 0px 25px -10px rgba(0,0,0,0.75);*/
 | |
| 	box-shadow: 0px 0px 25px -10px rgba(0,0,0,1);
 | |
| 
 | |
| 	/* start/end markers... */
 | |
| 	border-left: 100px solid gray;
 | |
| 	border-right: 100px solid gray;
 | |
| 
 | |
| 	margin: 10px;
 | |
| 
 | |
| 	margin-left: 50%;
 | |
| 	/* XXX for some reason this does not work as expected */
 | |
| 	margin-right: 50%;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| </style>
 | |
| 
 | |
| <script src="../ext-lib/jquery.js"></script>
 | |
| <script src="../ext-lib/jquery-ui.js"></script>
 | |
| 
 | |
| <script src="../ext-lib/velocity.min.js"></script>
 | |
| 
 | |
| <script src="../ext-lib/iscroll.js"></script>
 | |
| <script src="../ext-lib/iscroll-zoom.js"></script>
 | |
| 
 | |
| <script src="../lib/jli.js"></script>
 | |
| 
 | |
| <script>
 | |
| 
 | |
| var scale = function(){
 | |
| 	var s = /scale\(([^\)]+)\)/.exec($('.scaler')[0].style.transform)
 | |
| 	return s ? parseFloat(s.pop()) : 1
 | |
| }
 | |
| 
 | |
| 
 | |
| // XXX when setting origin at scales different from 1, we'll need to 
 | |
| //	adjust offset to compensate for the shift... 
 | |
| // XXX one other simplification might be adding a new element specifically
 | |
| //	dedicated to scaling...
 | |
| var centerOrigin = function(){
 | |
| 	var H = $('.viewer').height()
 | |
| 	var s = $('.viewer')[0].scrollTop
 | |
| 
 | |
| 	$('.ribbon-set').css({
 | |
| 		'transform-origin': '50% '+ (s + H/2) +'px'
 | |
| 	})
 | |
| }
 | |
| 
 | |
| 
 | |
| // XXX these accumolate errors...
 | |
| var zoomIn = function(c){
 | |
| 	c = c || 1.2
 | |
| 
 | |
| 	centerOrigin()
 | |
| 	$('.scaler')
 | |
| 		.velocity('stop')
 | |
| 		.velocity({
 | |
| 			scale: '*='+c,
 | |
| 
 | |
| 			width: '/='+c,
 | |
| 			height: '/='+c,
 | |
| 			'margin-left': '/='+c,
 | |
| 			'margin-top': '/='+c,
 | |
| 		}, {
 | |
| 			duration: 300,
 | |
| 			easing: 'linear',
 | |
| 		})
 | |
| }
 | |
| var zoomOut = function(c){
 | |
| 	c = c || 1.2
 | |
| 
 | |
| 	centerOrigin()
 | |
| 	$('.scaler')
 | |
| 		.velocity('stop')
 | |
| 		.velocity({
 | |
| 			scale: '/='+c,
 | |
| 
 | |
| 			width: '*='+c,
 | |
| 			height: '*='+c,
 | |
| 			'margin-left': '*='+c,
 | |
| 			'margin-top': '*='+c,
 | |
| 		}, {
 | |
| 			duration: 300,
 | |
| 			easing: 'linear',
 | |
| 		})
 | |
| }
 | |
| 
 | |
| 
 | |
| var setup = function(){
 | |
| 	var H = $('.viewer').height()
 | |
| 	var W = $('.viewer').width()
 | |
| 
 | |
| 	// set margins to be parant and not content dependant...
 | |
| 	$('.scaler')
 | |
| 		.velocity({
 | |
| 			'margin-left': -W/2,
 | |
| 			'margin-top': -H/2,
 | |
| 		}, 0)
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| var ISCROLL = false
 | |
| 
 | |
| 
 | |
| $(function(){
 | |
| 	setup()
 | |
| 
 | |
| 
 | |
| // setup iScroll...
 | |
| if(ISCROLL){
 | |
| 	// Vertical scroll and zoom...
 | |
| 	$('.scaler')
 | |
| 		.css({
 | |
| 			overflow: 'hidden',
 | |
| 		})
 | |
| 	window.scroll_view = new IScroll('.scaler', {
 | |
| 		// XXX setting this to false makes zoom reset x to 0 after it's done...
 | |
| 		scrollX: false,
 | |
| 		scrollY: true,
 | |
| 
 | |
| 		disableMouse: false,
 | |
| 		mouseWheel: true,
 | |
| 
 | |
| 		eventPassthrough: 'horizontal',
 | |
| 
 | |
| 		zoom: true,
 | |
| 	})
 | |
| 
 | |
| 	var t
 | |
| 	$('.scaler').on('touchend mouseup', function(){
 | |
| 		//t = $('.ribbon-set')[0].style.transform
 | |
| 
 | |
| 		t = $('.ribbon-set').offset().left
 | |
| 	})
 | |
| 	scroll_view.on('zoomEnd', function(){
 | |
| 		var v = $('.viewer')
 | |
| 
 | |
| 		var s = scroll_view.scale
 | |
| 		var W = v.width()
 | |
| 		var H = v.width()
 | |
| 
 | |
| 		var w = W/s
 | |
| 		var h = H/s
 | |
| 
 | |
| 		var e = $('.ribbon-set')
 | |
| 
 | |
| 		// XXX compensate for offset -- scroll ribbons by to 
 | |
| 		//	place them where they where under user's fingers...
 | |
| 		// XXX this does not work...
 | |
| 		/*
 | |
| 		var d = (e.offset().left - t) * s
 | |
| 		$('.ribbon').each(function(_, r){
 | |
| 			$(r).velocity({
 | |
| 				transformX: '+='+d,
 | |
| 			}, 0)
 | |
| 		})
 | |
| 		*/
 | |
| 
 | |
| 		e = e[0]
 | |
| 		e.style.width = w + 'px'
 | |
| 		e.style.height = h + 'px'
 | |
| 	})
 | |
| 
 | |
| 
 | |
| 
 | |
| 	// Ribbon scroll...
 | |
| 	//
 | |
| 	// Problems:
 | |
| 	//	- iScroll does not account for margins when aclculating 
 | |
| 	//	  scroll width, need to patch this on .update(..)...
 | |
| 	//	- can't scroll ribbons independently
 | |
| 	//		- two fingers will trigger zoom
 | |
| 	//		- for some reason if touching two ribbons while
 | |
| 	//		  zooming they will move in the same direction...
 | |
| 	//	- scrolling a ribbon does not account for scale...
 | |
| 	//	  ...the same problem exists for native scroll...
 | |
| 	window.scroll_ribbon = []
 | |
| 	$('.ribbon-container')//.eq(0)
 | |
| 		.css({
 | |
| 			overflow: 'hidden',
 | |
| 		})
 | |
| 		.each(function(_, e){
 | |
| 			console.log(e)
 | |
| 			// XXX this calculates the scroll width incorrectly...
 | |
| 			scroll_ribbon.push(new IScroll(e, {
 | |
| 				scrollX: true,
 | |
| 				scrollY: false,
 | |
| 
 | |
| 				disableMouse: false,
 | |
| 				// XXX this only reads vertical mousewheel...
 | |
| 				//	...need this to work in a horizontal direction...
 | |
| 				//mouseWheel: true,
 | |
| 			}))
 | |
| 		})
 | |
| }
 | |
| })
 | |
| 
 | |
| </script>
 | |
| 
 | |
| <body>
 | |
| 
 | |
| <div class="viewer mark-center">
 | |
| 	<div class="scaler">
 | |
| 		<div class="ribbon-set">
 | |
| 			<div class="ribbon-container">
 | |
| 				<div class="ribbon">
 | |
| 				</div>
 | |
| 			</div>
 | |
| 			<div class="ribbon-container">
 | |
| 				<div class="ribbon">
 | |
| 				</div>
 | |
| 			</div>
 | |
| 			<div class="ribbon-container">
 | |
| 				<div class="ribbon">
 | |
| 				</div>
 | |
| 			</div>
 | |
| 		</div>
 | |
| 	</div>
 | |
| </div>
 | |
| 
 | |
| </body>
 | |
| </html>
 |