Detect specific CSS3 Keyframe with JavaScript - javascript

How to detect that the animation reached a specific keyframe? (For example 50% or 75%).
This is what I tried:
element.addEventListener("animationend", AnimationListener, false);
but it supports animationstart, animationiteration and animationend only.
http://jsfiddle.net/W3y7h/294/

Using the example Fiddle provided, what you're essentially looking to know is when the value of #sun element's bottom property is equal to 100px. You can do this by using getComputedStyle() to check that value, clearing the interval when it is equal to 100px and then executing whatever code you wish, like so:
var style=window.getComputedStyle(document.getElementById("sun")),
interval=setInterval(function(){
if(parseInt(style.getPropertyValue("bottom"))===100){
clearInterval(interval);
console.log("50% reached");
}
},1);
#sun{
animation:sunrise 1s ease;
bottom:0;
background:#ff0;
border-radius:50%;
height:50px;
position:absolute;
width:50px;
}
#keyframes sunrise{
0%{
bottom:0;
left:0;
}
50%{
bottom:100px;
}
100%{
bottom:0;
left:400px;
}
}
<div id="sun"></div>
To check for multiple values, simply set a new interval. In the case of your example, the value of the bottom property should be 50px when the animation is 75% complete. That being said, it may not always be exactly 50px in every browser so, instead, given that we know the value of the bottom property will be decreasing at this point, instead check for it being less than or equal to 50:
var style=window.getComputedStyle(document.getElementById("sun")),
interval=setInterval(function(){
if(parseInt(style.getPropertyValue("bottom"))===100){
clearInterval(interval);
console.log("50% reached");
interval=setInterval(function(){
if(parseInt(style.getPropertyValue("bottom"))<=50){
clearInterval(interval);
console.log("75% reached");
}
},1);
}
},1);
#sun{
animation:sunrise 1s ease;
bottom:0;
background:#ff0;
border-radius:50%;
height:50px;
position:absolute;
width:50px;
}
#keyframes sunrise{
0%{
bottom:0;
left:0;
}
50%{
bottom:100px;
}
100%{
bottom:0;
left:400px;
}
}
<div id="sun"></div>

Related

Blocks expanding issue with z-index

