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>
Related
I have one outer box and an inner box and there are some identical boxes with the same class names inside the second box. I want all of these boxes to appear one after the other with this fade-in effect. So far I have done it for the outer and inner div, and I wanted to use the same function for all the identical boxes inside. I tried to do the same for outer and inner div since they too just need the exact same function. But I wasn't successful. Here is my code :
html:
<div class="div1">
<div class="div2">
<div class="div3"></div>
<div class="div3"></div>
<div class="div3"></div>
<div class="div3"></div>
<div class="div3"></div>
</div>
</div>
javascript:
let div1 = document.getElementsByClassName("div1")[0];
let div2 = document.getElementsByClassName("div2")[0];
let div3 = document.getElementsByClassName("div3");
div1.style.visibility = "hidden";
div2.style.visibility = "hidden";
function first() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
div1.style.animation = "fadein 5s";
div1.style.visibility = "visible";
resolve("div1 worked!");
}, 1000);
});
}
function second() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
div2.style.animation = "fadein 5s";
div2.style.visibility = "visible";
resolve("div2 worked!");
}, 1000);
});
}
function abc(element) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
element.style.animation = "fadein 5s";
element.style.visibility = "visible";
resolve("third");
}, 1000);
});
}
first()
.then(second)
.then((div3) => {
div3.forEach((element) => {
abc(element);
});
});
css
.div1 {
width: 400px;
height: 500px;
background-color: yellow;
}
.div2 {
width: 350px;
height: 400px;
background-color: green;
}
.div3 {
width: 300px;
height: 50px;
background-color: grey;
margin: 10px;
}
#keyframes fadein {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
The first two works and I don't know how I can reuse the function for the remaining div3 class divs. I tried to reuse the function for the first two as well, but it didn't work and ended up writing same functions again and again. I want to call function abc for each element in div3 and only execute the next one after the first element is done - like how it executes for first and second but using the same function. Not sure how to do that and I'm stuck. Here is a codepen link. As of now all the div3 divs appear together with the second div.
You can use loops and animation-delay to apply the animation as per your need. The following code will work for this case. Code is full with comments to explain what is happening at each point. I have also slightly modified the css so that we don't get any weird blinking effect while executing the code.
//Declare all the classes -
let divs = ["div1", "div2", "div3"];
//Initiate a delay for each iteration
let delay = 0;
//Run a loop for each class
for(let i = 0; i<divs.length; i++){
//Get the element
let div = document.getElementsByClassName(divs[i]);
//Run a loop for element with the class
//(We only have one div with the classes div1 and div2. So it will run one time for them.
//We have 5 divs with div3 class. It will run 5 times in that case
for(let j = 0; j<div.length; j++){
//Get the individual element and add animation with delay
//The delay will also ensure that the animation starts only when the previous element has finished the animation
div[j].style.animation = `fadein 5s ${delay}s forwards` ;
div[j].classList.add("show");
//Increase delay with every iteration
delay+=5;
}
}
div {
visibility: hidden;
}
.div1 {
width: 400px;
height: 500px;
background-color: yellow;
}
.div2 {
width: 350px;
height: 400px;
background-color: green;
}
.div3 {
width: 300px;
height: 50px;
background-color: grey;
margin: 10px;
}
.show {
opacity: 0;
visibility: visible;
}
#keyframes fadein {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
<div class="div1">
<div class="div2">
<div class="div3">1</div>
<div class="div3">2</div>
<div class="div3">3</div>
<div class="div3">4</div>
<div class="div3">5</div>
</div>
</div>
The script may seem very long but it is only 10 lines long without the comments. This will also work if you increase or decrease the number of divs
This is one way to solve the problem using setInterval for executing a piece of code every x seconds.
The function fadeIn takes an array of elements that will be faded in by adding the class "show" (se details for "show" in CSS-code below). This will animate the given elements.
The function start collects the elements that will be faded and fades in the first collection of element, then countinuesly fades in the rest of the elements in the array "elements" every 3 seconds.
function fadeIn(el) {
// For every element in the collection
for (var i = 0; i < el.length; i++) {
// Add the class "show"
el[i].classList.add('show');
}
}
function start() {
/*
Collects all the elements that we want to fadeIn in order. First collection of elements will be animated firstly, second collection of elements will be animated secondly, etc.
*/
var elements = [];
elements.push(document.getElementsByClassName("div1"));
elements.push(document.getElementsByClassName("div2"));
elements.push(document.getElementsByClassName("div3"));
// Show the first collection of elements
fadeIn(elements[0]);
// Show the rest of the element collections in array "elements"
var i = 1;
fadeInInterval = setInterval(function() {
fadeIn(elements[i]);
// If there is no more collections to fade in, end the setInterval
if (i == elements.length-1) {
clearInterval(fadeInInterval)
}
i++
}, 3000) // Every 3 seconds
}
start();
div {
visibility: hidden;
}
.div1 {
width: 400px;
height: 500px;
background-color: yellow;
}
.div2 {
width: 350px;
height: 400px;
background-color: green;
}
.div3 {
width: 300px;
height: 50px;
background-color: grey;
margin: 10px;
}
.show {
animation: fadein 5s;
visibility: visible;
}
#keyframes fadein {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
<div class="div1">
<div class="div2">
<div class="div3"></div>
<div class="div3"></div>
<div class="div3"></div>
<div class="div3"></div>
<div class="div3"></div>
</div>
</div>
I have a video player transforming to display at the bottom of the video on hover.
How can I hide the div again after 3 seconds of the video time, even when hovering over the video?
.video-block {
display: flex;
}
.box-btns {
position: absolute;
display: flex;
flex-wrap: wrap;
bottom: 0;
width: 100%;
background-color: rgba(54, 91, 160, 0.56);
z-index: 2;
flex: 1;
transform: translateY(100%);
transition: transform 0.9s;
}
.video-block:hover {
transform: translateY(0%);
transition: transform 0.2s;
}
<div class="video-block">
<video id="main-video" src="../css/abc.mp4"></video>
<div class="media-box">
<div class="box-btns">
<button onclick="playVideo()" class="play-btn">
<i class="ion-play"></i>
</button>
<button onclick="pauseVideo()" class="pause-btn">
<i class="ion-pause"></i>
</button>
</div>
</div>
</div>
If I assume well you want to hide the controls after certain seconds of moving the mouse over rather than after playing. Otherwise you would not be able to pause the video.
I am going to use JavaScript for this. First of all added the mousemove event to add and remove the class responsable of showing the button controls instead of using CSS. I add the box-btns--visible class to the video controls whenever there is a mouse movement over the video. Then I create a 3 seconds timer to remove the box-btns--visible class from the controls, but if I move the mouse before the timer ends I reset the timer. I added the play and pause events and an open source video for you to play around. You can visit this documentation links for better understanding.
HTMLMediaElement
Mouse over event It is not the same event but it has a good example related to your use case
const playButton = document.querySelector('.play-btn');
const pauseButton = document.querySelector('.pause-btn');
const video = document.getElementById('main-video');
const controls = document.querySelector('.box-btns');
let timer;
function hideControls() {
timer = setTimeout(() => controls.classList.remove('box-btns--visible'), 3000);
}
function preventHideControls() {
clearTimeout(timer);
}
video.addEventListener('mousemove', function(e) {
controls.classList.add('box-btns--visible');
preventHideControls();
hideControls();
});
playButton.addEventListener('click', async function(e) {
try {
await video.play();
playButton.setAttribute('disabled', '');
pauseButton.removeAttribute('disabled');
} catch (err) {
playButton.removeAttribute('disabled');
}
});
pauseButton.addEventListener('click', async function(e) {
try {
await video.pause();
pauseButton.setAttribute('disabled', '');
playButton.removeAttribute('disabled');
} catch (err) {
pauseButton.removeAttribute('disabled');
}
});
.video-block {
display: flex;
width: 300px;
height: 100px;
background-color: red;
position: relative;
overflow: hidden;
}
.box-btns {
position: absolute;
display: flex;
flex-wrap: wrap;
bottom: 0;
left: 0;
width: 100%;
opacity: 0;
background-color: rgba(54, 91, 160, 0.56);
z-index: 2;
flex: 1;
transform: translateY(100%);
transition: all 0.9s ease;
}
.box-btns--visible {
transform: translateY(0%);
transition: transform 0.2s;
opacity: 1;
}
.playing {
background-color: black;
color: white;
}
<div class="video-block">
<video id="main-video" src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"></video>
<div class="media-box">
<div class="box-btns">
<button class="play-btn">
Play
</button>
<button class="pause-btn" disabled>
Pause
</button>
</div>
</div>
</div>
I will show you some example so I think you can get some Idea of that
I used JQuery!
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
This part show video on the webpage
<video width=640 muted src="CotswoldSequence1.mov" id="playvid" ontimeupdate="getvidtime(this)"></video>
I use this part to get the current time of the video
ontimeupdate="getvidtime(this)"
This one show you current time of the video during the playing
function getvidtime(event) {
getCurrentTime = Math.trunc(event.currentTime);
document.getElementById("demo").innerHTML = getCurrentTime;
}
This one is show the time when you move the mouse over the video
$('#myvid').mouseenter(function(){
$( ".demox" ).text(getCurrentTime);
});
This section when you move mouse on the video button will be show otherwise it will be hide
$('#myvid').mouseenter(function(){
$('#playbtn').show();
});
$('#myvid').mouseleave(function(){
$('#playbtn').hide();
});
In this section when click the button if ID equel to button ID video will be play and after 3sec button hide as well as when you move mouse out of the the video and then move mouse on the video you can see the which second mouse move on the video " $( ".demox" ).text(getCurrentTime);" and after 3sec buttton hide
$('#playbtn').click(function(){
if(this.id == 'playbtn'){
$('#playvid')[0].play();
setTimeout(() => {
$('#playbtn').fadeOut();
}, 3000);
$('#myvid').mouseenter(function(){
$( ".demox" ).text(getCurrentTime);
setTimeout(() => {
$('#playbtn').hide();
}, 3000);
});
}
});
Here is the full code
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
</head>
<div class = container style="max-width: 640px;" id="myvid">
<video width=640 muted src="CotswoldSequence1.mov" id="playvid" ontimeupdate="getvidtime(this)"></video>
<div>
<button class=controls id="playbtn" style="position: fixed; top: 332px; left: 12px;">Play/pause</button>
</div>
<p>Playback position: <span id="demo"></span></p>
Mouseenter position: <p class="demox"></p>
</div>
<script>
var getCurrentTime;
function getvidtime(event) {
getCurrentTime = Math.trunc(event.currentTime);
document.getElementById("demo").innerHTML = getCurrentTime;
}
$(document).ready(function(){
$('#myvid').mouseenter(function(){
$('#playbtn').show();
});
$('#myvid').mouseleave(function(){
$('#playbtn').hide();
});
$('#playbtn').click(function(){
if(this.id == 'playbtn'){
$('#playvid')[0].play();
setTimeout(() => {
$('#playbtn').fadeOut();
}, 3000);
$('#myvid').mouseenter(function(){
$( ".demox" ).text(getCurrentTime);
setTimeout(() => {
$('#playbtn').hide();
}, 3000);
});
}
});
});
</script>
I used settimeout because it give same time for the video time
you can use your own video to src="CotswoldSequence1.mov" here
copy this code and past to your editor and run see whats happen!
I think you can get some idea!
I have a simple script where random keywords appear at a timed interval. What I'd like is for them to stop appearing after one is clicked on.
Here's what I have so far:
function generate() {
$("[id*='keyword']").each(function(){
$(this).removeClass("show");
})
var number= Math.floor(Math.random() * 5) + 1
$("#keyword"+number).addClass("show");
}
$(function(){
setInterval(generate, 4000);
})
$("[id*='keyword']").click(function() {
clearInterval(generate);
});
div[id*='keyword']{
background: #aaa;
position: absolute;
left: -200px;
opacity: 0;
width:200px;
line-height: 60px;
text-align: center;
color: white;
height: 60px;
-webkit-transition: 1s all ease;
transition: 1s all ease;
}
div[id*='keyword'].show{
left: 0;
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="keyword1" class="keyword">
<h3>Keyword1</h3>
</div>
<div id="keyword2" class="keyword">
<h3>Keyword2</h3>
</div>
<div id="keyword3" class="keyword">
<h3>Keyword3</h3>
</div>
The random keyword appearing works fine, but the clearInterval function is not. I feel like I'm missing something simple here.
Thanks!
do like that way,
var intervalTime=0;
$(function(){
intervalTime = setInterval(generate, 4000);
})
$("[id*='keyword']").click(function() {
clearInterval(intervalTime);
});
change two lines of your code like the following:
window.intervalID = setInterval(generate, 4000);
and
clearInterval(window.intervalID);
I have created the following code that on page load adds opacity: 1 to all divs on the page. In doing so all the images are seen on pageload, but I want each to fade in slowly and after one has completely loaded/is visible I want the 2nd image to load exactly the same then followed by the third.
How can I accomplish this via the code below; what needs to be changed/added? Please note it must use pure Javascript; no CSS3 or jQuery as the proprietary framework I'm working in requires pure JS.
var imageOne = document.getElementById('imageOne');
var imageTwo = document.getElementById('imageTwo');
var imageThr = document.getElementById('imageThr');
function fadeIn() {
imageOne.style.opacity = '1';
imageTwo.style.opacity = '1';
imageThr.style.opacity = '1';
}
#imageOne {
background: url('https://thingiverse-production-new.s3.amazonaws.com/renders/16/04/2d/b5/ed/smiley_face_thumb_small.jpg');
background-repeat: no-repeat;
width: 50px;
height: 50px;
margin-right: 20px;
float: left;
opacity: 0;
}
#imageTwo {
background: url('http://www.mpaart.org/wp-content/uploads/2015/07/twitter-logo-round-50x50.png');
background-repeat: no-repeat;
width: 50px;
height: 50px;
margin-right: 20px;
float: left;
opacity: 0;
}
#imageThr {
background: url('http://orig08.deviantart.net/24c1/f/2009/238/d/8/small_50x50__png_clock_pic_by_counter_countdown_ip.png');
background-repeat: no-repeat;
width: 50px;
height: 50px;
float: left;
opacity: 0;
}
<body onload="fadeIn()">
<div id="wrapper">
<div id="imageOne"></div>
<div id="imageTwo"></div>
<div id="imageThr"></div>
</div>
</body>
You can use CSS transitions, which is faster and won't require jQuery.
.fadeIn {
transition: opacity 1.25s;
}
Add the class fadeIn to your image elements, and now it'll fade.
To make it fade one after the other, use JavaScript timers to space out setting opacity to 1. Example:
var elements = [ /* Image elements to fade */ ];
for (var i = 0; i < elements.length; i++) {
setTimeout(function() {
elements[i].style.opacity = 1;
}, 1250 * i);
}
You can use callback function of fadeIn to load other image
function fadeIn() {
$("#imageOne").fadeIn("fast",function(){
$("#imageTwo").fadeIn("fast", function(){
$("#imageThr").fadeIn("fast");
});
});
}
This is what I came up with so far. Unfortunately, I haven't figure how to have them fade in, as the below just makes them appear one after the other. Though it's pure Javascript.
Any suggestions?
var imageOne = document.getElementById('imageOne');
var imageTwo = document.getElementById('imageTwo');
var imageThr = document.getElementById('imageThr');
function fadeIn(element) {
element.style.opacity += 0.9;
if (element.style.opacity < 1) {
setTimeout(function() {
fadeIn(element);
}, 100);
}
}
setTimeout(function() {
fadeIn(document.getElementById("imageOne"));
}, 1000);
setTimeout(function() {
fadeIn(document.getElementById("imageTwo"));
}, 5000);
setTimeout(function() {
fadeIn(document.getElementById("imageThr"));
}, 10000);
Here is the spinet:
$('#processing .progress-bar').animate({'width':'60%'},4000);
Is it possible to display how the milliseconds are being countdown by the function?
for instance I want to be able to display:
4000
3000
2000
1000
0000
then the function stops
You can add a step function to the jquery animate, and inside calcualte how much time is left for the animation to finish:
$(function () {
var Now = 0;
var animationDuration = 4000;
var DesiredWidth = "200";
$(".test").animate({
width: DesiredWidth
}, {
easing:"linear",
duration: animationDuration,
//the argument in the step call back function will hold the
// current position of the animated property - width in this case.
step: function (currentWidth,fx) {
Now = Math.round((100/DesiredWidth)*currentWidth);
$(".ms_span").text(Now+"%");
}
});
});
div {
width: 0;
height: 100px;
display: block;
background: purple;
position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="test"></div>
<br/>Percent: <span class="ms_span">
var duration = 4000,
interval = 1000,
pbar = $('#processing .progress-bar');
pbar.text( duration );
var cd = setInterval(function() {
duration -= interval;
pbar.text( duration );
}, interval);
pbar.animate({'width':'60%'}, duration, function() {
clearInterval(cd);
pbar.text( '0000' );
});
.progress-bar {
background-color: black;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="processing">
<div class="progress-bar">pBar</div>
</div>
After looking at #Banana's solution, I realized that I had completely forgotten about the step function and the new(ish) progress function, both of which can be passed to .animate. My updated solution is below, and I have removed the other to avoid confusion.
var $steps = $("#steps");
$('#processing .progress-bar').animate({
'width': '60%'
}, {
duration: 4000,
progress: function(prom, prog, rem) {
$steps.html("Prog: " + prog + "<br/>Rem: " + rem);
}
});
#processing {
width: 80%;
margin: 5%;
border: 2px solid black;
height: 25px;
}
#processing .progress-bar {
height: 100%;
background: lime;
width: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div>
<div id="processing">
<div class="progress-bar"></div> <span id="steps"></span>
</div>
</div>
As a side-note, depending on what you are planning to use this for, the other thing that you might want to look into is jQuery's .progress method, which handles progress notifications. Note that I am fairly certain that calling .progress on animations themselves won't have any effect unless you use a solution like the above to make progress notifications at each step of the animation. This is done with calls to .notify or .notifyWith but doing this in an animation is a little extreme. Regardless, this can be useful for situations in which you have an asynchronous call running for an indeterminate amount of time.
Docs for deferred.promise.
Docs for deferred.notify.
Docs for deferred.notifyWith.