I am trying to toggle between two animation classes within my ng-view. This is how I have my ng-view setup in my html:
<div id="animation-container" class="view-animate-container">
<div id="ng-view" ng-view class="view-animate"></div>
</div>
And here is the css for my first animation
.view-animate.ng-enter, .view-animate.ng-leave {
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.8s;
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.8s;
display:block;
position:absolute;
top:0;
left:0;
}
.view-animate.ng-enter {
-webkit-transform: translate3d(100%, 0, 0);
}
.view-animate.ng-enter.ng-enter-active {
-webkit-transform: translate3d(0, 0, 0);
}
.view-animate.ng-leave.ng-leave-active {
-webkit-transform: translate3d(-100%, 0, 0);
}
2nd animation:
.view-leave.ng-enter, .view-leave.ng-leave {
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.8s;
-moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.8s;
-o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.8s;
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.8s;
display:block;
position:absolute;
top:0;
left:0;
}
.view-leave.ng-enter {
opacity:0;
-webkit-transform: translate3d(-100%, 0, 0);
}
.view-leave.ng-enter.ng-enter-active {
opacity:1;
-webkit-transform: translate3d(0, 0, 0);
}
.view-leave.ng-leave.ng-leave-active {
opacity:0;
-webkit-transform: translate3d(100%, 0, 0);
}
All I'm trying to do is change the class from view-enter to view-leave when the back button is clicked.
<a id="back-btn" class="btn back" href="javascript:history.back()">BACK</a>
This Jquery code I wrote almost got the job done, but not 100%:
$("#back-btn").click(function(){
$("#ng-view").attr('class','view-leave');
});
It seemed to animate the leaving container in the right direction, but not the entering container. So I'm looking for a simple solution to what seems like a simple problem.
You don't even need jQuery for this, you can use Angular's ng-class attribute. Add an ng-click to your back button which calls a function inside your controller. Something like this:
In your HTML:
<div id="animation-container" class="view-animate-container">
<div id="ng-view" ng-view class="view-animate" ng-class="animationClass"></div>
</div>
<a class="btn back" href="javascript:history.back()" ng-click="toggleAnimation()">BACK</a>
In your Controller:
$scope.animationClass = "view-enter";
$scope.toggleAnimation = function() {
if ($scope.animationClass === "view-enter") {
$scope.animationClass = "view-leave";
} else if ($scope.animationClass === "view-leave") {
$scope.animationClass = "view-enter";
}
};
I found a different way with the new $routeChangeStart event.
This solution saves history to check if the next page is actually the previous page.
Place this in your controlller:
$scope.backward = false;
$scope.history = [];
$scope.$on('$routeChangeStart', function(next, current) {
var previous = $scope.history[$scope.history.length - 2];
if (previous && current.originalPath === previous.originalPath) {
$scope.backward = true;
$scope.history.pop();
} else {
$scope.backward = false;
$scope.history.push(current);
}
});
Then use a container around your ng-view with an ng-class reacting to the $scope.backward.
<div ng-class="{'backward': backward}">
<ng-view class="view-animate">
</div>
And have two CSS animations. The forward on .view-animate or whatever class you use for your ng-view. And the backward on .backward .view-animate.
Just for anyone else that might be looking for a simple solution to this question, expanding off #muenchdo answer. I set a timeout to revert to the previous animation after the transition was over.
like this:
$scope.animationClass = "view-enter";
$scope.toggleAnimation = function() {
$scope.animationClass = "view-leave";
$timeout(function() {
$scope.animationClass = "view-enter";
}, 350);
}
This was the simplest way I could find out there, hopefully this helps someone out there that is looking for a simple solution to what seems like simple functionality.
Related
My jquery/js code is not waiting for images loaded to fade out. What is the problem?
$('#entry').css('background-image','url(../img/backg3.jpg)').waitForImages(function() {
$('#load').fadeOut(1000);
$('.spinner').fadeOut(1000);
});
/*******************
Loading
*********************/
#load {
position:absolute;
height:100vh;
width:100vw;
background-color:#ddd;
z-index:1000;
/*-moz-transition:all 2s ease-out;
-webkit-transition:all 2s ease-out;
-webkit-transition:all 2s ease-out;
transition:all 2s ease-out;*/
}
#-o-keyframes spin {
100%{
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
#-moz-keyframes spin {
100%{
-moz-transform: rotate(360deg);
transform: rotate(360deg);
}
}
#-webkit-keyframes spin {
100%{
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
#keyframes spin {
100%{
transform: rotate(360deg);
}
}
.spinner {
position:absolute;
top:45vh;
left:45vw;
width:5vh;
height:5vh;
border: 6px solid #F90;
border-left-color:#FC3;
border-bottom-color:#FF6;
border-right-color:transparent;
border-radius:100%;
animation: spin 400ms infinite linear;
margin: auto;
}
<div id="load">
<div class="spinner"></div>
</div>
So I want while my background image is loading to hold the spinner, but it fade outs without image.
Page - http://sarosacramento.com/
Plugin - https://github.com/alexanderdickson/waitForImages
From their github page, it looks like you're supposed to apply .waitForImages() to an element selector (which either has image children or images in its CSS). In your code, instead of applying it to the selector, you're first adding CSS, then trying to apply .waitForImage(), which won't work, since the .css() doesn't return a selector. Try instead:
$('#entry').waitForImages(function () {
$('#load').fadeOut(1000);
$('.spinner').fadeOut(1000);
});
for the JS and just put the background image in normal CSS:
#entry {
background-image: url(../img/backg3.jpg);
}
(If you must set it via JS, do that before applying .waitForImages() to $("entry"):
$('#entry').css('background-image','url(../img/backg3.jpg)');
$('#entry').waitForImages(function () { ...
though I haven't actually tested this.)
Here's an example: http://jsfiddle.net/aq9t6kvk/2/. (It mostly uses your code, but I used some different images that wouldn't be in our caches already. But since the first one might already be loading while JSFiddle is "initializing the awesome", there are some backups for subsequent "Run"s.)
I am trying to make a menu like the semantic UI but I only achieved to click the menu button and open the menu and vice versa. I use toggle class to show the sidebar but I dont know if this way is completely right:
<div class="menu-button" id="menu-button"></div>
$('#menu-button').click(function(event) {
$('#hide-menu').toggleClass('show-menu');
});
.hide-menu {
background-color:#336ca6;
position: absolute;
top:0;
right:0;
z-index: 1;
width: 300px;
height: 100%;
-webkit-transform: translate3d(300px,0,0);
-moz-transform: translate3d(300px,0,0);
-o-transform: translate3d(300px,0,0);
-ms-transform: translate3d(300px,0,0);
transform: translate3d(300px,0,0);
-webkit-transition: all 0.3s linear;
-moz-transition: all 0.3s linear;
-ms-transition: all 0.3s linear;
-o-transition: all 0.3s linear;
transition: all 0.3s linear;
}
.show-menu {
-webkit-transform: translate3d(0,0,0);
-moz-transform: translate3d(0,0,0);
-o-transform: translate3d(0,0,0);
-ms-transform: translate3d(0,0,0);
transform: translate3d(0,0,0);
}
I've tried the event propagation but I can't manage to make it play.
Edit your js code to following
$('#menu-button').click(function(e){
e.stopPropagation();
$('#hide-menu').toggleClass('show-menu');
});
$('#hide-menu').click(function(e){
e.stopPropagation();
});
$('body,html').click(function(e){
$('#hide-menu').removeClass('show-menu');
});
Hope this will work.
Here is fiddle.
http://jsfiddle.net/ex8ddv5q/1/
For a different take on it check this Fiddle
$('#menu-button').click(function (evt) {
evt.stopPropagation();
$('#hide-menu').toggleClass('show-menu');
});
$('body,html').click(function (e) {
var container = $("#hide-menu");
if (!container.is(e.target) && container.has(e.target).length === 0) {
container.removeClass('show-menu');
}
});
In case somebody comes here and is using Angular instead of JQuery, we got this to work with something similar to the above like this:
public toggleSideNav() {
this.showSideNav = !this.showSideNav;
console.log('show side nav', this.showSideNav);
event.stopPropagation();
}
public hideSideNav() {
this.showSideNav = false;
console.log('hide side nav');
}
And this in the template:
<app-sidenav></app-sidenav>
<div class="main-body" (click)="applicationService.hideSideNav()">
<router-outlet></router-outlet>
</div>
Suppose if your sidebar width is 270px,check the mouse click coordinate.If it's greater give its style left attribute as -270px;
function handleMousePos(event) {
var mouseClickWidth = event.clientX;
if(mouseClickWidth>=270){
document.getElementById("mySidenav").style.left='-270px'
}
}
document.addEventListener("click", handleMousePos);
Here is my sample:https://codepen.io/johncy/pen/oMyzZr
$('body').click(function(){
$('#hide-menu').removeClass('show-menu');
});
Right now I am using Rico St.Cruz brillant working query.transit library but now I have to change some things to do with classes instead though not being this firm in CSS transitions. I tried to
replace:
JS:
$("#target_element").mouseenter( function() {
$("#arr_left")
.transition( { x: 3 }, 300, 'easeOutSine' )
.transition( { x: 0 }, 300, 'easeInSine' );
};
}
with:
JS:
$("#target_element").mouseenter( function() {
$("#arr_left").addClass('hint');
}
CSS:
#arr_left.hint {
-webkit-animation: hint_left 600ms;
-moz-animation: hint_left 600ms;
-o-animation: hint_left 600ms;
animation: hint_left 600ms;
}
#keyframes hint_left {
0%, 100% {
-webkit-transform: translate(0);
-moz-transform: translate(0);
-o-transform: translate(0);
transform: translate(0);
-webkit-animation-timing-function: cubic-bezier(0.39, 0.575, 0.565, 1); /* easeOutSine */
animation-timing-function: cubic-bezier(0.39, 0.575, 0.565, 1);
}
50% {
-webkit-transform: translate(3px);
-moz-transform: translate(3px);
-o-transform: translate(3px);
transform: translate(3px);
-webkit-animation-timing-function: cubic-bezier(0.47, 0, 0.745, 0.715); /* easeInSine */
animation-timing-function: cubic-bezier(0.47, 0, 0.745, 0.715) ;
}
}
but this new code does not work.
1) What I am doing wrong here?
2) What is the shortest code (browser compatible) to reach this?
Addition: I’d like to keep the "hint" class generic to address via JS with each arrow has a specific own translation property. Thanks so much in advance!
EDIT:
http://jsfiddle.net/bg7w6jmh/61/
I added a fiddle. Note: I need the extra container for the arrow because it’s animated (rotated) in other places.
The aim is to make the little arrow smoothly move to the left 3px and back in to indicate the target_element being animated on click or swipe. For the values and easing see the keyframes. Thanks for help!
Happens to be ok now. While I was working endlessly on my fiddle I recognized that I missed a round bracket at the end of my event declaration…
I'm encountering some strange behavior in one of my web apps when using Angular's routeProvider as a template engine. Although it works, it doesn't make sense to me why it works.
Whats happening is that during transitions from page to page (mostly in safari/mobile safari) you will see the page you're transitioning to flicker in the front of view before transitioning in. How I fixed this problem is just by adding a slash to the end of the href's url, ex:href="#/home/" instead of href="#/home . Does anyone out there know why adding a "/" to the url would fix such a problem?
I set up the routeProvider like this:
.config(function($routeProvider) {
$routeProvider.when('/home', {
controller : 'HomeCtrl',
templateUrl : './home.html'
}).when('/pageTwo', {
controller : 'twoCtrl',
templateUrl : './pageTwo.html'
}).otherwise({
redirectTo: '/home'
});
})
My html like this:
<ul id="nav">
<li>
HOME
</li>
<li>
TWO
</li>
</ul>
and css like this:
.view-animate-container {
position:relative;
width: 100%;
height: 100%;
}
.view-animate {
position: absolute;
width: 100%;
height: 100%;
-webkit-perspective: 1000;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.view-animate.ng-enter, .view-animate.ng-leave {
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
-moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
-o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
}
.view-animate.ng-enter {
opacity:0;
-webkit-transform: translate3d(20%,0,0);
transform: translate3d(20%, 0, 0);
}
.view-animate.ng-enter.ng-enter-active {
display: block;
-webkit-transform: translate3d(0,0,0);
transform: translate3d(0, 0, 0);
opacity:1;
}
.view-animate.ng-leave.ng-leave-active {
-webkit-transform: translate3d(-20%,0,0);
transform: translate3d(-20%, 0, 0);
opacity:0;
}
Is there a reason why you link to the hash instead of the route itself?
Have you tried changing your links to Home instead of href="#/home" ?
Angular will manage the hash for you, (or not, if your browser supports pushState).
I am using CSS3 Transitions, and I am wondering if once the animation is started with:
-webkit-transform: translate3d(-100%, 0, 0);
Can I somehow increase the speed which was pre-set using:
-webkit-transition: all 10s linear;
I want the speed to be 2s using jQuery.
It appears you can with this.style["-webkit-transition"]
http://jsfiddle.net/X5shh/
HTML
<div class="one"></div>
CSS
.one
{
-webkit-transition: all 10s linear;
width:200px;
height:20px;
background:green;
}
.two
{
-webkit-transform: translate3d(100%, 0, 0);
}
jQuery
$("div").click(function(){
$(this).toggleClass("two");
this.style["-webkit-transition"] = "all 2s linear"
});
EDIT
or
this.style["-webkit-transition-duration"] = "2s";