I have a blocks overview, and when you click on one block it expands.
When clicking outside the expanded block, or on the "x", it resizes back to the default size.
But there are two issues I don't know how to solve.
When you click on a block with Chrome/Safari, the z-index updates a millisecond too late and it doesn't look smooth. (Firefox on MAC is okay when expanding.)
When it's expanded and goes back, the z-index needs to be higher than the other blocks. So, when it goes to normal the site looks a lot better.
So, when clicking, it should add z-index:2; and when it's resizing back to default size the z-index needs to be 1 so its higher than the others ( which are 0) but, when another is expanding, that needs to be the highest.
Can anyone help me with this? I'd rather use some JS magic for this, maybe inline style?
I also made a jsfiddle to show what I mean.
https://jsfiddle.net/fourroses666/sp7vbtok/2/
HTML:
<div class="grid">
<div class="grid-item">
<div class="g-inner" style="background-image:url(https://placekitten.com/350/350);">
<div class="g-item"><img src="/some-png-img.png" height="175" width="175" /></div>
<div class="g-more">Bla bla bla.</div>
<div class="g-close">x</div>
</div>
</div>
</div>
JS
$(".grid-item").on("click", function(){
$(".grid-item").removeClass("active");
$(this).addClass("active");
});
$(".g-close").on("click", function(e){
e.stopPropagation();
$(this).closest(".grid-item").removeClass("active");
});
CSS
.grid{width:875px; margin:20px auto;}
.grid:after {content:''; display:block; clear:both;}
.grid-item{width:175px; height:175px;}
.g-more{display:none; position:absolute; top:175px; height:175px; width:175px; transition:all 1s ease-in-out; opacity:0; padding:20px;}
.active .g-more{opacity:1; display:block;}
.grid-item{float:left; width:175px; height:175px; background:#ddd; color:#fff;}
.grid-item:before{display:block; padding:0;}
.grid-item-wide, .grid-item-wide .g-inner, .grid-item-wide .g-item{width:350px; height:175px;}
.g-inner{cursor:pointer; overflow:hidden; z-index:1; width:175px; height:175px; transition:all 1s ease-in-out; -webkit-background-size:cover; -moz-background-size:cover; -o-background-size:cover; background-size:cover; background-repeat:no-repeat; background-position:left 50%;}
.active .g-inner{width:350px; height:350px; position:relative; z-index:2; cursor:default;}
.open-left.active .g-inner{margin-left:-175px;}
.open-top.active .g-inner{margin-top:-175px;}
.g-item{width:175px; height:175px; position:relative;}
.g-close{cursor:pointer; position:absolute; right:-50px; bottom:-50px; width:50px; height:50px; line-height:50px; font-size:35px; display:none; opacity:0; text-align:center; transition:all 1s ease-in-out;}
.active .g-close{opacity:1; right:0; top:auto; bottom:0; z-index:5; display:block;}
try to use insted
.active .g-inner {
width:350px;
height:350px;
}
with transform:scale and transform-origin (-if you want set pivot x and y as top-left) like this:
.active .g-inner {
transform: scale(2);
transform-origin: left top;
}
its work fine for me

Adding a light to javascript w/ ping test

I want to display this light if a certain condition is true in javascript using an if statement. How can I add an external CSS class to a javascript if statement?
Here is my css code:
.beacon{
position:absolute;
background-color:#32CD32;
height:1.5em;
width:1.5em;
border-radius:50%;
-webkit-transform:translateX(-50%) translateY(-50%);
}
.beacon:before{
position:absolute;
content:"";
height:1.5em;
width:1.5em;
left:0;
top:0;
background-color:transparent;
border-radius:50%;
box-shadow:0px 0px 2px 2px #32CD32;
-webkit-animation:active 2s infinite linear;
animation:active 2s infinite linear;
}
#-webkit-keyframes active{
0%{
-webkit-transform:scale(.1);
opacity:1;
}
70%{
-webkit-transform:scale(2.5);
opacity:0;
}
100%{
opacity:0;
}
}
#keyframes active{
0%{
transform:scale(.1);
opacity:1;
}
70%{
transform:scale(2.5);
opacity:0;
}
100%{
opacity:0;
}
}
this is the javascript code:
<div class="too white">
<script language="javascript">
url = "http://www.511virginia.org/"
ping = new XMLHttpRequest();
ping.onreadystatechange = function(){
if(ping.readyState == 4){
if(ping.status == 200){
document.write("Website is up");
}
else {
document.write("Website is down");
}
}
}
ping.open("GET", url, false);
ping.send();
</script>
</div>
It depends on any framework you're using. For example, if you're using jQuery then change a DOM element's CSS using .css(property, value). Angular has it's own methods. For raw DOM manipulation take a look at the w3c page on JavaScript HTML DOM - Changing CSS, which shows the following.
document.getElementById(id).style.property = new style

Transition of added element with position absolute

