CSS transition takes final state immediately - javascript

I have a problem starting a CSS transition automatically. Commonly this is done by adding a class to the element being animated. I'm creating my elements dynamically by jQuery. When adding the class immediately after creating the element it takes it's final state immediately without transition. It works only when I add a short delay. Not very nice, can this be done in a different way?
function startbullet() {
var bullet = $('<div class="bullet"></div>');
$("#wrapper").append(bullet);
setTimeout(function () { bullet.addClass("animate"); }, 10);
}
setInterval(startbullet, 2000);
#wrapper {
height: 400px;
position: relative;
}
.bullet {
position: absolute;
top: 10px;
left: 10px;
width: 20px;
height: 20px;
background-color: #0ff;
border-radius: 10px;
transition-duration: 5s;
transition-timing-function: linear;
}
.bullet.animate {
top: 150px;
left: 400px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div id="wrapper">
</div> <!-- end wrapper -->

You can use a keyframe animation instead of a transition, like this:
.bullet.animate {
animation-name: bulletIn;
animation-duration: 5s;
animation-fill-mode: forwards;
}
#keyframes bulletIn {
0% { top: 10px; left: 10px; }
100% { top: 150px; left: 400px; }
}
Here is a fiddle for you https://jsfiddle.net/e3hqghv3/

According to this blog post you can call window.getComputedStyle before adding the class to force a redraw, I guess this is done under the hood by jquery's animate function.
function startbullet() {
var bullet = $('<div class="bullet"></div>');
$("#wrapper").append(bullet);
window.getComputedStyle(bullet.get(0)).top;
bullet.addClass("animate");
}

Use jQuery.animate just before adding class
function startbullet() {
var bullet = $('<div class="bullet"></div>');
$("#wrapper").append(bullet);
bullet.animate().addClass("animate");
}
setInterval(startbullet, 2000);
#wrapper {
height: 400px;
position: relative;
}
.bullet {
position: absolute;
top: 10px;
left: 10px;
width: 20px;
height: 20px;
background-color: #0ff;
border-radius: 10px;
transition-duration: 5s;
transition-timing-function: linear;
}
.bullet.animate {
top: 150px;
left: 400px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
</div>

Related

Animate just bottom border to width of 0 upon button disabled

function sleep(ms) {
return new Promise (
resolve => setTimeout(resolve, ms)
);
}
async function disableButton() {
document.getElementById("actionButtons").disabled = true;
await sleep(5000);
document.getElementById("actionButtons").disabled = false;
}
document.getElementById("actionButtons").addEventListener("click", function() { disableButton(); })
#actionButtons {
position: relative;
width: 120px;
height: 30px;
margin: 5px;
top: 10px;
left: 40px;
background-color: white;
border: 1px solid black;
position: relative;
}
#actionButtons:after{
content: "";
position: absolute;
left: -1px;
right: -1px;
height: 0px;
bottom: -2px;
background: black;
}
#actionButtons:disabled:after{
height: 4px;
transform-origin: bottom;
animation: cooldown 5s linear forwards;
}
#keyframes cooldown{
from{
width: 100%;
}
to {
width: 0%;
}
}
<button id="actionButtons"></button>
This snippet is now what I've found as a solution to what I was looking for. Thank you for all the help!
I'm attempting to create a button with a cooldown.
I have javascript setup to disable then enable the button. I want a thicker full width bottom border upon being disabled, and that border to animate to a width of 0, upon which the but is reenabled.
My issue is with the CSS, getting a bottom border created upon disabled that I can then animate. Any animations I use effect the entire button, how can I just access the bottom border? Also, I want it to only animate to 0, once enabled I dont want the animation going back to full width. This is the CSS code I have:
.actionButtons {
position: relative;
width: 120px;
height: 30px;
margin: 5px;
top: 10px;
left: 40px;
border: 1px solid black;
}
.actionButtons:disabled {
content: '';
position: relative;
bottom: -6px;
width: 119px;
border-bottom: 2px solid black;
animation: cooldown 10s linear;
}
#keyframes cooldown {
0% { width: 100%; }
100% { width: 0; }
}
Any ideas for how to accomplish this?
So as i said in comment you can use pseudo element to create border and then animate scaleY() of it. In that way you have well performed fluent animation of height.
if you will animate height in px then you will get quantized value to whole one. (tested in chrome)
function sleep(ms) {
return new Promise (
resolve => setTimeout(resolve, ms)
);
}
async function disableButton() {
document.getElementById("actionButtons").disabled = true;
await sleep(5000);
document.getElementById("actionButtons").disabled = false;
}
document.getElementById("actionButtons").addEventListener("click", function() { disableButton(); })
#actionButtons {
position: relative;
width: 120px;
height: 30px;
margin: 5px;
top: 10px;
left: 40px;
border: 1px solid black;
border-bottom-width: 0;
position: relative;
}
#actionButtons:after{
content: "";
position: absolute;
left: -1px;
right: -1px;
height: 1px;
bottom: 0;
background: red;
}
#actionButtons:disabled {
content: '';
position: relative;
bottom: -6px;
width: 119px;
animation: cooldown 5s linear forwards;
}
#actionButtons:disabled:after{
height: 5px;
transform-origin: bottom;
animation: scale-down 4s linear forwards;
}
#keyframes scale-down{
from{
transform: scaleY(1);
}
to {
transform: scaleY(0);
}
}
#keyframes cooldown {
0% { width: 100%; }
100% { width: 0; }
}
<button id="actionButtons"></button>
Not exactly sure what you were trying to achieve but you can use transition css-property to auto animate css changes.
In your case, you can add,
transition: border 1s ease;
to animate your border.
I have reduced the sleep to 1s and increased the border width to 10px just for presentational purposes.
Is this what you wanted to achieve ?
function sleep(ms) {
return new Promise(
resolve => setTimeout(resolve, ms)
);
}
async function disableButton() {
document.getElementById("actionButtons").disabled = true;
await sleep(1000);
document.getElementById("actionButtons").disabled = false;
}
document.getElementById("actionButtons").addEventListener("click", function() {
disableButton();
})
#actionButtons {
position: relative;
width: 120px;
height: 30px;
margin: 5px;
top: 10px;
left: 40px;
border: 1px solid black;
transition: border 1s ease;
}
#actionButtons:disabled {
content: '';
position: relative;
bottom: -6px;
width: 119px;
border-bottom: 10px solid black;
}
<button id="actionButtons"></button>

