mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-07 06:57:02 +08:00
Tweaks to panel and my drag panel demo
This commit is contained in:
@ -42,6 +42,16 @@ main > * {
|
|||||||
.content-padded {
|
.content-padded {
|
||||||
padding: 10px; }
|
padding: 10px; }
|
||||||
|
|
||||||
|
.section {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 1; }
|
||||||
|
|
||||||
|
.full-section {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 1;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%; }
|
||||||
|
|
||||||
.alert {
|
.alert {
|
||||||
padding: 8px 35px 8px 14px; }
|
padding: 8px 35px 8px 14px; }
|
||||||
|
|
||||||
@ -221,36 +231,55 @@ a.list-item {
|
|||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
line-height: 1.3; }
|
line-height: 1.3; }
|
||||||
|
|
||||||
[data-panel] {
|
.ion-panel {
|
||||||
display: none;
|
display: none;
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
z-index: 0; }
|
z-index: 0; }
|
||||||
|
|
||||||
.panel-active {
|
.ion-panel-active-left {
|
||||||
|
left: 0; }
|
||||||
|
|
||||||
|
.ion-panel-active-right {
|
||||||
|
right: 0; }
|
||||||
|
|
||||||
|
.ion-panel-active {
|
||||||
display: block;
|
display: block;
|
||||||
width: 270px; }
|
width: 270px; }
|
||||||
|
|
||||||
header, main, footer {
|
.bar-header, .content, .bar-footer {
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
-webkit-transition: -webkit-transform 300ms ease;
|
-webkit-transition: -webkit-transform 200ms ease;
|
||||||
-moz-transition: -moz-transform 300ms ease;
|
-moz-transition: -moz-transform 200ms ease;
|
||||||
transition: transform 300ms ease;
|
transition: transform 200ms ease;
|
||||||
-webkit-transform: translate3d(0, 0, 0);
|
-webkit-transform: translate3d(0, 0, 0);
|
||||||
-moz-transform: translate3d(0, 0, 0);
|
-moz-transform: translate3d(0, 0, 0);
|
||||||
transform: translate3d(0, 0, 0); }
|
transform: translate3d(0, 0, 0); }
|
||||||
|
|
||||||
.panel-opened > section > header,
|
.ion-panel-left .bar-header,
|
||||||
.panel-opened > section > main,
|
.ion-panel-left .content,
|
||||||
.panel-opened > section > footer {
|
.ion-panel-left .bar-footer {
|
||||||
-webkit-transform: translate3d(270px, 0, 0);
|
-webkit-transform: translate3d(270px, 0, 0);
|
||||||
-moz-transform: translate3d(270px, 0, 0);
|
-moz-transform: translate3d(270px, 0, 0);
|
||||||
transform: translate3d(270px, 0, 0); }
|
transform: translate3d(270px, 0, 0); }
|
||||||
|
|
||||||
|
.ion-panel-right .bar-header,
|
||||||
|
.ion-panel-right .content,
|
||||||
|
.ion-panel-right .bar-footer {
|
||||||
|
-webkit-transform: translate3d(-270px, 0, 0);
|
||||||
|
-moz-transform: translate3d(-270px, 0, 0);
|
||||||
|
transform: translate3d(-270px, 0, 0); }
|
||||||
|
|
||||||
|
.ion-panel-animated {
|
||||||
|
-webkit-transition: -webkit-transform 200ms ease;
|
||||||
|
-moz-transition: -moz-transform 200ms ease;
|
||||||
|
transition: transform 200ms ease; }
|
||||||
|
|
||||||
.ptr-capable {
|
.ptr-capable {
|
||||||
-webkit-user-drag: element; }
|
-webkit-user-drag: element; }
|
||||||
|
|
||||||
@ -324,6 +353,11 @@ body {
|
|||||||
main {
|
main {
|
||||||
background-color: white; }
|
background-color: white; }
|
||||||
|
|
||||||
|
.full-section {
|
||||||
|
-webkit-box-shadow: -3px 0px 10px rgba(0, 0, 0, 0.2), 3px 0px 10px rgba(0, 0, 0, 0.2);
|
||||||
|
-moz-box-shadow: -3px 0px 10px rgba(0, 0, 0, 0.2), 3px 0px 10px rgba(0, 0, 0, 0.2);
|
||||||
|
box-shadow: -3px 0px 10px rgba(0, 0, 0, 0.2), 3px 0px 10px rgba(0, 0, 0, 0.2); }
|
||||||
|
|
||||||
.alert {
|
.alert {
|
||||||
margin-bottom: 1.42857;
|
margin-bottom: 1.42857;
|
||||||
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
|
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
|
||||||
@ -534,10 +568,15 @@ main {
|
|||||||
a.list-item {
|
a.list-item {
|
||||||
color: #333333; }
|
color: #333333; }
|
||||||
|
|
||||||
[data-panel] {
|
.ion-panel {
|
||||||
background: #eeeeee;
|
background: #eeeeee; }
|
||||||
|
|
||||||
|
.ion-panel-left .ion-panel {
|
||||||
border-right: 1px solid #bbbbbb; }
|
border-right: 1px solid #bbbbbb; }
|
||||||
|
|
||||||
|
.ion-panel-right .ion-panel {
|
||||||
|
border-left: 1px solid #bbbbbb; }
|
||||||
|
|
||||||
.ptr-content {
|
.ptr-content {
|
||||||
background: #eee; }
|
background: #eee; }
|
||||||
|
|
||||||
|
|||||||
@ -1,45 +1,255 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
<meta charset="utf-8">
|
||||||
<meta name="format-detection" content="telephone=no" />
|
<title>Panels</title>
|
||||||
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
|
|
||||||
<link rel="stylesheet" href="css/framework.css">
|
|
||||||
<script src="js/angular-1.2.0rc1.min.js"></script>
|
|
||||||
<script src="js/angular-touch.js"></script>
|
|
||||||
<script src="js/app.js"></script>
|
|
||||||
|
|
||||||
<script src="js/framework/framework-panel.js"></script>
|
<!-- Sets initial viewport load and disables zooming -->
|
||||||
<script src="js/framework/glue/angular-touch.js"></script>
|
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||||
</head>
|
<!--<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">-->
|
||||||
<body ng-app="Chat">
|
<link rel="stylesheet" href="css/framework.css">
|
||||||
<section class="panel-page-container">
|
|
||||||
|
|
||||||
<panel id="this-panel" class="panel-content" ng-class="{'panel-open': isPanelShowing}" ng-controller="MenuCtrl">
|
</head>
|
||||||
<ul class="list">
|
<body>
|
||||||
<li class="list-item">
|
|
||||||
Max Lynch
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</panel>
|
|
||||||
|
|
||||||
<section ng-controller="RoomsCtrl">
|
<section id="page" class="full-section ion-panel-animated">
|
||||||
|
|
||||||
<header class="bar bar-header bar-dark">
|
<header class="bar bar-header bar-dark">
|
||||||
<button class="button button-dark" ng-click="openPanel()">Rooms</button>
|
<button id="left-button" class="button">Left</button>
|
||||||
<h1 class="title">Feeds</h1>
|
<h1 class="title">Panels</h1>
|
||||||
|
<button id="right-button" class="button">Left</button>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main class="content has-header">
|
<main class="content content-padded has-header">
|
||||||
<ul class="list">
|
<p><button class="button button-primary">Other Left Side Panel</button></p>
|
||||||
<li class="list-item" ng-repeat="room in rooms">
|
<p id="event-log"></p>
|
||||||
{{room.name}}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
<footer class="bar bar-footer bar-dark">
|
||||||
|
<h3 class="title">Panels</h3>
|
||||||
|
</footer>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</section>
|
|
||||||
|
|
||||||
</body>
|
<section id="my-left-panel" class="ion-panel ion-panel-active-left">
|
||||||
|
This is my default left side panel!
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="my-right-panel" class="ion-panel ion-panel-active-right">
|
||||||
|
This is my right side panel!
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="my-other-left-panel" class="ion-panel">
|
||||||
|
This is my other left side panel!
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
<script src="js/framework/framework-events.js"></script>
|
||||||
|
<script src="js/framework/framework-gestures.js"></script>
|
||||||
|
<script src="js/framework/ion-panel.js"></script>
|
||||||
|
<script src="js/framework/handlers/panel-handler.js"></script>
|
||||||
|
<script>
|
||||||
|
var LeftRightPanelViewController = function(options) {
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
|
this.animateClass = options.animateClass;
|
||||||
|
this.left = options.left;
|
||||||
|
this.leftWidth = options.leftWidth;
|
||||||
|
this.right = options.right;
|
||||||
|
this.rightWidth = options.rightWidth;
|
||||||
|
this.center = options.center;
|
||||||
|
|
||||||
|
this._rightShowing = false;
|
||||||
|
this._leftShowing = false;
|
||||||
|
|
||||||
|
// Bind release and drag listeners
|
||||||
|
window.FM.onGesture('release', function(e) {
|
||||||
|
_this._endDrag(e);
|
||||||
|
}, document.body);
|
||||||
|
|
||||||
|
window.FM.onGesture('drag', function(e) {
|
||||||
|
_this._handleDrag(e);
|
||||||
|
}, document.body);
|
||||||
|
|
||||||
|
window.FM.onGesture('swiperight', function(e) {
|
||||||
|
console.log('SWIPERIGHT');
|
||||||
|
//_this.openPercentage(-100);
|
||||||
|
}, document.body);
|
||||||
|
window.FM.onGesture('swipeleft', function(e) {
|
||||||
|
console.log('SWIPELEFT');
|
||||||
|
//_this.openPercentage(-100);
|
||||||
|
}, document.body);
|
||||||
|
};
|
||||||
|
|
||||||
|
LeftRightPanelViewController.prototype = {
|
||||||
|
toggleLeft: function() {
|
||||||
|
var openAmount = this.getOpenAmount();
|
||||||
|
if(openAmount > 0) {
|
||||||
|
this.openPercentage(0);
|
||||||
|
} else {
|
||||||
|
this.openPercentage(100);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toggleRight: function() {
|
||||||
|
var openAmount = this.getOpenAmount();
|
||||||
|
if(openAmount < 0) {
|
||||||
|
this.openPercentage(0);
|
||||||
|
} else {
|
||||||
|
this.openPercentage(-100);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getOpenAmount: function() {
|
||||||
|
var r = /translate3d\((-?\d+)px/;
|
||||||
|
var d = r.exec(this.center.style.webkitTransform);
|
||||||
|
|
||||||
|
if(d && d.length > 0) {
|
||||||
|
return parseInt(d[1]);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
getOpenRatio: function() {
|
||||||
|
var amount = this.getOpenAmount();
|
||||||
|
if(amount >= 0) {
|
||||||
|
return amount / this.leftWidth;
|
||||||
|
}
|
||||||
|
return amount / this.rightWidth;
|
||||||
|
},
|
||||||
|
openPercentage: function(percentage) {
|
||||||
|
var p = percentage / 100;
|
||||||
|
var maxLeft = this.leftWidth;
|
||||||
|
var maxRight = this.rightWidth;
|
||||||
|
if(percentage >= 0) {
|
||||||
|
this.openAmount(maxLeft * p);
|
||||||
|
} else {
|
||||||
|
this.openAmount(maxRight * p);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
openAmount: function(amount) {
|
||||||
|
var maxLeft = this.leftWidth;
|
||||||
|
var maxRight = this.rightWidth;
|
||||||
|
|
||||||
|
if((this._leftShowing && amount > maxLeft) || (this._rightShowing && amount < -maxRight)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.center.style.webkitTransform = 'translate3d(' + amount + 'px, 0, 0)';
|
||||||
|
|
||||||
|
if(amount >= 0) {
|
||||||
|
this._leftShowing = true;
|
||||||
|
this._rightShowing = false;
|
||||||
|
this.right.style.display = 'none';
|
||||||
|
this.left.style.display = 'block';
|
||||||
|
} else {
|
||||||
|
this._rightShowing = true;
|
||||||
|
this._leftShowing = false;
|
||||||
|
this.right.style.display = 'block';
|
||||||
|
this.left.style.display = 'none';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
snapToRest: function(e) {
|
||||||
|
// We want to animate at the end of this
|
||||||
|
this.center.classList.add(this.animateClass);
|
||||||
|
this._isDragging = false;
|
||||||
|
|
||||||
|
// Check how much the panel is open after the drag, and
|
||||||
|
// what the drag velocity is
|
||||||
|
var ratio = this.getOpenRatio();
|
||||||
|
|
||||||
|
if(ratio == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var velocityThreshold = 0.3;
|
||||||
|
var velocityX = e.gesture.velocityX
|
||||||
|
var direction = e.gesture.direction;
|
||||||
|
|
||||||
|
// Less than half, going left
|
||||||
|
//if(ratio > 0 && ratio < 0.5 && direction == 'left' && velocityX < velocityThreshold) {
|
||||||
|
//this.openPercentage(0);
|
||||||
|
//}
|
||||||
|
|
||||||
|
// Going right, less than half, too slow (snap back)
|
||||||
|
if(ratio > 0 && ratio < 0.5 && direction == 'right' && velocityX < velocityThreshold) {
|
||||||
|
this.openPercentage(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Going left, more than half, too slow (snap back)
|
||||||
|
else if(ratio > 0.5 && direction == 'left' && velocityX < velocityThreshold) {
|
||||||
|
this.openPercentage(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Going left, less than half, too slow (snap back)
|
||||||
|
else if(ratio < 0 && ratio > -0.5 && direction == 'left' && velocityX < velocityThreshold) {
|
||||||
|
this.openPercentage(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Going right, more than half, too slow (snap back)
|
||||||
|
else if(ratio < 0.5 && direction == 'right' && velocityX < velocityThreshold) {
|
||||||
|
this.openPercentage(-100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Going right, more than half, or quickly (snap open)
|
||||||
|
else if(direction == 'right' && ratio >= 0 && (ratio >= 0.5 || velocityX > velocityThreshold)) {
|
||||||
|
this.openPercentage(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Going left, more than half, or quickly (span open)
|
||||||
|
else if(direction == 'left' && ratio <= 0 && (ratio <= -0.5 || velocityX > velocityThreshold)) {
|
||||||
|
this.openPercentage(-100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Snap back for safety
|
||||||
|
else {
|
||||||
|
this.openPercentage(0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_endDrag: function(e) {
|
||||||
|
this.snapToRest(e);
|
||||||
|
},
|
||||||
|
_initDrag: function(e) {
|
||||||
|
this.center.classList.remove(this.animateClass);
|
||||||
|
this._isDragging = true;
|
||||||
|
this._startX = 0;
|
||||||
|
this._offsetX = 0;
|
||||||
|
this._lastX = 0;
|
||||||
|
},
|
||||||
|
_handleDrag: function(e) {
|
||||||
|
if(!this._isDragging) {
|
||||||
|
this._initDrag(e);
|
||||||
|
|
||||||
|
this._startX = e.gesture.touches[0].pageX;
|
||||||
|
this._lastX = this._startX;
|
||||||
|
|
||||||
|
this._offsetX = this.getOpenAmount();
|
||||||
|
}
|
||||||
|
console.log('Dragging page', this._startX, this._lastX, this._offsetX, e);
|
||||||
|
var newX = this._offsetX + (this._lastX - this._startX);
|
||||||
|
|
||||||
|
this.openAmount(newX);
|
||||||
|
|
||||||
|
this._lastX = e.gesture.touches[0].pageX;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Grab the sections
|
||||||
|
var page = document.getElementById('page');
|
||||||
|
var leftPanel = document.getElementById('my-left-panel');
|
||||||
|
var rightPanel = document.getElementById('my-right-panel');
|
||||||
|
var controller = new LeftRightPanelViewController({
|
||||||
|
left: leftPanel,
|
||||||
|
leftWidth: 270,
|
||||||
|
right: rightPanel,
|
||||||
|
rightWidth: 270,
|
||||||
|
center: page,
|
||||||
|
animateClass: 'ion-panel-animated'
|
||||||
|
});
|
||||||
|
window.FM.onGesture('tap', function(e) {
|
||||||
|
controller.toggleLeft();
|
||||||
|
}, document.getElementById('left-button'));
|
||||||
|
window.FM.onGesture('tap', function(e) {
|
||||||
|
controller.toggleRight();
|
||||||
|
}, document.getElementById('right-button'));
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
256
example/panel_controller.html
Normal file
256
example/panel_controller.html
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Panels</title>
|
||||||
|
|
||||||
|
<!-- Sets initial viewport load and disables zooming -->
|
||||||
|
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||||
|
<!--<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">-->
|
||||||
|
<link rel="stylesheet" href="../../dist/framework.css">
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<section id="page" class="full-section ion-panel-animated">
|
||||||
|
|
||||||
|
<header class="bar bar-header bar-dark">
|
||||||
|
<button id="left-button" class="button">Left</button>
|
||||||
|
<h1 class="title">Panels</h1>
|
||||||
|
<button id="right-button" class="button">Left</button>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main class="content content-padded has-header">
|
||||||
|
<p><button class="button button-primary">Other Left Side Panel</button></p>
|
||||||
|
<p id="event-log"></p>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer class="bar bar-footer bar-dark">
|
||||||
|
<h3 class="title">Panels</h3>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
<section id="my-left-panel" class="ion-panel ion-panel-active-left">
|
||||||
|
This is my default left side panel!
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="my-right-panel" class="ion-panel ion-panel-active-right">
|
||||||
|
This is my right side panel!
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="my-other-left-panel" class="ion-panel">
|
||||||
|
This is my other left side panel!
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
<script src="../../js/framework/framework-events.js"></script>
|
||||||
|
<script src="../../js/framework/framework-gestures.js"></script>
|
||||||
|
<script src="../../js/framework/ion-panel.js"></script>
|
||||||
|
<script src="../../js/framework/handlers/panel-handler.js"></script>
|
||||||
|
<script>
|
||||||
|
var LeftRightPanelViewController = function(options) {
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
|
this.animateClass = options.animateClass;
|
||||||
|
this.left = options.left;
|
||||||
|
this.leftWidth = options.leftWidth;
|
||||||
|
this.right = options.right;
|
||||||
|
this.rightWidth = options.rightWidth;
|
||||||
|
this.center = options.center;
|
||||||
|
|
||||||
|
this._rightShowing = false;
|
||||||
|
this._leftShowing = false;
|
||||||
|
|
||||||
|
// Bind release and drag listeners
|
||||||
|
window.FM.onGesture('release', function(e) {
|
||||||
|
_this._endDrag(e);
|
||||||
|
}, document.body);
|
||||||
|
|
||||||
|
window.FM.onGesture('drag', function(e) {
|
||||||
|
_this._handleDrag(e);
|
||||||
|
}, document.body);
|
||||||
|
|
||||||
|
window.FM.onGesture('swiperight', function(e) {
|
||||||
|
console.log('SWIPERIGHT');
|
||||||
|
//_this.openPercentage(-100);
|
||||||
|
}, document.body);
|
||||||
|
window.FM.onGesture('swipeleft', function(e) {
|
||||||
|
console.log('SWIPELEFT');
|
||||||
|
//_this.openPercentage(-100);
|
||||||
|
}, document.body);
|
||||||
|
};
|
||||||
|
|
||||||
|
LeftRightPanelViewController.prototype = {
|
||||||
|
toggleLeft: function() {
|
||||||
|
var openAmount = this.getOpenAmount();
|
||||||
|
if(openAmount > 0) {
|
||||||
|
this.openPercentage(0);
|
||||||
|
} else {
|
||||||
|
this.openPercentage(100);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toggleRight: function() {
|
||||||
|
var openAmount = this.getOpenAmount();
|
||||||
|
if(openAmount < 0) {
|
||||||
|
this.openPercentage(0);
|
||||||
|
} else {
|
||||||
|
this.openPercentage(-100);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getOpenAmount: function() {
|
||||||
|
var r = /translate3d\((-?\d+)px/;
|
||||||
|
var d = r.exec(this.center.style.webkitTransform);
|
||||||
|
|
||||||
|
if(d && d.length > 0) {
|
||||||
|
return parseInt(d[1]);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
getOpenRatio: function() {
|
||||||
|
var amount = this.getOpenAmount();
|
||||||
|
if(amount >= 0) {
|
||||||
|
return amount / this.leftWidth;
|
||||||
|
}
|
||||||
|
return amount / this.rightWidth;
|
||||||
|
},
|
||||||
|
openPercentage: function(percentage) {
|
||||||
|
var p = percentage / 100;
|
||||||
|
var maxLeft = this.leftWidth;
|
||||||
|
var maxRight = this.rightWidth;
|
||||||
|
if(percentage >= 0) {
|
||||||
|
this.openAmount(maxLeft * p);
|
||||||
|
} else {
|
||||||
|
this.openAmount(maxRight * p);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
openAmount: function(amount) {
|
||||||
|
var maxLeft = this.leftWidth;
|
||||||
|
var maxRight = this.rightWidth;
|
||||||
|
|
||||||
|
if((this._leftShowing && amount > maxLeft) || (this._rightShowing && amount < -maxRight)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.center.style.webkitTransform = 'translate3d(' + amount + 'px, 0, 0)';
|
||||||
|
|
||||||
|
if(amount >= 0) {
|
||||||
|
this._leftShowing = true;
|
||||||
|
this._rightShowing = false;
|
||||||
|
this.right.style.display = 'none';
|
||||||
|
this.left.style.display = 'block';
|
||||||
|
} else {
|
||||||
|
this._rightShowing = true;
|
||||||
|
this._leftShowing = false;
|
||||||
|
this.right.style.display = 'block';
|
||||||
|
this.left.style.display = 'none';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
snapToRest: function(e) {
|
||||||
|
// We want to animate at the end of this
|
||||||
|
this.center.classList.add(this.animateClass);
|
||||||
|
this._isDragging = false;
|
||||||
|
|
||||||
|
// Check how much the panel is open after the drag, and
|
||||||
|
// what the drag velocity is
|
||||||
|
var ratio = this.getOpenRatio();
|
||||||
|
|
||||||
|
if(ratio == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var velocityThreshold = 0.3;
|
||||||
|
var velocityX = e.gesture.velocityX
|
||||||
|
var direction = e.gesture.direction;
|
||||||
|
|
||||||
|
// Less than half, going left
|
||||||
|
//if(ratio > 0 && ratio < 0.5 && direction == 'left' && velocityX < velocityThreshold) {
|
||||||
|
//this.openPercentage(0);
|
||||||
|
//}
|
||||||
|
|
||||||
|
// Going right, less than half, too slow (snap back)
|
||||||
|
if(ratio > 0 && ratio < 0.5 && direction == 'right' && velocityX < velocityThreshold) {
|
||||||
|
this.openPercentage(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Going left, more than half, too slow (snap back)
|
||||||
|
else if(ratio > 0.5 && direction == 'left' && velocityX < velocityThreshold) {
|
||||||
|
this.openPercentage(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Going left, less than half, too slow (snap back)
|
||||||
|
else if(ratio < 0 && ratio > -0.5 && direction == 'left' && velocityX < velocityThreshold) {
|
||||||
|
this.openPercentage(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Going right, more than half, too slow (snap back)
|
||||||
|
else if(ratio < 0.5 && direction == 'right' && velocityX < velocityThreshold) {
|
||||||
|
this.openPercentage(-100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Going right, more than half, or quickly (snap open)
|
||||||
|
else if(direction == 'right' && ratio >= 0 && (ratio >= 0.5 || velocityX > velocityThreshold)) {
|
||||||
|
this.openPercentage(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Going left, more than half, or quickly (span open)
|
||||||
|
else if(direction == 'left' && ratio <= 0 && (ratio <= -0.5 || velocityX > velocityThreshold)) {
|
||||||
|
this.openPercentage(-100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Snap back for safety
|
||||||
|
else {
|
||||||
|
this.openPercentage(0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_endDrag: function(e) {
|
||||||
|
this.snapToRest(e);
|
||||||
|
},
|
||||||
|
_initDrag: function(e) {
|
||||||
|
this.center.classList.remove(this.animateClass);
|
||||||
|
this._isDragging = true;
|
||||||
|
this._startX = 0;
|
||||||
|
this._offsetX = 0;
|
||||||
|
this._lastX = 0;
|
||||||
|
},
|
||||||
|
_handleDrag: function(e) {
|
||||||
|
if(!this._isDragging) {
|
||||||
|
this._initDrag(e);
|
||||||
|
|
||||||
|
this._startX = e.gesture.touches[0].pageX;
|
||||||
|
this._lastX = this._startX;
|
||||||
|
|
||||||
|
this._offsetX = this.getOpenAmount();
|
||||||
|
}
|
||||||
|
console.log('Dragging page', this._startX, this._lastX, this._offsetX, e);
|
||||||
|
var newX = this._offsetX + (this._lastX - this._startX);
|
||||||
|
|
||||||
|
this.openAmount(newX);
|
||||||
|
|
||||||
|
this._lastX = e.gesture.touches[0].pageX;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Grab the sections
|
||||||
|
var page = document.getElementById('page');
|
||||||
|
var leftPanel = document.getElementById('my-left-panel');
|
||||||
|
var rightPanel = document.getElementById('my-right-panel');
|
||||||
|
var controller = new LeftRightPanelViewController({
|
||||||
|
left: leftPanel,
|
||||||
|
leftWidth: 270,
|
||||||
|
right: rightPanel,
|
||||||
|
rightWidth: 270,
|
||||||
|
center: page,
|
||||||
|
animateClass: 'ion-panel-animated'
|
||||||
|
});
|
||||||
|
window.FM.onGesture('tap', function(e) {
|
||||||
|
controller.toggleLeft();
|
||||||
|
}, document.getElementById('left-button'));
|
||||||
|
window.FM.onGesture('tap', function(e) {
|
||||||
|
controller.toggleRight();
|
||||||
|
}, document.getElementById('right-button'));
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
@ -59,11 +59,9 @@
|
|||||||
isPanelOpen = false;
|
isPanelOpen = false;
|
||||||
|
|
||||||
// remove from <body> so that no panels should be open
|
// remove from <body> so that no panels should be open
|
||||||
// using the replace method so that it changes the classnames in one go
|
var className = document.body.className;
|
||||||
document.body.className = document.body.className
|
className = className.replace(PANEL_OPEN_LEFT, "").replace(PANEL_OPEN_RIGHT, "").trim();
|
||||||
.replace(PANEL_OPEN_LEFT, "")
|
document.body.className = className;
|
||||||
.replace(PANEL_OPEN_RIGHT, "")
|
|
||||||
.trim();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -49,3 +49,21 @@ main > * {
|
|||||||
padding: $contentPadding;
|
padding: $contentPadding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A section is a wrapper that contains objects that are positioned
|
||||||
|
// together. For example, the entire contents of a page could
|
||||||
|
// be a section, to make it easy to drag the section and expose panels
|
||||||
|
// on the left and right sides of the app.
|
||||||
|
.section {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
// A full section is like a section but with a full size
|
||||||
|
.full-section {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 1;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shadow {
|
||||||
|
}
|
||||||
|
|||||||
@ -55,3 +55,10 @@
|
|||||||
-moz-transform: translate3d( ($panelOpenWidth * -1), 0,0 );
|
-moz-transform: translate3d( ($panelOpenWidth * -1), 0,0 );
|
||||||
transform: translate3d( ($panelOpenWidth * -1), 0,0 );
|
transform: translate3d( ($panelOpenWidth * -1), 0,0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.ion-panel-animated {
|
||||||
|
-webkit-transition: -webkit-transform $panelAnimationSpeed ease;
|
||||||
|
-moz-transition: -moz-transform $panelAnimationSpeed ease;
|
||||||
|
transition: transform $panelAnimationSpeed ease;
|
||||||
|
}
|
||||||
|
|||||||
@ -8,3 +8,7 @@ body {
|
|||||||
main {
|
main {
|
||||||
background-color: $baseBackgroundColor;
|
background-color: $baseBackgroundColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.full-section {
|
||||||
|
@include box-shadow(#{-3px 0px 10px rgba(0,0,0,0.2), 3px 0px 10px rgba(0,0,0,0.2)});
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user