mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-28 18:00: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>
|