Animating Elements using JS

I am trying to move a div left from its original position i.e. right , the effect that i'm aiming at is that the div goes to left and then slides to the right a bit.
Vanilla JS only.
Code:
CSS:
leftBtn.addEventListener("click", function() {
pushDiv.style.right = "420px";
pushDiv.style.right = "360px";
});
* {
box-sizing: border-box;
font-family: 'Montserrat', sans-serif;
transition: 0.5s ease;
}
.holder{
position: absolute;
left: 50%;
top: 50%;
height: 300px;
width: 800px;
margin: 0 auto;
background: #eee;
transform: translate(-50%, -50%);
box-shadow: 4px 9px 2px #000;
}
.push-div {
width: 350px;
position: absolute;
background: #F44336;
height: 370px;
right: 0;
top: -35px;
border-radius: 5px;
}
<div class="holder">
<button type="button" name="button" id="btn1">Left</button>
<button type="button" name="button" id="btn2">Right</button>
<div class="push-div" id="pushDiv">
</div>
But on clicking on the button it shows 360px rather than giving the effect.
How do I achieve that? I have tried adding a delay but that doesn't seems to work.
var leftBtn = document.getElementById('leftBtn'),
pushDiv = document.getElementById('pushDiv');
leftBtn.addEventListener("click", function() {
pushDiv.style.right = "410px";
setTimeout( function() {
pushDiv.style.right = "360px";
}, 600 );
});
#pushDiv {
position: absolute;
background: red;
top: 100px;
right: 200px;
width: 100px;
height: 100px;
transition: all .6s;
}
<button id="leftBtn">Move It</button>
<div id="pushDiv"></div>
Try using css animations
JS
const pushDiv = document.querySelector('.pushdiv');
leftBtn.addEventListener('click', animate());
function animate(){
pushDiv.addClass('animation');
{
CSS
.animation{
animation: slideleft 0.7s ease-in;
}
#keyframes slideleft{
// enter your animation keyframes there are some cool tutorials that will show you how to do that same effect
}

How to use removeClass according to multiple conditions?

Can someone help me out with this animation? I have been trying to replicate this one. I got so close to completing it but just can't find a way to make the animation endless on every click. Huge, Thanks in advance!
Problem: After two clicks my animation transitioning of div elements away from the window does not seem to be working.
Expected Result: One every click the Background should transitioning into the window just like the reference from Instagram that I have linked you with.
Reference
Here is the Demo Link
<div class="bg">
<div id="blue" class="skew"></div>
<div id="red" class="skew"></div>
<div id="blue_2" class="skew"></div>
</div>
<button>Toggle</button>
$skew: skew(-10deg);
html,
body {
width: 100%;
height: 100%;
box-sizing: border-box;
}
.bg {
position: relative;
background: red;
width: inherit;
height: inherit;
overflow: hidden;
}
.skew {
position: relative;
width: 100%;
height: inherit;
transform: translateX(-110%);
animation-fill-mode: forwards;
&.blue_wrapper {
background: blue;
animation: slideRight 1s forwards;
}
&.red_wrapper {
background: red;
animation: slideRight 1s forwards;
}
&::before,
&::after {
content: "";
position: absolute;
top: 0;
width: 250px;
height: inherit;
background: inherit;
transform: $skew;
}
&::before {
left: -5%;
}
&::after {
right: -5%;
}
}
#red,
#blue_2 {
position: absolute;
top: 0;
left: 0;
}
blue_2.blue_wrapper_2 {
background: blue;
animation: slideRight 1s forwards;
}
button {
position: fixed;
right: 30px;
bottom: 30px;
}
#keyframes slideRight {
from {
transform: translateX(-110%);
}
to {
transform: translateX(0);
}
}
$(document).ready(function() {
$("button").on("click", function() {
if (
$("#blue").hasClass("blue_wrapper")
) {
$("#red").addClass("red_wrapper");
} else if (
$("#blue").hasClass("skew blue_wrapper") &&
$("#red").hasClass("skew red_wrapper")
) {
$("skew red_wrapper").removeClass("red_wrapper");
$("skew blue_wrapper").removeClass("blue_wrapper");
$("blue_2").addClass("blue_wrapper_2");
} else if {
$("#blue_2").hasClass("blue_wrapper_2")
) {
$("#red").removeClass("red_wrapper");
$("#blue").removeClass("blue_wrapper");
} else {
$("#blue").addClass("blue_wrapper");
}
});
});
You logic makes no sense for
else if (
$("#blue").hasClass("") +
$("#red").hasClass("") +
$("#blue_2").hasClass("blue_wrapper_2")
) {
$("#red").removeClass("red_wrapper");
$("#blue").removeClass("blue_wrapper");
In the above you are checking if the classes have no class then removing the class that is lnt there.
Also you are using + when I assume you meant && or ||
Your Demo link isn't working because you aren't removing the blue Wrapper or red wrapper, this will get the demo to work:
$(document).ready(function() {
$("button").on("click", function() {
if ($("#blue").hasClass("blue_wrapper")) {
$("#red").addClass("red_wrapper");
$("#blue").removeClass("blue_wrapper");
} else {
$("#blue").addClass("blue_wrapper");
$("#red").removeClass("red_wrapper");
}
});
});
For your regular code, you should replace + with && or || as needed, and remove wrappers that you add.
Some syntax issues, some selector issues. Compiled the CSS to test. Removed one odd CSS thing that would not compile. Note I modified to use lime to start to better illustrate.
$(function() {
$("button.toggle").on("click", function() {
if (
$("#blue").hasClass("blue_wrapper") && !$("#red").hasClass("red_wrapper")
) {
$("#red").addClass("red_wrapper");
} else if (
$("#blue").hasClass("blue_wrapper") &&
$("#red").hasClass("red_wrapper")
) {
$(".red_wrapper").removeClass("red_wrapper");
$(".blue_wrapper").removeClass("blue_wrapper");
$("#blue_2").addClass("blue_wrapper_2");
} else if (
$("#blue_2").hasClass("blue_wrapper_2")
) {
$("#red").removeClass("red_wrapper");
$("#blue").removeClass("blue_wrapper");
$("#blue_2").removeClass("blue_wrapper_2")
} else {
$("#blue").addClass("blue_wrapper");
}
});
});
.skew {
transform: skew(-10deg);
}
html,
body {
width: 100%;
height: 100%;
box-sizing: border-box;
}
.bg {
position: relative;
background: lime;
width: inherit;
height: inherit;
overflow: hidden;
}
.skew {
position: relative;
width: 100%;
height: inherit;
transform: translateX(-110%);
animation-fill-mode: forwards;
}
.skew.blue_wrapper {
background: blue;
animation: slideRight 1s forwards;
}
.skew.red_wrapper {
background: red;
animation: slideRight 1s forwards;
}
.skew::before,
.skew::after {
content: "";
position: absolute;
top: 0;
width: 250px;
height: inherit;
background: inherit;
transform: $skew;
}
.skew::before {
left: -5%;
}
.skew::after {
right: -5%;
}
#red,
#blue_2 {
position: absolute;
top: 0;
left: 0;
}
#blue_2.blue_wrapper_2 {
background: blue;
animation: slideRight 1s forwards;
}
button {
position: fixed;
right: 30px;
bottom: 30px;
}
#keyframes slideRight {
from {
transform: translateX(-110%);
}
to {
transform: translateX(0);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="bg">
<div id="blue" class="skew">blue</div>
<div id="red" class="skew">red</div>
<div id="blue_2" class="skew">blue_2</div>
</div>
<button class="toggle">Toggle</button>

js Tooltip with delayed mouseout without jQuery

I want to display a tooltip when hovering a div. It should also be displayed when the mouse is hovering the tooltip-div.
Adding an event listener does this job, but if both divs are not overlapping the mouseout calls when the mouse is between them and the tooltip disappears.
Now I want to add a delay for the mouseout which is cancelled when it gets a new mouseover, but I don't know how.
document.getElementById("hoverElem").addEventListener("mouseover", function() {
document.getElementById("displayElem").style.visibility = "visible";
});
document.getElementById("hoverElem").addEventListener("mouseout", function() {
document.getElementById("displayElem").style.visibility = "hidden";
});
#hoverElem {
position: fixed;
height: 100px;
weidth: 200px;
top: 0px;
left: 50%;
background-color: white;
}
#displayElem {
position: fixed;
height: 100px;
weidth: 20px;
top: 150px;
left: 50%;
background-color: yellow;
visibility: hidden;
}
<div id="hoverElem">
A little Div
<div id="displayElem">
Tooltip to show
</div>
</div>
You can intiate a timer in the mouseleave and then clear it in mouseenter of
displayElem like
document.getElementById("hoverElem").addEventListener("mouseenter", function() {
document.getElementById("displayElem").style.visibility = "visible";
});
var hoverTimer;
document.getElementById("hoverElem").addEventListener("mouseleave", function() {
hoverTimer = setTimeout(function() {
document.getElementById("displayElem").style.visibility = "hidden";
}, 500);
});
document.getElementById("displayElem").addEventListener("mouseenter", function() {
clearTimeout(hoverTimer);
});
document.getElementById("displayElem").addEventListener("mouseleave", function() {
this.style.visibility = "hidden";
});
#hoverElem {
position: fixed;
height: 100px;
weidth: 200px;
top: 0px;
left: 50%;
background-color: white;
}
#displayElem {
position: fixed;
height: 100px;
weidth: 20px;
top: 150px;
left: 50%;
background-color: yellow;
visibility: hidden;
}
<div id="hoverElem">
A little Div
<div id="displayElem">
Tooltip to show
</div>
</div>
have you considered using pure CSS instead?
div {
position: fixed;
height: 100px;
width: 200px;
top: 0px;
left: 50%;
background-color: black;
}
div:hover span,
span:hover{
opacity:1;
}
span {
display:block;
opacity:0;
color:orange;
-webkit-transition-delay: .5s;
transition-delay: .5s;
-webkit-transition:opacity 1s ;
transition:opacity 1s ;
position: fixed;
height: 100px;
width: 100px;
top: 150px;
left: 50%;
background-color: yellow;
visibility: visible;
}
<div>
<span>lorem Ipsum</span>
</div>

