How to use ng-animate to add slide effect on menu - css

I am trying to implement a slide effect using ng-animate and CSS styles, but can't figure out what's wrong with my code...
Can I do this using values in percentages for min-height and max-height? I cant use fixed values in px.
JSFIDDLE
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
Click to toggle menu
<div class="menu" ng-show="collapsed" ng-animate="{show: 'menu-show', hide: 'menu-hide'}">
<div class="files">
<input type="checkbox" />
<label>first</label>
<input type="checkbox" />
<label>second</label>
</div>
<div class="diffs">
<input type="checkbox" />
<label>first</label>
<input type="checkbox" />
<label>second</label>
</div>
</div>
</div>
CSS:
.menu-show-setup, .menu-hide-setup {
transition:all 0.5s ease-out;
overflow:hidden
}
.menu-show-setup {
max-height:0;
}
.menu-show-setup.menu-show-start {
max-height:25%;
}
.menu-hide-setup {
max-height:25%;
}
.menu-hide-setup.menu-hide-start {
max-height:0;
}

First ensure you have angular and angular-animate loaded.
The CDN for angular-animate is ...
<script src="//ajax.googleapis.com/ajax/libs/angularjs/X.Y.Z/angular-animate.js"></script>
Then you need to reference the animations that ngAnimate gives ...
https://docs.angularjs.org/api/ngAnimate
For example, ng-if when switched from false to true will add the class .fade AND .ng-enter to the element on which the ng-if is located. These classes will be automatically removed after a short time. ngAnimate does this for you.
What you HAVE to do is to style what these classes do ...
example:
.fade.ng-enter {
transition:0.5s linear all;
opacity:0;
}
/* The finishing CSS styles for the enter animation */
.fade.ng-enter.ng-enter-active {
opacity:1;
}
now ng-animate will animate from .fade.ng-enter to .fade.ng-enter.ng-enter-active
if you do not define these styles ng-animate will do nothing.
You will see classes being added and remove by ng-animate if you inspect the relevant element in your browser's develop tools. If you cannot see these classes being added and removed then something is wrong with your loading of angular or ng-animate.

Related

Vue transitioned element not showing after transition is complete

I'm trying to animate an element to full browser height when the user clicks on the top bar. The animation works, but once the (enter) animation is finished the container jumps back to zero height, while it's supposed to stay until the user clicks the close button.
How do I make the container stay 100vh when the animation is finished?
I tried adding height: 100vh; on the element, but by doing that the transition animation stopped working. (by removing the height, the animation works but the element disappears)
Not sure if it matters, but I changed v-if into v-show and also added a key on the container, but that didn't seem to make a difference.
Here's a link to my code. And to view the animation.
<!-- AboutMeComponent.vue -->
<template>
<div>
<div v-show="!extended" class="small-container" #click="extended = !extended">
<h4>
CLICK ME
</h4>
</div>
<ExtendTransition>
<div v-show="extended" key="1" class="main-container">
<div class="icon-container">
<a v-show="extended" href="#" #click="extended = !extended">
<font-awesome-icon icon="times"/>
</a>
</div>
</div>
</ExtendTransition>
</div>
</template>
<!-- ExtendTransition.vue -->
<template>
<transition appear name="extend" mode="out-in">
<slot></slot>
</transition>
</template>
<style lang="scss">
.extend-enter-active,
.extend-leave-active {
transition: 3s;
}
.extend-enter-to,
.extend-leave {
height: 100vh;
}
.extend-leave-to {
height: calc(20px + 1vw);
}
.extend-enter {
height: calc(40px + 3vw);
}
</style>
A transition only is applied while the transition is playing. Once the transition finished, all transition classes are removed. This means that your element must have the CSS you want it to have after the transition is finished. You can then use the transition classes to set the initial state and define the transition to get to that point, and from that point to the initial state.
The easiest way to solve this problem is by making ExtendTransition.vue the only component that worries about the transition, and using a wrapper that wraps the thing you want to extend.
<template>
<transition appear name="extend" mode="out-in">
<div class="extend-transition-wrapper" v-show="extended">
<slot></slot>
</div>
</transition>
</template>
<script>
export default {
props: {
extended: {
type: Boolean,
default: false
}
}
};
</script>
The only thing you then have to do is to set the default state of your wrapper:
.extend-transition-wrapper {
height: 100vh;
will-change: height;
position: relative;
}
In your ABoutMeComponent.vue you then use a prop to show and hide the content:
<ExtendTransition :extended="extended">
<div class="main-container">
<div class="icon-container">
<a v-show="extended" href="#" #click="extended = !extended">
<font-awesome-icon icon="times"/>
</a>
</div>
</div>
</ExtendTransition>
And finally you set .main-container to always have a height of 100%. Since we set the wrapper to have position: relative, this will force the main container to become the height of that element.

