Page elements flying in - javascript

My purpose is to modify my page to load elements by "flying in". I found this JSFiddle example, and I should now make it to happen on page load, without clicking anything. So it triggers on page load.
$(function() {
$("#add-sidebar-module").on("click", function() {
$("<div />", {
'class': "module",
text: "I'm new here."
}).prependTo("#sidebar");
});
$("#add-article").on("click", function() {
$("<div />", {
'class': "module",
html: "<h1>Title</h1><p>text text text.</p>"
}).prependTo("#main");
});
});
I'm also afraid that there is some kind of issues in what comes to the page loading and the animation. Tips and tricks to make sure it's as smooth as possible would be welcome!

http://jsfiddle.net/PJN6r/
<div class="animate-on-load">
This is animated
</div>
$('.animate-on-load').addClass('module');
As per your request.
I would not suggest triggering a click on page load. Just add the class on load.

This is more smooth effect: enter link description here
.module {
-webkit-animation: flyin 1s cubic-bezier(.62, -0.36, .4, 1.28);
-moz-animation: flyin 1s cubic-bezier(.62, -0.36, .4, 1.28);
-o-animation: flyin 1s cubic-bezier(.62, -0.36, .4, 1.28);
-ms-animation: flyin 1s cubic-bezier(.62, -0.36, .4, 1.28);
animation: flyin 1s cubic-bezier(.62, -0.36, .4, 1.28);
}
#-webkit-keyframes flyin {
from {
opacity: 0;
-webkit-transform: scale(1.4);
}
to {
-webkit-transform: scale(1);
opacity: 1;
}
}
#-moz-keyframes flyin {
from {
opacity: 0;
-moz-transform: scale(1.4);
}
to {
-moz-transform: scale(1);
opacity: 1;
}
}
#-o-keyframes flyin {
from {
opacity: 0;
-o-transform: scale(1.4);
}
to {
-o-transform: scale(1);
opacity: 1;
}
}
#-ms-keyframes flyin {
from {
opacity: 0;
-ms-transform: scale(1.4);
}
to {
-ms-transform: scale(1);
opacity: 1;
}
}
#keyframes flyin {
from {
opacity: 0;
transform: scale(1.4);
}
to {
transform: scale(1);
opacity: 1;
}
}
body {
padding: 50px;
}
.main, .sidebar {
padding: 1em;
}
.main {
float: left;
width: 60%;
}
.sidebar {
float: right;
width: 20%;
}
.module {
border: 0.5em solid #ccc;
background: #eee;
padding: 1.5em;
margin: 0 0 2em 0;
}
h1 {
margin-top: 0;
}

Check out this jQuery plugin. It animates any element you want when the page loads, so that you don't have to click anything.
Here is a demo of it.
To use this plugin, make sure you first include jQuery on any pages that use it, and include the JavaScript file as well.
Then wrap this tag around all elements you want to fly-in.
<div class="runway">
... fly-in elements go here ...
</div
Finally add either fly-in-right or fly-in-left class to the DOM element you wish to animate.
<img class="fly-in-left" src="..." />
And that should do it! When the element if visible on the page, it will animate a 'fly-in'!

Related

Why does the drawer not animate on the way out?

