mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-11-03 04:40:10 +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>
 |