Angular Animation for ng-repeat not working

I would like to do a simple fade in animation for the items that my ng-repeat generates, I followed all the instructions on the ngAnimate site but still no dice.
Here is my module
var app = angular.module('testApp', ['ngRoute','ngAnimate']);
Here is the ng-repeat in my markup
<div class="col-md-6 col-xs-12" ng-repeat="mark in marks" ng-animate="'animate' ">
<div class="col-md-12 well well-sm" >
<div data-ng-include="'./Partials/mark.html'" />
</div>
</div>
Here is some CSS for the animation
.animate-enter {
-webkit-transition: 1s linear all; /* Chrome */
transition: 1s linear all;
opacity: 0;
}
.animate-enter.animate-enter-active {
opacity: 1;
}
And here are the scripts I'm including
<!-- JS -->
<!-- Vendor Libs -->
<script src="./js/angular.min.js"></script>
<script src="./js/angular-animate.min.js"></script>
<script src="./js/angular-route.js"></script>
<script src="./js/jquery.min.js"></script>
<!-- UI Libs -->
<script src="./js/bootstrap.min.js"></script>
<!-- App libs -->
<script src="./js/app.js"></script>
<script src="./Controllers/MarksController.js"></script>
<script src="./Controllers/ViewMarkController.js"></script>
<script src="./Services/marksService.js"></script>
*) All the required CSS files are also linked in my header.
*) Link to Project: https://www.mediafire.com/?6h1qwcrblqczjpr
You don't need the ng-animate="'animate'" directive.
All you need to do is add a class to the intended item, and add the relevant angualrjs animate classes.
Please see the code below:
.animate-repeat {
-webkit-transition: 1s linear all;
transition: 1s linear all;
}
.animate-repeat.ng-move,
.animate-repeat.ng-enter,
.animate-repeat.ng-leave {
-webkit-transition:all linear 0.5s;
transition:all linear 0.5s;
}
.animate-repeat.ng-leave.ng-leave-active,
.animate-repeat.ng-move,
.animate-repeat.ng-enter {
opacity:0;
max-height:0;
}
.animate-repeat.ng-leave,
.animate-repeat.ng-move.ng-move-active,
.animate-repeat.ng-enter.ng-enter-active {
opacity:1;
max-height:40px;
}
The HTML:
<div ng-controller="RestaurantsController">
<input type="text" ng-model="search_cat.name">
<br>
<b>Category:</b>
<div ng-repeat="cat in cuisines">
<b><input type="checkbox" ng-model="cat.checked" /> {{cat.name}}</b>
</div>
<hr />
<div ng-repeat="w in filtered=(restaurants | filter:filterByCategory) " class="animate-repeat">
{{w.name}}
</div>
<hr /> Number of results: {{filtered.length}}
</div>
Please see working example here
From the source
Animations
AngularJS provides animation hooks for common directives such as ngRepeat, ngSwitch, and ngView, as well as custom directives via the $animate service. These animation hooks are set in place to trigger animations during the life cycle of various directives and when triggered, will attempt to perform a CSS Transition, CSS Keyframe Animation or a JavaScript callback Animation (depending on if an animation is placed on the given directive). Animations can be placed using vanilla CSS by following the naming conventions set in place by AngularJS or with JavaScript code when it's defined as a factory.
Animations are not available unless you include the ngAnimate module as a dependency within your application.

Requirements for getting the tile-cascade page transition to work in polymer

