On state change, do animation - javascript

Currently I'm working in Vue.js and have a navigation menu that I'd like to animate. What I'm looking to do is show two li elements when a user hovers over one of the navigational buttons.
Currently what I'm doing is setting a data type of showActivities to false by default and setting that to true on mouseenter and false on mouseleave. So this has the items appearing and disappearing on hover but they're not animated. How could animation for this be done?
<ul class="navs">
<li>Schedule</li>
<li #mouseenter="showActivities = true" #mouseleave="showActivities = false">Team Activity</li>
<li v-show="showActivities">tik tak tow</li>
<li v-show="showActivities">Bejewel</li>
<li>Resources</li>
<li class="logout">Logout</li>
</ul>
<script>
export default {
name: 'SideMenu',
data() {
return {
showActivities: false,
};
},
};
</script>

okay if i got you correct you want a type of animation like a slow fade In and Out.
In vuejs transitions, state are attached to CSS classes that can be called and modified ass you want it to be. The doc is clearer about it
Vuejs Transitions
for example if you add this in your css section the transition will be a slow fade In and Out:
.fade-enter-active, .fade-leave-active {
transition: opacity .5s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
}

Related

Navbar opacity on scroll vuejs

I want to change the opacity of my fixed navbar background when user scrolling the page. Initially navbar background should be transparent and when scrolling down it background needs to be change to white.
Like this example https://codepen.io/michaeldoyle/pen/Bhsif
I have found various examples for this scenario using jquery. But I need to achieve this using vuejs.
$(window).scroll(function() {
if ($(document).scrollTop() > 200) {
$('nav').addClass('transparent');
} else {
$('nav').removeClass('transparent');
}
});
I tried above code inside my vue page. I put it inside mounted(). But it doesn't work. I need to done this using vue. Not like above jquery.
<nav class="navbar navbar-inverse">
<ul class="nav menu">
<li>
<router-link to="/about" #click.native="closeNavBarFromChild">About</router-link>
</li>
<li class="hidden-lg hidden-md">
<router-link to="/product" #click.native="closeNavBarFromChild">Product</router-link>
</li>
</ul>
</nav>
This is how my navbar component looks like.
nav.navbar{
-webkit-transition: all 0.4s ease;
transition: all 0.8s ease;
}
.navbar-inverse {
background-color: rgba(255,255,255,0);
}
nav.navbar.transparent {
background-color:rgba(0,0,0,1);
}
this is the css part that i used.
Set your listener in created lifecycle hook:
export default {
created () {
window.addEventListener('scroll', this.onScroll);
},
destroyed () {
window.removeEventListener('scroll', this.onScroll);
},
methods: {
onScroll (event) {
// add/remove class
}
}
}

Opacity transition works on fade out, but not fade in