I want my drawer to animate on the way in, and on the way out and when the animation ends, to turn to display: none but when the drawer is closed, it disappears and doesn't animate out.
const Drawer = ({ closeDrawer, isDrawerOpen }) => {
const [isAnimating, setIsAnimating] = useState()
let drawerClassName
if (isDrawerOpen) {
drawerClassName = "drawer-in"
} else if (!isDrawerOpen && isAnimating) {
drawerClassName = "drawer-animating"
} else if (!isDrawerOpen && !isAnimating) {
drawerClassName = "drawer-out"
}
return (
<>
<div
className={`drawer ${drawerClassName}`}
onAnimationStart={() => setIsAnimating(true)}
onAnimationEnd={() => setIsAnimating(false)}
></div>
<div onClick={closeDrawer}></div>
</>
)
}
CSS:
.drawer {
height: 100%;
width: 60%;
background-color: #fff;
position: absolute;
right: 0;
top: 0;
opacity: 1;
z-index: 3;
transform: translateX(100%);
}
.drawer-in {
animation: 0.7s drawerIn;
transform: translateX(0);
display: block;
}
.drawer-animating {
animation: 0.7s drawerOut;
display: block;
}
.drawer-out {
animation: 0.7s drawerOut;
display: none;
}
#keyframes drawerIn {
0% {
transform: translateX(100%);
}
1% {
transform: translateX(100%);
}
100% {
transform: translateX(0);
}
}
#keyframes drawerOut {
0% {
transform: translateX(0);
}
99% {
transform: translateX(100%);
}
100% {
transform: translateX(100%);
}
}
it's because when you set the drawer-out class to the element display: none; is activated immediately and you don't see the animation.
One solution is to run a setTimeout function within your JavaScript to wait for the animation to finish, then change the elements display property to none. This will allow your 'closing animation' to complete before removing the element. See my snippet below for working example.
Basically what's happening in my example snippet is I'm triggering the closing animation by adding a class associated with the animation. Then I'm setting a time out function that waits for the animation to complete (set time out in milliseconds to match your animation time within your CSS). Once the timeout is complete, the animation class is removed and the element's data attribute is set to closed which will trigger the display none. Hope this helps.
const menu = document.querySelector('.menu');
const menuToggle = document.querySelector('.menu_toggle');
menuToggle.checked=false
menuToggle.addEventListener('change',(e)=>{
menuToggle.disabled=true
let menuState = menu.dataset.menuState
if(menuState==='closed'){
menu.dataset.menuState='opened'
setTimeout(() => {
menuToggle.disabled=false
}, 500);
}else{
menu.classList.add('animate_close')
setTimeout(() => {
menu.classList.remove('animate_close')
menu.dataset.menuState='closed'
menuToggle.disabled=false
}, 500);
}
})
body {
background-color: rgb(235, 235, 235);
}
.menu {
background-color: black;
color: white;
width: fit-content;
}
.menu {
transition: all .5s ease-in-out;
}
.menu[data-menu-state="closed"] {
background-color: red;
display: none;
}
.menu[data-menu-state="opened"] {
animation: openMenu .5s ease-in-out;
transform: translateX(100%);
background-color: green;
}
.menu.animate_close{
background-color: rgb(0, 30, 128);
animation: closeMenu .5s ease-in-out;
opacity: 0;
}
#keyframes openMenu {
0% {
transform: translateX(0);
}
100% {
transform: translateX(100%);
}
}
#keyframes closeMenu {
0% {
transform: translateX(100%);
}
100% {
transform: translateX(0);
}
}
<body>
<label for="menu_toggle">Menu Toggle</label>
<input id="menu_toggle" type="checkbox" class="menu_toggle">
<div class="menu_container">
<div class="menu" data-menu-state="closed">
<ul>
<li>Item1</li>
<li>Item2</li>
<li>Item3</li>
</ul>
</div>
</div>
<script src="main.js"></script>
</body>

How to fire "animationend" event, when I can't set a CSS animation?

If I set the css animation to "element", it's fine. If the Css animation is not available, how does it function fire like a zero seconds animation in the ES5?
function run() { ... }
element.addEventListener('animationend', run);
Reply for
#Anurag Srivastava,
Am I wrong idea or do I have the following code wrong? Either way, the return value is "".
var el1 = document.getElementById("notAnimation");
console.log(el1.style.animation);
var el2 = document.getElementById("onAnimation");
console.log(el2.style.animation);
div {
padding: 10px;
margin: 20px;
}
#notAnimation {}
#onAnimation {
animation: scale 10s ease-in-out;
}
#keyframes scale {
0% {
transform: scale(1);
opacity: 1;
color: black;
}
50% {
transform: scale(0.95);
opacity: .4;
color: red;
}
100% {
transform: scale(1);
opacity: 1;
color: black;
}
}
<div id="notAnimation">
Not Animation
</div>
<div id="onAnimation">
Animation
</div>
You can check if element.style.WebkitAnimation and element.style.animation contain any value and execute run() if the value is ""
Edit Turns out that .style will return "" for any value. What you need is window.getComputedStyle() along with the property animationName. If it is none, there is no animation, else there is. Check the code below:
var el1 = document.getElementById("notAnimation");
console.log(window.getComputedStyle(el1)["animationName"])
var el2 = document.getElementById("onAnimation");
console.log(window.getComputedStyle(el2)["animationName"])
div {
padding: 10px;
margin: 20px;
}
#notAnimation {}
#onAnimation {
animation: scale 10s ease-in-out;
}
#keyframes scale {
0% {
transform: scale(1);
opacity: 1;
color: black;
}
50% {
transform: scale(0.95);
opacity: .4;
color: red;
}
100% {
transform: scale(1);
opacity: 1;
color: black;
}
}
<div id="notAnimation">
Not Animation
</div>
<div id="onAnimation">
Animation
</div>