I've been playing with this for a while, but can anyone explain what the requirements are to have the tile-cascade page transition to work in Polymer? When I take a look at the code for the transition, I see the following:
polyfill-next-selector { content: ':host(.tile-cascade) > * [tile-cascade] > div:nth-of- type(2)'; }
:host(.tile-cascade) ::content > * /deep/ [tile-cascade] > div:nth-of-type(2) {
-webkit-transition-delay: 0.05s;
transition-delay: 0.05s;
}
polyfill-next-selector { content: ':host(.tile-cascade) > * [tile-cascade] > div:nth-of-type(3)'; }
:host(.tile-cascade) ::content > * /deep/ [tile-cascade] > div:nth-of-type(3) {
-webkit-transition-delay: 0.1s;
transition-delay: 0.1s;
}
I believe this tells us what the markup should be made of (IE: It's looking for divs after the element with the tile-cascade attribute, but I'm not sure if I'm missing other requirements. I've attached a screen shot of some of the code from Chrome dev tools in hopes that it will proved some context
From my experience, there are three things that you need to do.
People often forget to include the reference for the tile-cascade animation. So make sure you have <link rel="import" href="../bower_components/core-animated-pages/transitions/tile-cascade.html"> on top of your element.
You cannot apply the tile-cascade attribute to the direct child of your core-animated-pages. Apply it to the next level container.
Your core-animated-pages needs to include tile-cascade in the transitions attribute.
To demonstrate point 2 & 3, I have the following piece of code that works properly in my project.
<core-animated-pages selected="{{ $.tabs.selected }}" transitions="tile-cascade" notap fit>
<section>
<core-selector tile-cascade>
<div class="portal-item">
<div class="tile"></div>
</div>
<div class="portal-item">
<div class="tile"></div>
</div>
<div class="portal-item">
<div class="tile"></div>
</div>
<div class="portal-item">
<div class="tile"></div>
</div>
Update
4. As already mentioned in the OP, each tile element needs to be wrapped by a div.
Say if you are using a template to iterate through the tiles, you will need to wrap whatever inside your template with a div otherwise the tile-cascade won't work (Interestingly, the list-cascade animation works without the need of the div wrapper). e.g.
<core-animated-pages transitions="cross-fade tile-cascade">
<section>
<div class="container" horizontal layout center-justified wrap cross-fade tile-cascade>
<template repeat="{{item in hierarchyItems}}">
<!-- you need this div here otherwise the tile-cascade animation doesn't work! -->
<div>
<my-element></my-element>
</div>
</template>
</div>
</section>

How to animate a dropdown menu using CSS3 animations?

I would like to add a CSS3 effect to my dropdown. (Just like that one in Instagram.com on "My profile").
I'm using Animate.css for the CSS3 effects.
I tried this, but it doesn't work.
HTML
<%=fa_icon "bell"%>
<ul id="dropdownalerts" class="f-dropdown text-left animated bounceInDown" data-dropdown-content>
<li><%=link_to "Facebook", "#"%></li>
<li><%=link_to "Email", "#" %></li>
</ul>
JS
$(document).ready(function(){
$('a').hover(function(){
$("ul").addClass('animated bounceInDown');
});
});
You can find a live version on Zapping.io
I got it working in an example. I used the HTML you provided, and then downloaded the bounceInDown animation and used that for the CSS in the examples below.
jsFiddle example here - hover method
jQuery
$(document).ready(function(){
$('a').hover(function() {
$("ul").addClass('animated bounceInDown');
},function(){
$("ul").removeClass('animated bounceInDown');
});
});
If you want to add a delay when hovering off, use something like this:
jsFiddle example - hover method with delay.
$(document).ready(function(){
$('a').hover(function() {
$("ul").addClass('animated bounceInDown');
},function(){setTimeout(function(){
$("ul").removeClass('animated bounceInDown');
}, 750);});
});
Those examples are assuming you want the animation fired on hover. If you want it fired on click, use something like this instead:
jsFiddle example click method - Look below for an alternative non-JS method.
$(document).ready(function(){
$('a').click(function() {
$("ul").toggleClass('animated bounceInDown');
});
});
Alternative method - No JS/jQuery
If you don't want to use JavaScript/jQuery, you can use the checkbox hack in CSS.
This essentially toggles between :checked, thus activating the animation.
jsFiddle example - It works in all current browsers.
HTML
<label id="click" for="dropdown">Click here</label>
<input style="display:none" type="checkbox" id="dropdown">
<ul id="dropdownalerts" class="f-dropdown text-left" data-dropdown-content>
<li>Facebook</li>
<li>Email</li>
</ul>
CSS - (only part of it) See the example above for full CSS.
input[type=checkbox]:checked ~ #dropdownalerts {
display:inline-block;
-webkit-animation: bounceInDown 1s both;
-moz-animation: bounceInDown 1s both;
-o-animation: bounceInDown 1s both;
animation: bounceInDown 1s both;
}

Blur effect on the entire webpage