This is frustrating me to no end. Before I post the code, here's a summary:
The goal, in simple terms: when I double click X, I want it to fade out; when I click Y, I want X to fade in.
The method: I'm using CSS to create the actual fade-in and fade-out "animations." I'm using JavaScript to apply the classes when necessary using a little trickery.
The problem: the fade-in transition doesn't work -- the element just appears instantly. What is driving me insane is the fact that the fade-in, when instantly added back onto a faded-out object, works perfectly. I'll explain this better as a comment in the JS code.
(Yes, I've added opacity: 1 and transition: opacity onto the base elements. It had no effect at all.)
The code:
CSS
*.fade-out {
opacity: 0;
transition: opacity 400ms;
}
*.fade-in {
opacity: 1;
transition: opacity 400ms;
}
*.hide {
display: none;
visibility: hidden;
}
JavaScript
$( '#ArtistEmblem' ).on( 'dblclick', function() {
fadeOut($( '#ArtistEmblem' ));
fadeIn($( '#btnShowLogo' ));
});
$( '#btnShowLogo' ).on( 'click', function() {
fadeOut($( '#btnShowLogo' ));
fadeIn($( '#ArtistEmblem' ));
});
function fadeOut(element) {
element.addClass( 'fade-out' );
setTimeout( function () {
element.addClass( 'hide' );
/*
* I tried immediately adding the 'fade-in' class here
* and it worked -- as soon as the element faded out, it faded
* back in (using the CSS transition). However, outside of this,
* it REFUSES to work; everything appears instantly
*/
console.log('timer triggered');
}, 400);
}
function fadeIn(element) {
element.removeClass( 'hide' );
element.removeClass( 'fade-out' );
element.addClass( 'fade-in' );
}
Relevant HTML
<div id="ArtistEmblem">
<img src="img/logo_artist_2.png" />
</div>
<div id="PopMenu" class="collapse">
<article>
<header>
<b>Debug Menu</b>
</header>
<section>
<button id="btnOpenOverlay">Open Overlay</button>
<button id="btnShowLogo" class="hide">Show Logo</button>
<button id="btnClose">Close Menu</button>
</section>
</article>
</div>
I apologize if this is something obvious but I've wasted far too much time trying to solve it. I am also open to better, faster, or more efficient solutions if that would be the best answer. Thanks in advance!
The problem is that the initial opacity of "hidden" element is 1 by default. You just need to set it to 0. And also remove display: none –
*.hide {
opacity: 0;
}
Also I would do a little refactoring and remove setTimeout:
$('#ArtistEmblem').on('click', function() {
fade($('#btnShowLogo'), $(this));
});
$('#btnShowLogo').on('click', function() {
fade($('#ArtistEmblem'), $(this));
});
function fade(inElement, outElement) {
inElement.removeClass('hide');
inElement.addClass('fade-in');
outElement.removeClass('fade-in');
outElement.addClass('fade-out');
}
If you don't want the hidden element to occupy space and you want it to be displayed-none, then you need to set display: block before starting the fadeOut.
I know you're asking for a JS heavy answer, but I highly recommend toggling a class of "active", "open" or something similar and using CSS with the transition. Less is more here.
Here's an example fiddle of something I've transitions not only the opacity, but also the z-index. That's the key with these transitions if you intend on having any elements below such as buttons that require hovering, clicking, etc.
JS Fiddle
Key parts:
.container {
z-index: -1;
opacity: 0;
transition: z-index .01s 1s, opacity 1s;
}
.container.active {
transition: z-index 0s, opacity 1s;
z-index: 500;
opacity: 1;
}
EDIT
I was just messing around with this type of thing for my own project, and observing how beautiful Stripe handles their navigation bar. Something so simple changes everything, and that's pointer-events. If you're okay with its support, (notable no ie. 10) this is infinitely easier to integrate. Here's another fiddle of the simulation in a nav bar.
The key part is pointer-events: none, as it ignores click events if set to none, almost as if it wasn't there, yet visibly it is. I highly recommend this.
https://jsfiddle.net/joshmoxey/dd2sts7d/1/
Here is an example using Javascript Animate API. Animate API is not supported in IE/Edge though.
var element = document.getElementById("fade-in-out")
var button = document.getElementById("x")
button.addEventListener("click", function(event) {
element.animate([{opacity: 1, visibility: "visible"},{opacity: 0, visibility: "hidden"}], {duration: 2000})
setTimeout(function() { element.remove() }, 2000)
})
button.addEventListener("dblclick", function(event) {
element && element.animate([{opacity: 0}, {opacity: 1}], {duration: 2000})
})
<input id="x" type="button" value="Click here" />
<div id="fade-in-out"> FADE ME </div>

Fading a component in and fading another one out React.js

I just recently started getting into using React.js and to make it easier for myself I'm trying to recreate projects I've made in the past, but instead of using jQuery like I did in the past I'm completely avoiding jQuery and using only React.
I tend to do animations where a div would fade in as another fades out like this:
$("#start").click(function() {
$("#h1").fadeOut(750);
$("#h2").delay(500).fadeIn(750);
$("#h1").css("z-index", 0);
$("#h2").css("z-index", 1);
});
I was wondering how can I reproduce this fade in and out effect without jQuery
(I know CSS animations could change the opacity, but the opacity isn't the only thing I'm trying to change, this affects the display property as well).
A simple way is to use CSS transitions. Basically you just add a class to an element, and define a transition in the CSS and it does the rest for you
There is a tutorial here
https://www.w3schools.com/css/css3_transitions.asp
Which does a good job of explaining how it all works with examples and a playground for you to try your own
The CSS Transition group add-on might help, it let's you define transitions like this:
JS:
<ReactCSSTransitionGroup
transitionName="example"
transitionEnterTimeout={500}
transitionLeaveTimeout={300}>
{items}
</ReactCSSTransitionGroup>
CSS:
.example-enter {
opacity: 0.01;
}
.example-enter.example-enter-active {
opacity: 1;
transition: opacity 500ms ease-in;
}
.example-leave {
opacity: 1;
}
.example-leave.example-leave-active {
opacity: 0.01;
transition: opacity 300ms ease-in;
}
One option would be to use a framework, like react-bootstrap, which includes a lot of the UI components you need for any given project. It includes a Fade component. Documentation can be found here: https://react-bootstrap.github.io/components.html#utilities
class Example extends React.Component {
constructor(...args) {
super(...args);
this.state = {};
}
render() {
return (
<div>
<Button onClick={()=> this.setState({ open: !this.state.open })}>
click
</Button>
<Fade in={this.state.open}>
<div>
<Well>
THIS CONTENT WILL FADE
</Well>
</div>
</Fade>
</div>
);
}
}
ReactDOM.render(<Example/>, mountNode);

JavaScript Navigation Button Code Issue

I am trying to make this button work so it does not just "instantly" display the menu. When I added the .style.WebkitTransition content to my code, it broke the functionality. The button works without it, but it displays the content instantly. I want it to transition smoothly like it does on nice websites. I don't need a demonstration demo or anything, I just need a JavaScript guru to tell me how to go about achieving my desired results from this code. Thank you!
JavaScript
function mobileFunction() {
var x = document.getElementById("JavaMenu").style.WebkitTransition = "ease 1s";
if (x.className === "navbar") {
x.className += " responsive";
} else {
x.className = "navbar";
}
}
Use max-height instead of height in css
function mobileFunction() {
var x = document.getElementById("JavaMenu");
x.style.transition = "ease 1s";
document.getElementById('JavaMenu').classList.toggle('responsive');
}
.navbar{ max-height:0; overflow:hidden; transition: ease 1s}
.navbar.responsive{ max-height: 200px;}
<span onclick="mobileFunction()">Toggle Menu</span>
<ul id="JavaMenu" class="navbar">
<li>Menu 1</li>
<li>Menu 2</li>
<li>Menu 3</li>
</ul>
You can't possibly animate display property.
Use should add top, left | margins | transform | opacity to achieve effective animation effect, display: block only shows the element. The most effective way of animating a menu is to hide it by display: none and throw it away from your view X = -MENU_WIDTH LEFT or X = SCREEN_WIDTH + MENU_WIDTH RIGHT then do a sliding effect
// CSS
#JavaMenu {
// hide it by default
display: none;
// width: 320px;
// throw it off screen, give it -width or more than -width to effectively hide it
transform: translateX(-320px);
// you can just simply put the transition here:
// transition: 1s ease;
}
// the show
#JavaMenu.responsive {
// show it
display: block;
// move it on screen;
transform: translateX(0);
}
// JS
// then toggle the classes as you did in your JS
// this will give it animation effect
Also instead of using .className() you can actually use .classList.contains('navbar') to check if navbar class exists, classList.add(class) to add and classList.remove(class) to remove.
hope that helps.