Sliding and fading a div element

I am trying to animate a div element (slide and fade) with a button click. At first, the element is not visible to a user. When the button is clicked, it will slide to right and fade in. Once the button is clicked again, it will slide to left and fade out. I come up with two solutions, with css and with JQuery.
In the first one, I used JQuery. You can find the example in this JSFiddle 1.
HTML
<button id="my-button">Click me!</button>
<div id="my-modal"></div>
CSS
#my-modal {
opacity: 1;
position: fixed;
top: 50px;
left: 0;
left: -250px;
width: 250px;
height: 100%;
background-color: red;
}
JQuery
$("#my-button").click(function () {
var $modal = $("#my-modal");
$modal.stop(true, true).animate({
left: "toggle",
opacity: "toggle"
}, 1000);
});
Here, everything seems working but it does directly opposite of what I want. It first fades out, and with the second click, it fades in. It is because that the opacity of the element is 1, but if I turn it to 0, nothing happens.
Secondly, I tried to do that with css animation by using key-frames (changing opacity from 0 to 1) but it has also problem. It starts the animation exactly the way I want. However, when I click the button again, it disappears immediately. Here is the JSFiddle 2.
HTML
<button id="my-button">Click me!</button>
<div id="my-modal"></div>
CSS
#my-modal {
opacity: 0;
position: fixed;
top: 50px;
left: 0;
left: -250px;
width: 250px;
height: 100%;
background-color: red;
-moz-transition: all 1s ease;
-webkit-transition: all 1s ease;
-o-transition: all 1s ease;
transition: all 1s ease;
}
.move-my-modal {
-moz-transform: translate(250px, 0px);
-webkit-transform: translate(250px, 0px);
-ms-transform: translate(250px, 0px);
-o-transform: translate(250px, 0px);
}
.animate-opacity {
-webkit-animation: toggle-opacity 1s ease;
-moz-animation: toggle-opacity 1s ease;
-o-animation: toggle-opacity 1s ease;
animation: toggle-opacity 1s ease;
-webkit-animation-fill-mode: forwards;
}
#-webkit-keyframes toggle-opacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#-moz-keyframes toggle-opacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#-o-keyframes toggle-opacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#keyframes toggle-opacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
JQuery
$("#my-button").click(function () {
var $modal = $("#my-modal");
$modal.toggleClass("move-my-modal");
$modal.toggleClass("animate-opacity");
});
To this end, I have these questions;
1) What are the problems with these two approaches? Is there something that I missed or forgot to use? How can I correct them to meet the requirements that I mentioned at the beginning.
2) Which one is the better way to make this action? Is there any cons or pros of these approaches?
3) Is there any other way to make this action? I am new on this area and I might not notice a simpler way.
You can toggle an .active class to the element and use CSS transitions.
This way, if the browser is old enough to not support animations, it will still work but it won't slow down computers that do not handle animations well.
$("#my-button").click(function () {
$("#my-modal").toggleClass('active');
});
#my-modal.active {
opacity: 1;
left: 0;
}
$("#my-button").click(function () {
$("#my-modal").toggleClass('active');
});
#my-modal {
opacity: 0;
position: fixed;
top: 50px;
left: -250px;
width: 250px;
height: 100%;
background-color: red;
transition: all 1s linear;
}
#my-modal.active {
opacity: 1;
left: 0;
}
<button id="my-button">Click me!</button>
<div id="my-modal"></div>
<!-- jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Why does the data-binding polyfill in Polymer not work within <style> tags?