jQuery popup / overlay effect

im really hoping someone can help me out with this project requirement as im new to JS or rather not advanced with it and i only have today to crack this one and no idea how.
Below is an image iwth how the effect needs to be, starts off from top to bottom, your see how it expands but curved at top and bottom until fully open.
Anyone have any ideas on how i can do this is JS / jQuery (non plugin based) i would be forever greateful if someone could help me on this.
Thanks a bunch
You can do that without Javascript / jQuery using just CSS3 border-radius. However, if you need to fire this up through your existing JS code, then simply wrap the style in a class, and apply that class on some event in your JS code.
Remember that in order to have that elliptical effect you have in your question, the block has to be rectangular and not square, otherwise you will end up in a circle.
A simple example snippet:
div {
margin: 16px;
height: 10px; width: 240px;
background-color: red;
border-radius: 50%;
opacity: 0;
transition: all 2s ease-in;
}
a:focus ~ div {
height: 120px; width: 240px;
border-radius: 0px;
opacity: 1;
}
Click
<div></div>
Snippet using jQuery to fire the effect:
$("#btn").on("click", function() {
$("#d1").addClass("effect");
});
div {
margin: 16px;
height: 10px; width: 240px;
background-color: red;
border-radius: 50%;
opacity: 0;
transition: all 2s ease-in;
}
div.effect {
height: 120px; width: 240px;
border-radius: 0px;
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a id="btn" href="#">Click</a>
<div id="d1"></div>
You can try this.
Demo on dabblet
body {
background-color: black;
margin: 0 auto;
overflow: hidden;
}
#overlay {
border-top-left-radius: 1000px 100px;
border-top-right-radius: 1000px 100px;
border-bottom-left-radius: 1000px 100px;
border-bottom-right-radius: 1000px 100px;
width: 100%;
height: 100px;
background-color: white;
margin: 0;
position: absolute;
top: calc(50% - 50px);
-webkit-animation: anim 4s infinite;
animation: anim 4s infinite;
height: 800px;
top: calc(50% - 400px);
}
#-webkit-keyframes anim {
0% {
height: 1px;
top: calc(50% - 0.5px);
}
100% {
height: 800px;
top: calc(50% - 400px);
}
}
#-moz-keyframes anim {
0% {
height: 1px;
top: calc(50% - 0.5px);
}
100% {
height: 800px;
top: calc(50% - 400px);
}
}
<div id="overlay"></div>

Categories