AngularJS ng-class add/remove animation do not apply/fire

I'm trying to add an animation on add/remove on the <a>-Tag, based on the toggleBookmark function. The active class is added when it returns true and works fine.
However, the ng-add or icon__bookmark-add animation does not fire on the <a> tag.
Why? What am I doing wrong?
HTML:
<li ng-repeat="event in events | filter:searchText">
<div ng-click="toggleBookmark(event.id)" class="events-list__icons">
<a ng-class="{active:isBookmarked(event.id)}" class="icon__bookmark"></a>
</div>
</li>
Controller:
$scope.isBookmarked = (id) ->
BookmarkService.isBookmarked(id) // this just returns true or false
$scope.toggleBookmark = (id) ->
BookmarkService.toggleBookmark(id) // returns nothing
CSS:
.icon__bookmark.ng-add,
.icon__bookmark.ng-add-active,
.icon__bookmark-add,
.icon__bookmark-add-active {
animation: flip .6s ease-in-out;
backface-visibility: visible;
}
ng-class="{active:isBookmarked(event.id)}" only adds the class active.
You should redefine your CSS so that 'active' runs the animation. See this jsfiddle: http://jsfiddle.net/nicolasmoise/XaL9r/1/
You can also use the ngAnimate service and create a new directive for .events-list__icons.
$animate.addClass(element, 'active')
Would add active, active-add (to set up the animation), and active-add-active (to run the animation) classes.

Categories