I have been building a slideshow custom element using polymer and have been using the Animate.css library for slide transitions. When used Canary with "Experimental web platform" features turned on, the tag works as expected, but in the regular version of chrome with the experimental features turned off, the platform polyfill does not allow me to data-bind within style tags. As an example:
<polymer-element name="impress-slide" constructor="ImpressSlide" attributes="exit entrance">
<template>
<link rel="stylesheet" type="text/css" href="basic-animations.css">
<style type="text/css">
:host{
position: relative;
top: 0;
left: 0;
overflow: hidden;
display: none;
width: 100%;
height: 100%;
margin: 0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
/* Animate.css */
-webkit-animation: 1s both;
animation: 1s both;
-webkit-animation-name: {{ animation }} !important;
animation-name: {{ animation }} !important;
}
#-webkit-keyframes fadeOutRightBig {
0% {
opacity: 1;
-webkit-transform: translateX(0);
transform: translateX(0);
}
100% {
opacity: 0;
-webkit-transform: translateX(2000px);
transform: translateX(2000px);
}
}
#keyframes fadeOutRightBig {
0% {
opacity: 1;
-webkit-transform: translateX(0);
-ms-transform: translateX(0);
transform: translateX(0);
}
100% {
opacity: 0;
-webkit-transform: translateX(2000px);
-ms-transform: translateX(2000px);
transform: translateX(2000px);
}
}
#keyframes bounceIn {
0% {
opacity: 0;
-webkit-transform: scale(.3);
-ms-transform: scale(.3);
transform: scale(.3);
}
50% {
opacity: 1;
-webkit-transform: scale(1.05);
-ms-transform: scale(1.05);
transform: scale(1.05);
}
70% {
-webkit-transform: scale(.9);
-ms-transform: scale(.9);
transform: scale(.9);
}
100% {
-webkit-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);
}
}
:host(.past:host) {
/*opacity: 0;*/
}
:host(.current:host) {
display: block;
}
:host(.next:host) {
pointer-events: none;
}
</style>
<content></content>
</template>
<script type="text/javascript">
(function() {
Polymer('impress-slide', {
entrance: 'bounceIn',
exit: 'fadeOutRightBig',
animation: "",
animateIn: function() {
// this.opacity = 1;
this.animation = this.entrance;
},
animateOut: function() {
// this.opacity = 0;
this.animation = this.exit;
},
ready: function() {
}
})
})();
</script>
</polymer-element>
The animation-name: {{ animation }} !important; will remain unrendered in the polyfill version, evaluating simply to animation: 1s both;. I was wondering if anyone had any insight as to why this is and what I can do as a workaround?
So after some digging, I found a discussion of the problem on the polymer github page: https://github.com/Polymer/polymer/issues/270.
Basically, this is an unsupported feature in the ShadowDOMPolyfill for the time being, and the authors are unsure whether or not they will implement this functionality for performance reasons. The programmer assigned to the issue suggests the following workaround:
<style>
div {
border: 1px solid black;
width: {{width}}px;
}
/* polyfill specific rule */
/* #polyfill-rule
#host[id={{id}}] div {
border: 1px solid black;
width: {{width}}px;
}
*/
</style>
...
<script type="text/javascript">
Polymer('x-foo', {
...
registerCallback: function(declaration) {
// add shimmedStyles to this instance
if (window.ShadowDOMPolyfill) {
var content = declaration.templateContent();
content.insertBefore(content.shimmedStyle, content.firstChild);
}
}
});
</script>
For whatever reason, my own implementation of this method failed. In lieu of this, I wrote a workaround that, while being a little ugly, works quite well in unsupported browsers:
<script type="text/javascript">
(function() {
Polymer('impress-slide', {
entrance: 'bounceIn',
exit: 'fadeOutRightBig',
animation: "",
animateIn: function() {
this.animation = this.entrance;
// Fallback for polyfill
if (window.ShadowDOMPolyfill &&
((this.style.animationName != this.entrance) ||
(this.style.webkitAnimationName != this.entrance))) {
this.style.webkitAnimation =
this.style.animation = this.entrance + " 1s both";
}
},
animateOut: function() {
this.animation = this.entrance;
// Fallback for polyfill
if (window.ShadowDOMPolyfill &&
((this.style.animationName != this.exit) ||
(this.style.webkitAnimationName != this.exit))) {
this.style.webkitAnimation =
this.style.animation = this.exit;
}
},
ready: function() {
}
})
})();
</script>
Essentially, these modifications test the browser for the presence of the polyfill and for the incorrect assignment of the animation style properties. If these are found, the function will manually apply them to the slide using inline insertion (e.g. this.style.animation = this.entrance + " 1s both";).
The downsides of this approach are that it exposes the inner workings of the element to the end user in the event of the polyfill, undermining the goal of encapsulation within the custom element. However, under normal circumstances within a supported browser, the element will transition as expected, with the encapsulation intact.

