So what I want to achieve is that as you open the content pane, based on the ratio of how open it is, the main content shrinks.
Basically I am trying to emulate the airbnb application on ios when you open their side menu.
I started trying to play around with the height and width of the pane but no luck so far. If anyone has any ideas some help would be appreciated
The <side-menu-content> directive exposes $scope.sideMenuContentTranslateX - you may be able to $watch this and set a 3d value on the <side-menu-content>.
well this is what I have so far. Itās not perfect and needs a bit of tinkering, but IMO itās a good start:
app.directive('shrink', function($timeout) {
return {
restrict: 'A',
link: function($scope, $element, $attr) {
// Run in the next scope digest
$timeout(function() {
// Watch for changes to the x var which is a value between 0 and 275
$scope.$watch('sideMenuContentTranslateX', function(x) {
var toScale = (1- Math.abs(x/275));
//we do not want the side menu to be less than 70 percent of it's original size
if(toScale > 0.7){
$element[0].style.webkitTransform += ' scaleY('+ toScale +')';
}
//if we are at the end of the animation then skew it
if(x === 275){
$element[0].style.webkitTransform += ' scaleY(0.7) skewY(-20deg)';
}
});
});
}
};
});
@mlovekovsky Looks a little funky but itās a good start. You should take a look at this article about 3d transforms. Instead of scaleY, try rotateY. It seems this could be a better way to product the desired effect.
thanks for the heads up! Going to play around with the different transforms, rotateY would be better since it would prevent the images looking squished
I think a lot of what will make this work is the handling of the background. In your example, the area behind the content has color to differentiate between the two. Also, check out the fade bar directive the ionic guys made up. You can set a value to change as the ratio changes.
.directive('fadeBar', function ($timeout) {
return {
restrict: 'E',
template: '<div class="fade-bar"></div>',
replace: true,
link: function ($scope, $element, $attr) {
// Run in the next scope digest
$timeout(function () {
// Watch for changes to the openRatio which is a value between 0 and 1 that says how "open" the side menu is
$scope.$watch('sideMenuController.getOpenRatio()', function (ratio) {
// Set the transparency of the fade bar
$element[0].style.opacity = Math.abs(ratio);
});
});
}
};
})
well I based myself off of the fade bar example.
What I did was I made my side-menu takes up 100% of the screen, so that when the side āshrinks awayā it does so with the background color still visible.
I wanted to use a fade bar, but my background is a gradient, so it looks kind of awkward if part of it fades on the top.
Hope what I wrote makes sense heh
@mlovekovsky, so I have a few codepens that I got together that I think could do the trick.
The first one just shows how to work with the getOpenRatio event for the sideMenuController.
Here Iām fading the content base on how open the menu is. In this one, Iām playing with some css 3d transforms to get the effect that seems similar to that first image you posted. These two examples could get you in the right direction.
The only thing Iām curious about is how to set these values based on the open ratioā¦that is how can a value of 0 or 1 be used to go between all the css values needed. What do you think?
hmm ya working with the ratio is a bit more complex since you need to find a the proper way of calculating what values to attribute to the CSS.
What works a bit better IMO is to work with the sideMenuContentTranslateX value. If you know your X limit (i.e. in my case it is 275px) then I create an inverse proportion of how much to scale by: var toScale = (1 - Math.abs(x / 275));
So then to make it menu smaller as it moves to the side I would do something like:
I have another quick question.
If I scale it too much, then the main content simply goes off the screen. Do you know how to limit how much the side menu slides by.
Currently the default is 275px, but if letās say I want to block the side menu to only slide 120px instead, how would I go about doing that?
You can do into the sass files and change the variable that dictates the width of the side menu content then build your own version of ionic that way. The Ionic guys have a nice tutorial on customizing the sass files so take a look at it
To simplify the problem what I did was disable the drag (sine the interaction got a little funky when dragging).
Then my directive became super simple!
.directive('shrink', function($timeout) {
return {
restrict: 'A',
link: function($scope, $element, $attr) {
// Run in the next scope digest
$timeout(function() {
// Watch for changes to the x var which is a value between 0 and 275
$scope.$watch('sideMenuContentTranslateX', function(x) {
if (x === 275) {
$element[0].style.webkitTransform += ' scaleY(0.6) scaleX(0.6) translateX(-140px)';// skewY(-20deg)';
}
});
});
}
};
I scale it down then I push the menu back on the screen. It doesnāt have the āopen doorā effect but it does have a nice shrinking away effect.
I will take a look at the SASS tutoril now so I donāt have to do the translateX(-140px) part in the directive.
hmm i noticed something weird.
After shrinking the content I noticed itās still active.
So when itās small and to the side i can scroll it and actually click on the elements to navigate it.
Any idea on how to disable that?
This is true when using the default slide function. Itās something Iāve noticed and iām not quite sure how to fix it. I know JQM creates a div that overlays the whole content and when the user taps that, it toggles the menu to close.
Maybe a similar method can be applied to watch touches on the content pane and toggle the menu to close?