So I have this problem: I append a div into a div at 50px top then try to animate to 0px but the animation never works, even if the div is moved to 0%.
Here is the very simple code
HTML
<div id="toto"></div>
JS
$('#toto').append('<div id="test" class="test">test</div>');
$('#test').css('top', '0px');
CSS
#toto{
display:block;
}
.test{
display:block;
position:absolute;
transition:all 3s;
top:50px;
}
FIDDLE
Link
Any idea how to have it move with CSS transitions? Thanks.
The CSS is being applied too fast for the top change to trigger the transition. You can wrap the class change in a fast setTimeout() https://jsfiddle.net/nb0fty1b/1/
$('#toto').append('<div id="test" class="test">test</div>');
setTimeout(function() {
$('#test').css('top', '0px');
},100);
#toto{
display:block;
min-height:200px;
}
.test{
display:block;
position:absolute;
transition:all 3s;
top:50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="toto">
</div>
Don't change the top on page load like:
setTimeout(function(){
$('#test').css('top', 0);
},2000);
You can do that with CSS animation and #keyframes.
$('#toto').append('<div id="test" class="test">test</div>');
#toto {
min-height: 200px;
position: relative;
}
.test {
position: absolute;
top: 50px;
animation: move 3s forwards;
}
#keyframes move {
to {
top: 0;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="toto"></div>

How to make a marquee cycle once at a button click?

What I am trying to achieve is so that a marquee plays once when I click the button. My problem is that if I set the loop to 1 then it only plays once and then does nothing. My other problem is that it stops midway with my current code if I let go of the left mouse button. Or it stops where it was. Is there any way to make it either play once when the button is pressed and then play again whenever the button is pressed again and allow it to complete the loop completely. Here is the code, I am open to using java script instead of html. Here is my current code:
<marquee behavior="scroll" direction="up" scrollamount="30" id="marquee" height="40">
<p>+1</p>
</marquee>
<input type="button" id="gather" class="build" Value="play" onmousedown="document.getElementById('marquee').start()." onmouseup="document.getElementById('marquee').stop()" onload="document.getElementById('marquee').stop()">
You can use CSS keyframes and JQuery (or Javascript) in order to accomplish that.
In the example below, I'm using CSS rules to achieve the animation effect, and applying it adding/removing the span element from te DOM using JQuery.
Code example:
var marquee = '<span class="anim">+1</span>';
$('.btn').click(function(){
$('.anim').remove(); //remove the node if its there
$('.marquee').append(marquee); //append the node
});
.marquee{
width: 20px;
height: 20px;
overflow:hidden;
}
.marquee > span {
position:relative;
top:-100%;
left:0;
}
.anim{
animation-name: example;
animation-duration: 2s;
}
#keyframes example {
0%,100% {
opacity:0;
top:100%;
}
50% {
opacity:1;
top:0;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="marquee"></div>
<button class="btn">Click here!</button>
Are you willing to use pure CSS?
It seems like you want a "+1" counter on click. You can accomplish this using CSS transitions. I'm going to use an anchor rather than an input, because you have more control over styling it.
You'll probably want to add some movement to it, change the timing, maybe swap linear to ease-out, but this is a starting point. Please consider it a proof of concept.
HTML:
a.play {
padding:6px 8px;
border-radius:4px;
background:#ccc;
border:1px solid #bbb;
text-decoration:none;
color:#111;
position:relative;
}
a.play:focus:before,
a.play:active:before {
Content:"+1";
position:absolute;
top:-16px;
left:6px;
color:#006699;
font-weight:bold;
-webkit-animation: fadeinout 1.3s linear forwards;
animation: fadeinout 1.3s linear forwards;
}
#-webkit-keyframes fadeinout {
0%,100% { opacity: 0; }
10% { opacity: 1; }
}
#keyframes fadeinout {
0%,100% { opacity: 0; }
10% { opacity: 1; }
}
<div style="height:60px;"></div>
Play

Animation using Class Name in Javascript

I am trying to animate a div by adding a CSS class name to it on click of a button. But this works only for the first time. Next time I click the button and add the CSS class name, it doesn't animate the div. What am I doing wrong here?
<head>
<script>
function abc() {
document.getElementById("a").className = "";
document.getElementById("a").className = document.getElementById("a").className + " b";
}
</script>
<style>
#a {
width:100px;
height:100px;
background:red;
position:relative;
}
.b {
animation-name:myfirst;
animation-duration:5s;
animation-timing-function:linear;
animation-delay:2s;
animation-iteration-count:1;
animation-direction:alternate;
animation-play-state:running;
}
#keyframes myfirst
{
0% {background:red; left:0px; top:0px;}
25% {background:yellow; left:200px; top:0px;}
50% {background:blue; left:200px; top:200px;}
75% {background:green; left:0px; top:200px;}
100% {background:red; left:0px; top:0px;}
}
#-webkit-keyframes myfirst /* Safari and Chrome */
{
0% {background:red; left:0px; top:0px;}
25% {background:yellow; left:200px; top:0px;}
50% {background:blue; left:200px; top:200px;}
75% {background:green; left:0px; top:200px;}
100% {background:red; left:0px; top:0px;}
}
</style>
</head>
<body>
<div id="a" class="c"></div>
<button onclick="abc()">Click</button>
</body>
The classes on a given element are a set, so adding one that’s already there doesn’t change anything. This kind of animation would probably be better done using JavaScript. (In practice, CSS animation is like anything in CSS — it depends on state, not actions.)
Or am I misunderstanding? Is the problem that it doesn’t stop?
Since you’re using animations, it’s probably safe to assume classList support, so:
document.getElementById("a").classList.toggle("b");

Categories

Resources