CSS animation active doesn't continue?

I've been trying to learn css animations and I'm starting to get a grip on them but I'm having an issue an animation effect. I have an animation class assigned to a section that is a download button when I click it the animation plays for the extent of the click, if i click and hold it plays the whole animation. I want the animation to play all the way through on on click, not a click and hold.
Heres the Html section the class is applied to:
<a href="software/ASC.exe">
<section id="download" class="animated" title="Download ASC">
Download
</section>
</a>
Here is the CSS animation class:
.animated {
}
.animated:active {
-webkit-animation:fadeOutUp 2s;
-moz-animation:fadeOutUp 2s;
-o-animation:fadeOutUp 2s;
-ms-animation:fadeOutUp 2s;
animation:fadeOutUp 2s;
box-shadow:3px 1px 20px 4px #0099CC;
}
#-webkit-keyframes fadeOutUp {
0% {
opacity: 1;
-webkit-transform: translateY(0);
}
100% {
opacity: 0;
-webkit-transform: translateY(-20px);
}
}
#-moz-keyframes fadeOutUp {
0% {
opacity: 1;
-moz-transform: translateY(0);
}
100% {
opacity: 0;
-moz-transform: translateY(-20px);
}
}
#-o-keyframes fadeOutUp {
0% {
opacity: 1;
-o-transform: translateY(0);
}
100% {
opacity: 0;
-o-transform: translateY(-20px);
}
}
#keyframes fadeOutUp {
0% {
opacity: 1;
transform: translateY(0);
}
100% {
opacity: 0;
transform: translateY(-20px);
}
}
.fadeOutUp {
-webkit-animation-name: fadeOutUp;
-moz-animation-name: fadeOutUp;
-o-animation-name: fadeOutUp;
animation-name: fadeOutUp;
}
Any help is appreciated!
HTML
<a href="#" id="buttonLink">
<section id="download" class="animated" title="Download ASC">
Download
</section>
</a>
CSS
.clicked {
-webkit-animation:fadeOutUp 2s;
-moz-animation:fadeOutUp 2s;
-o-animation:fadeOutUp 2s;
-ms-animation:fadeOutUp 2s;
animation:fadeOutUp 2s;
box-shadow:3px 1px 20px 4px #0099CC;
}
JavaScript
var el = document.getElementById('buttonLink');
el.addEventListener('click', function(){
document.getElementById('download').className = 'clicked';
})
DEMO
You could do it with jQuery
DEMO http://jsfiddle.net/kevinPHPkevin/Uj5gC/1/
$("#download").click(function () {
$(this).addClass("animated1");
});
To reset the animation just remove the class after 2 seconds
DEMO http://jsfiddle.net/kevinPHPkevin/Uj5gC/4/
$("#download").click(function () {
$(this).addClass("animated1");
setInterval(function () {
$("#download").removeClass("animated1");
}, 2000);
});
** EDITED**
Just for the challenge, here's a CSS only option using :target
DEMO http://jsfiddle.net/kevinPHPkevin/Uj5gC/2/
A demo that uses javascript to add that 'animated' class. Anyone knows a way to do that from CSS (kinda' impossible though :D)? It'd be interesting. Plunk here http://plnkr.co/edit/IhkmgKQ9Od0dyb3HFuEv?p=preview
window.onload = function() {
var btn = document.getElementById("download");
btn.addEventListener("click", function(e) {
this.className = "animated";
});
}
You can archieve this in pure CSS by using :not(:active) instead of just .active.

Categories

Resources