I want that the unregistered users on my website, see the entire website's pages with a blur effect.
How can I create this blur effect with css ?
Try this...
body {
filter:blur(3px);
}
You'll need to add -moz-, -webkit- prefixes (or use something like PrefixFree)
Here's some results, if by blur you mean fuzziness:
This guy uses image shifting and opacity techniques in combo, I know your users are looking at a blurred website, but if there's no easy solution then perhaps taking a snapshot of your rego page and overlaying the image then it might do:
http://web.archive.org/web/20120211000759/http://simurai.com/post/716453142/css3-image-blur
If you wanted to attempt duplicating your rego page, given that it may be a) disabled and b) minimal, then perhaps you could even have a bash at using the above image technique and applying it to node sets, offsetting the copies with CSS positioning and opacity - idk if zoom might help you too there. Even if your page was minimal enough, this would obviously require Javascript to duplicate the nodes, unless your backend can do this node duplication. Just an idea, really. Here's a really awful, very quick example:
http://jsfiddle.net/9qnsz/2/
This SO posts outlines some of the limitations and difficulties with gaussian blur when not done with image, and has some interesting links:
Gaussian Blur onHover Using jQuery
EDIT: As requested, the contents of the jsfiddle:
<div class="container">
<div class="overlay">
<p>Please register etc etc...</p>
</div>
<form action="javascript:;" class="form0">
<input type="text" value="Username" />
<input type="text" value="Password" />
<button>Submit</button>
</form>
<form action="javascript:;" class="form1">
<input type="text" value="Username" />
<input type="text" value="Password" />
<button>Submit</button>
</form>
<form action="javascript:;" class="form2">
<input type="text" value="Username" />
<input type="text" value="Password" />
<button>Submit</button>
</form>
<form action="javascript:;" class="form3">
<input type="text" value="Username" />
<input type="text" value="Password" />
<button>Submit</button>
</form>
<form action="javascript:;" class="form4">
<input type="text" value="Username" />
<input type="text" value="Password" />
<button>Submit</button>
</form>
</div>​
.container {
width:500px;
height:500px;
position:relative;
border:1px solid #CCC;
}
form {
position:absolute;
left:10px;
top:10px;
}
form.form0 {
left:11px;
top:11px;
opacity:0.1;
}
form.form1 {
left:8px;
top:8px;
opacity:0.1;
zoom:1.02;
}
form.form2 {
left:11px;
top:11px;
opacity:0.1;
zoom:1.01;
}
form.form3 {
left:9px;
top:9px;
opacity:0.2;
}
form.form4 {
left:11px;
top:11px;
opacity:0.1;
}
.overlay {
width:250px;
height:250px;
margin-top:50px;
margin-left:auto;
margin-right:auto;
border:1px solid #666;
}
Edit (2015): The filter css property is forming tantalisingly complete coverage. This lets you write rules like body { filter: blur(10px); }, which blurs the entire page.
From what I can tell, there's no cross-browser way of blurring an element, even in this "modern age" of html5, css3, etc...
There is a blur filter for IE (and only IE). An svg blur filter can also be applied to an html element but from what I can tell, it only works in Firefox.
If you're happy for browser-specific hacks, go ahead, but if you need the effect to work on all browsers you're outta luck.
If you just want to blur text, you can use a clever text-shadow trick:
.blurry {
color: transparent;
text-shadow: 0 0 3px black; /* set to colour you want */
}
There are also ways to blur images, either by overlaying transparent, shifted copies of the image, or by processing the data with javascript.
Perhaps you can cobble together these techniques, and it will achieve what you want.
But the broad answer, regrettably, for the moment is: there is no easy, holistic way to blur stuff in HTML.
(I thought we were living in the future, man? What gives?!)
Addendum: Hope is in sight. At the time of writing, some webkit nightly ("bleeding edge") builds are implementing some of the new css filter specification. That demo doesn't work on any webkit browser I have installed, so it's still far from mainstream yet.
You can add a fixed div set to 100% width and height to your body. That will fill the screen and you can put either a semi-transparent background on it or use CSS3 to create the effect you are looking for.
Create a new div tag with id="body_bag" and put your rest of the site edits within that div and use following css to give the blur effect.
#body_bag {
position: absolute;
width: 100%;
top: 0;
left: 0;
background: #000;
opacity: 0.5;
filter: alpha(opacity = 50); /* required for opacity to work in IE */
}

Resources