I made a small animation
When clicked, the animated square will change its height, but it will also animate when the window size / scale is changed. How to make it animate only when clicked, and in other cases just resize (no animation)
function myClick() {
document.getElementById("myDiv").style.height = Math.floor(Math.random() * 100) + "vmin";
}
#myDiv {
width: 20vmin;
height: 20vmin;
background: green;
transition: height 1s ease;
}
#myDiv:active {
background: blue;
}
<!DOCTYPE html>
<body>
<div id="myDiv" onclick="myClick()"></div>
</body>
</html>
One method is to add a class with transition and remove it after animation finished:
var timer;
document.getElementById("myDiv").addEventListener("transitionend", function(e)
{
clearTimeout(timer);
document.getElementById("myDiv").classList.toggle("clicked", false);
}, false);
function myClick() {
clearTimeout(timer);
document.getElementById("myDiv").classList.toggle("clicked", true);
document.getElementById("myDiv").style.height = Math.floor(Math.random() * 100) + "vmin";
timer = setTimeout(function() { //backup plan
document.getElementById("myDiv").classList.toggle("clicked", false);
}, 2000);
}
#myDiv {
width: 20vmin;
height: 20vmin;
background: green;
}
#myDiv:active {
background: blue;
}
#myDiv.clicked {
transition: height 1s ease;
}
<body>
<div id="myDiv" onclick="myClick()"></div>
</body>
Another method is to remove transition class when window is resized
function myClick() {
document.getElementById("myDiv").classList.toggle("clicked", true);
document.getElementById("myDiv").style.height = Math.floor(Math.random() * 100) + "vmin";
}
window.addEventListener('resize', function() {
document.getElementById("myDiv").classList.toggle("clicked", false);
});
#myDiv {
width: 20vmin;
height: 20vmin;
background: green;
}
#myDiv:active {
background: blue;
}
#myDiv.clicked {
transition: height 1s ease;
}
<body>
<div id="myDiv" onclick="myClick()"></div>
</body>
The only way I know is the listening window resize event.
We are removing the transition effect while resizing in here;
const myDiv = document.getElementById("myDiv")
window.addEventListener('resize', () => {
myDiv.style.transition = "all 0s ease 0s"
});
But then you have to put the transition back when you click like this;
function myClick() {
if(myDiv.style.transition === "all 0s ease 0s"){
myDiv.style.transition = "height 1s ease";
}
myDiv.style.height = Math.floor(Math.random() * 100) + "vmin";
}
Here's one way. It's a bit crude but it works. The div only has an animate class while the animation is taking place, using a timer. I made the timer longer than necessary and it turns yellow to make clear what's happening. I'm not sure if it can be done without a timer kludge.
let animateTimeout;
function myClick() {
let myDiv = document.getElementById("myDiv");
myDiv.style.height = Math.floor(Math.random() * 100) + "vmin";
myDiv.classList.add("animate");
clearTimeout(animateTimeout);
animateTimeout = setTimeout(() => myDiv.classList.remove("animate"), 1500);
}
#myDiv {
width: 20vmin;
height: 20vmin;
background: green;
}
#myDiv.animate {
background: yellow;
transition: height 1s ease;
}
#myDiv:active {
background: blue;
}
<!DOCTYPE html>
<body>
<div id="myDiv" onclick="myClick()"></div>
</body>
</html>
Related
I learning coding HTML and CSS, I'm practicing this project on this website:https://backstagetalks.com/#issue5.
I'm wondering how can the background color of this website change so smoothly like that.
Long story short
You need to change CSS transition property:
body{
transition:background-color .2s ease-in-out;
}
This will animate/transition changing colors switched by "background-color" property.
If you are unsure of how the background color is changed you can do this:
body{
transition:all .2s ease-in-out;
}
This will animate/transition everything
You can use css transition property
Check the scrollTop and change the backgroundColor when scrollTop reach some number
const back = document.querySelector('.back')
back.addEventListener('scroll', (event) => {
if (back.scrollTop >= 1000 && back.scrollTop < 2000) {
back.style.backgroundColor = '#ffff00'
} else if (back.scrollTop >= 2000 && back.scrollTop < 3000) {
back.style.backgroundColor = '#00ff00'
} else if (back.scrollTop >= 3000 && back.scrollTop < 4000) {
back.style.backgroundColor = '#00ffff'
} else if (back.scrollTop >= 4000 && back.scrollTop < 5000) {
back.style.backgroundColor = '#0000ff'
} else {
back.style.backgroundColor = '#ff0000'
}
})
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.back {
background-color: #ff0000;
height: 296px;
overflow-y: scroll;
transition: background-color 2s ease-in-out; /* Change 2s with delay */
}
.content {
height: 5000px;
overflow: hidden;
}
<div class="back">
<div class="content"></div>
</div>
I would like a bar to animate from left to right. I have a numerical input. After the submit click, the bar should then be animated.
Unfortunately, I don't know how to trigger the animation. I deliberately set the initial width value to 150px to show that the animation actually works, but it not works if be triggered programmatically.
btn = document.getElementById("btn");
btn.addEventListener('click', () => {
const val = document.querySelector('input').value
draw(val);
})
function draw(val) {
bar = document.getElementById("bar");
bar.style.setProperty('--width', (val * 10) + "px");
}
:root {
--width: 150px;
}
#bar{
background:red;
height:50px;
margin:50px;
transform-origin:top;
animation: grow 2s forwards;
}
#keyframes grow {
from {
width:0px;
}
to {
width:var(--width);
}
}
<input value="5">
<button id="btn">draw</button>
<div id="bar"></div>
Instead of animation, use CSS transtion. Then (almost) any change to an element would be animated.
const runIt = () => {
$('.bar').css('width', '100%');
};
.bar {
height: 5px;
border-radius: 5px;
background: blue;
transition: 2s;
width: 10px;
margin-bottom: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="bar"></div>
<button onclick="runIt()">Run</button>
This seems like a perfect use for CSS Transitions. Rather than adding an animation to the element, just set its width to have a transition time. Then, any time you change the width, it will be animated.
const btn = document.getElementById("btn");
btn.addEventListener('click', () => {
const val = document.querySelector('input').value
draw(val);
})
function draw(val) {
bar = document.getElementById("bar");
bar.style.setProperty('width', (val * 10) + "px");
}
#bar{
background:red;
width: 0;
height:50px;
margin:50px;
transform-origin:top;
transition: width 2s; /* Any time the width changes, it will be animated of 2 seconds */
}
<input value="5">
<button id="btn">Click Me</button>
<div id="bar"></div>
How can I change the animation duration onclick? This is what I've done, I created two buttons, one with an animationduration of 10s while the other has an animationduration of 20s. The duration regardless of which button I click is the same, 10 seconds, as it is in the class section. How can I get depending on the button I click two different durations? Please use normal Javascript, no Jquery. Thank you! I also need to use the document.GetElementById().classname =""; as it is in the code.
function tenseconds() {
animation();
var sd = document.getElementById('ghost').className = 'earth';
sd.style.animationDuration = "10s";
}
function twentyseconds() {
animation();
var sd = document.getElementById('ghost').className = 'earth';
sd.style.animationDuration = "20s";
}
function animation() {
document.getElementById('ghost').className = 'earth';
}
<!DOCTYPE html>
<html>
<head>
<style>
.earth {
position: relative;
animation: move 10s linear;
background: red;
height: 20px;
width: 20px;
}
#-webkit-keyframes move {
from {
left: 0%;
}
to {
left: 100%;
}
}
</style>
</head>
<body>
<div id="ghost"> </div>
<button onclick="tenseconds();">10 seconds </button>
<button onclick="twentyseconds()"> 20 seconds </button>
</body>
</html>
Updated to use an animation, data attributes etc. Customize as needed. NOT supported in Edge, IE perhaps others. Leave to you to investigate possible ways to fix that. Review OLD edit for the original "fix"
I added another element and button so you could see how it might be used.
var myAnimation = {
keyframes: [
// keyframes
{
transform: 'translateX(0px)'
},
{
transform: 'translateX(300px)'
}
],
options: {
// timing options
// ms of duration default 1 second
duration: 1000,
iterations: 1, //forever would be Infinity
easing: "linear"
}
};
function animation(target, duration, visual) {
let sd = document.getElementById(target);
sd.className = visual;
myAnimation.options.duration = duration * 1000;
sd.animate(myAnimation.keyframes, myAnimation.options,visual);
}
function setup() {
let classThings = document.getElementsByClassName("animate-button");
let myFunction = function() {
let duration = this.dataset.duration;
let visual = this.dataset.visual;
let target = this.dataset.target;
animation(target, duration, visual);
};
for (var i = 0; i < classThings.length; i++) {
classThings[i].addEventListener('click', myFunction, false);
}
}
(function() {
setup();
})();
<!DOCTYPE html>
<html>
<head>
<style>
.fire {
position: relative;
background: red;
height: 20px;
width: 20px;
}
.water {
position: relative;
background: blue;
height: 20px;
width: 20px;
}
</style>
</head>
<body>
<div id="ghost"></div>
<div id="billy"></div>
<button class="animate-button" data-duration="10" data-target="ghost" data-visual="fire">10 seconds</button>
<button class="animate-button" data-duration="20" data-target="ghost" data-visual="fire">20 seconds</button>
<button class="animate-button" data-duration="5" data-target="billy" data-visual="water">5 seconds billy</button>
</body>
</html>
I created a little function that takes the animation time in seconds as an argument. Read the comments in the code for explanation.
function animation(duration) {
// select whatever element you are trying to animate
let target = document.getElementById('ghost');
// change the animationduration before starting to animate
target.style.animationDuration = `${duration}s`;
// add the animating class and start the animation
target.classList.add('animating');
// create a timeout to remove the animating class from your animated element
setTimeout(() => {
target.classList.remove('animating');
}, `${duration*1000}`);
}
#ghost{
position: relative;
background: red;
height: 20px;
width: 20px;
}
.animating {
animation: move 10s linear;
}
#-webkit-keyframes move {
from {
left: 0%;
}
to {
left: 100%;
}
}
<!DOCTYPE html>
<div id="ghost"> </div>
<button onclick="animation(10);">10 seconds </button>
<button onclick="animation(20);"> 20 seconds </button>
I am trying to make a div slide to the left and THEN disappear. I am using this code.
function slide_in(current_my) {
$("#" + current_my).animate({
left: "510"
}, {
duration: 750
});
document.getElementById(current_my).style.display = "none";
}
if I remove the last line of code the div slides nicely to the left over 750ms. But when I add the last line the div just disappears.
I tired adding:
wait(750);
before the last line, where the 'wait' function was defined as :
function wait(ms)
{
var d = new Date();
var d2 = null;
do { d2 = new Date(); }
while(d2-d < ms);
}
but that just made the div sit there for 750ms and then disappear. Again, what I want is for the 'current_my' div to slide / animate and THEN disappear (display:none). Any ideas? Thank you.
You need to use the complete option of jQuery animate. Also since you already have the object, there is no point in going to find it again. In your complete method, you can just use the this keyword and apply the hiding or any other animation directly to the object again.
$("#" + current_my).animate({ left: "510" }, { duration: 750 }, function() {
$(this).hide();
});
You should hide the div in complete callback
function slide_in(current_my) {
$("#" + current_my).animate({
left: "510"
}, 750, function() {
document.getElementById(current_my).style.display = "none";
});
}
Doc reference
Animate takes a callback when finished.
You could
function slide_in(current_my) {
$("#" + current_my).animate({
left: "510"
}, {
duration: 750
}, function () {
document.getElementById(current_my).style.display = "none";
});
}
An alternative using animate.css, you would need to adjust the animation duration on the css file.
$(document).ready(function() {
$('button.btn').click(function() {
$('div.box').addClass('animated fadeOutLeftBig');
});
});
.box {
width: 50px;
height: 50px;
margin-left: 200px;
background-color: red;
}
.box p {
text-align: center;
font-size: 1em;
}
div.box {
-webkit-animation-duration: 5s;
-webkit-animation-delay: 0s;
-moz-animation-duration: 5s;
-moz-animation-delay: 0s;
-ms-animation-duration: 5s;
-ms-animation-delay: 0s;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box">
<p>Test</p>
</div>
<button class="btn">Fade Left</button>
This is slightly more than asked but lets make it fun. Toss in an event to trigger the animation instead of a function, passing the location and duration numbers just for fun:
$(document).on('slidehide', '.myanimate', function(event, requstedduration, whereto, shouldhide) {
var p = $(this).position();
$(this).animate({
left: whereto
}, {
duration: requstedduration,
start: function() {$('.silly').toggle(shouldhide);},
complete: function() {
$(this).toggle(!shouldhide);
}
});
});
$('.myanimate').on('click', function() {
console.log('moving');
$(this).trigger('slidehide', [750, 510, true]);
});
// just so we can restart/see again
$(document).on('click', '.silly', function() {
console.log('restart');
$('.myanimate').show().trigger('slidehide', [750, 10, false]);;
});
.myanimate {
position: absolute;
left: 100px;
}
.silly {
display: none;
)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="myanimate">howdy there (click to trigger)</div>
<div class='silly'>Animation complete. (click to restart)</div>
I want to have a fixed nav which fades out when the mouse isn't moving and fades back in when it does.
I've came across this other post which does the job but the problem is that it uses visibility and I want to use opacity that way I can make it fade in and out with a transition transition: all .4s ease-in-out;
$("#fp-nav").style.opacity = "0";
$("html").mousemove(function(event) {
$("#fp-nav").style.opacity = "1";
myStopFunction();
myFunction();
});
function myFunction() {
myVar = setTimeout(function() {
$("#fp-nav").style.opacity = "0";
}, 1000);
}
function myStopFunction() {
if (typeof myVar != 'undefined') {
clearTimeout(myVar);
}
}
#fp-nav {
position: fixed;
z-index: 100;
top: 50%;
opacity: 1;
-webkit-transform: translate3d(0, 0, 0);
transition: all .4s ease-in-out;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="fp-nav">
Hello world Hello world Hello world Hello world
</div>
Or am I supposed to use fp-nav.style.opacity = "0"; instead of $("#fp-nav").style.opacity = "0";
You can replace .hide() and .show() by your own css code to visually hide the bar: hide becomes css("opacity", 0) and show becomes css("opacity", 1).
Then, you add a transition to your bar:
.navbar {
transition: opacity 1000ms ease-in-out;
};
$("div").css("opacity", 0);
$("html").mousemove(function( event ) {
$("div").css("opacity", 1);
myStopFunction();
myFunction();
});
function myFunction() {
myVar = setTimeout(function(){
$("div").css("opacity", 0);
}, 1000);
}
function myStopFunction() {
if(typeof myVar != 'undefined'){
clearTimeout(myVar);
}
}
div {
transition: opacity 1000ms ease-in-out;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>navbar</div>
It might be nice to let the css define how you want to hide/show via an additional class. You can then, for example, use addClass("is-hidden") and removeClass("is-hidden"):
var hiddenClass = "is-hidden";
var customHide = function($el) {
$el.addClass(hiddenClass);
}
var customShow = function($el) {
$el.removeClass(hiddenClass);
}
customHide($("div"));
$("html").mousemove(function( event ) {
customShow($("div"));
myStopFunction();
myFunction();
});
function myFunction() {
myVar = setTimeout(function(){
customHide($("div"));
}, 1000);
}
function myStopFunction() {
if(typeof myVar != 'undefined'){
clearTimeout(myVar);
}
}
/* CSS now determines how we want to hide our bar */
div {
position: relative;
background: green;
transition: transform 500ms ease-in-out;
}
div.is-hidden {
transform: translateY(-160%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>navbar</div>
$(document).on('mousemove', function(){
$('#nav').addClass('shown');
setTimeout(function(){
$('#nav').removeClass('shown');
}, 5000);
});
#nav {
opacity: 0;
transition: opacity 1s ease-in-out;
background: black;
width: 300px;
height: 100px;
}
#nav.shown {
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="nav">
</div>
Here's my go:
Obviously, edit the timings and opacity as needed. The animations themselves are pure CSS, and JS is just used to add/remove a class from the nav.