I've been working on a very simple animation script. The images are to move when clicked, stop when clicked again, etc. I have this all working fine. The trouble is I have a stop everything button below the images which is suppose to not only stop the images but to return them to their original position. So far it stops, but it doesn't return.
I've searched and found a few different solutions, however this is a university assignment and I am NOT allowed to use Jquery.
This is my script:
var timer = null;
var cat = null;
var dog = null;
function moveOver1Pixel()
{
cat.style.left = parseInt(cat.style.left) + 1 + "px";
}
function moveOver10Pixels()
{
dog.style.left = parseInt(dog.style.left) + 10 + "px";
}
window.onload=function()
{
//MOVE CAT FUNCTION
cat = document.getElementById("cat");
cat.onclick=function(){
if(timer == null)
{
timer = setInterval("moveOver1Pixel();", 100);
}else{
clearInterval(timer);
timer = null;
}
}
// MOVE DOG FUNCTION
dog = document.getElementById("dog");
dog.onclick=function(){
if(timer == null)
{
timer = setInterval("moveOver10Pixels();", 30);
}else{
clearInterval(timer);
timer = null;
}
}
// STOP BUTTON FUNCTION
document.getElementById("stop").onclick=function()
{
window.clearInterval(timer);
timer = null;
reset = true;
}
}
and this is the html portion I am using:
<img src="cat.jpg" id="cat" style="height:100px;position:absolute;left:10px">
<img src="dog.jpg" id="dog" style="height:100px;position:absolute;left:10px;top:110px">
<input type="button" value="EVERYONE STOP" id="stop" style="position:absolute;left:10px;top:220px">
I feel like the solution to my problem should be simple... something I'm missing inside of the button's onclick function? Or am I going to have to create an entirely new function for the reset/return of the images to their original place?
I changed a lot:
var timer, cat, dog, ticksCat = 0, ticksDog = 0,
moveOver1Pixel = function(inc){
cat.style.left = parseInt(cat.style.left) + inc + "px";
// Don't change if inc is -1, ~-1 === 0 == false
if(~inc) ticksCat+=inc;
},
moveOver10Pixels = function(inc){
dog.style.left = parseInt(dog.style.left) + inc*10 + "px";
if(~inc) ticksDog+=inc;
};
window.onload=function(){
//MOVE CAT FUNCTION
cat = document.getElementById("cat");
cat.onclick=function(){
if(!timer){
timer = setInterval(function(){
moveOver1Pixel(+1);
}, 100);
}else{
clearInterval(timer);
timer = null;
}
};
// MOVE DOG FUNCTION
dog = document.getElementById("dog");
dog.onclick=function(){
if(!timer){
timer = setInterval(function(){
moveOver10Pixels(+1);
}, 30);
}else{
clearInterval(timer);
timer = null;
}
};
// STOP BUTTON FUNCTION
document.getElementById("stop").onclick=function(){
window.clearInterval(timer);
timer = null;
reset = true;
// to do immediately
while(ticksCat--){ moveOver1Pixel(-1); }
while(ticksDog--){ moveOver10Pixels(-1); }
/* animated
while(ticksCat--){ setTimeout(function(){moveOver1Pixel(-1)}, 100*ticksCat);}
while(ticksDog--){ setTimeout(function(){moveOver10Pixels(-1)}, 30*ticksDog);}
Multiplication on time is to synchronously set a queue of async moves
*/
};
};
How about this?
document.getElementById("stop").onclick=function()
{
window.clearInterval(timer);
timer = null;
reset = true;
document.getElementById("cat").style.left = "10px"
document.getElementById("dog").style.left = "10px"
}
var timer = null;
var cat = null;
var dog = null;
function moveOver1Pixel()
{
cat.style.left = parseInt(cat.style.left) + 1 + "px";
}
function moveOver10Pixels()
{
dog.style.left = parseInt(dog.style.left) + 10 + "px";
}
window.onload=function()
{
//MOVE CAT FUNCTION
cat = document.getElementById("cat");
cat.onclick=function(){
if(timer == null)
{
timer = setInterval("moveOver1Pixel();", 100);
cat.startLeft=cat.offsetLeft;
cat.startTop=cat.offsetTop;
}else{
clearInterval(timer);
timer = null;
}
}
// MOVE DOG FUNCTION
dog = document.getElementById("dog");
dog.onclick=function(){
if(timer == null)
{
timer = setInterval("moveOver10Pixels();", 30);
dog.startLeft=dog.offsetLeft;
dog.startTop=dog.offsetTop;
}else{
clearInterval(timer);
timer = null;
}
}
// STOP BUTTON FUNCTION
document.getElementById("stop").onclick=function()
{
window.clearInterval(timer);
timer = null;
reset = true;
if (typeOf cat.startLeft !=undefined)
{
cat.style.left=cat.startLeft+"px";
cat.style.top=cat.startTop+"px";
}
if (typeOf dog.startLeft !=undefined)
{
dog.style.left=dog.startLeft+"px";
dog.style.top=dog.startTop+"px";
}
}
}
A more modern and "proper" solution to would be to use css transitions to handle the animation while using JS to control the position:
var cat = document.getElementById("cat");
var dog = document.getElementById("dog");
cat.addEventListener('click', moveIt);
dog.addEventListener('click', moveIt);
function moveIt()
{
this.style.left = "400px";
}
// STOP BUTTON FUNCTION
document.getElementById("stop").addEventListener('click', function()
{
cat.style.removeProperty('left');
dog.style.removeProperty('left');
//Uncomment for instant-reset
/*
cat.style.transitionDuration = dog.style.transitionDuration = '0s';
window.setTimeout(function()
{
cat.style.removeProperty('transition-duration');
dog.style.removeProperty('transition-duration');
}, 250);
*/
});
With your css looking something like this:
#cat, #dog
{
position: absolute;
left: 10px;
transition: 10s left linear;
}
#cat
{
left: 25px
}
#dog
{
transition-duration: 1s;
}
See this JSFiddle for a demo: http://jsfiddle.net/SPHMM/3/. Of course, if the assignment is specifically to do all the animation in javascript, this probably doesn't count. But for real life applications, this should provide the best quality, lowest cpu usage animation.
Related
I am trying to fade the volume of an mp3 in to 1 if the body has the class fp-viewing-0
How ever this isn't working and the volume doesn't change how can I fix this?
Code:
var audio0 = document.getElementById('audio-0');
audio0.volume = 0;
setInterval( function(){
if ($("body").hasClass("fp-viewing-0")) {
audio0.animate({volume: 1}, 1000);
}
else {
audio0.animate({volume: 0}, 1000);
}
}, 100);
HTML
<audio id="audio-0" src="1.mp3" autoplay="autoplay"></audio>
I've also tried:
$("#audio-0").prop("volume", 0);
setInterval( function(){
if ($("body").hasClass("fp-viewing-0")) {
$("#audio-0").animate({volume: 1}, 3000);
}
else {
$("#audio-0").animate({volume: 0}, 3000);
}
}, 100);
Kind Regards!
I have changed the jquery animate part to a fade made by hand. For that i created a fade time and steps count to manipulate the fade effect.
var audio0 = document.getElementById('audio-0');
audio0.volume = 0;
if ($("body").hasClass("fp-viewing-0")) {
audio0.volume = 1; //max volume
var fadeTime = 1500; //in milliseconds
var steps = 150; //increasing makes the fade smoother
var stepTime = fadeTime/steps;
var audioDecrement = audio0.volume/steps;
var timer = setInterval(function(){
audio0.volume -= audioDecrement; //fading out
if (audio0.volume <= 0.03){ //if its already inaudible stop it
audio0.volume = 0;
clearInterval(timer); //clearing the timer so that it doesn't keep getting called
}
}, stepTime);
}
Better would be to place all of this in a function that receives these values a fades accordingly so that it gets organized:
function fadeAudio(audio, fadeTime, steps){
audio.volume = 1; //max
steps = steps || 150; //turning steps into an optional parameter that defaults to 150
var stepTime = fadeTime/steps;
var audioDecrement = audio.volume/steps;
var timer = setInterval(function(){
audio.volume -= audioDecrement;
if (audio.volume <= 0.03){ //if its already inaudible stop it
audio.volume = 0;
clearInterval(timer);
}
}, stepTime);
}
Which would make your code a lot more compact and readable:
var audio0 = document.getElementById('audio-0');
audio0.volume = 0;
if ($("body").hasClass("fp-viewing-0")) {
fadeAudio(audio0, 1500);
}
i have time progress bar. i use this code.i need time runner inside blue box.
how can i fix it, means when the yellow bar move depends on time need a time
display box.
var timer = 0,
perc = 0,
timeTotal = 2500,
timeCount = 1,
cFlag;
function updateProgress(percentage) {
var x = (percentage/timeTotal)*100,
y = x.toFixed(3);
$('#pbar_innerdiv').css("width", x + "%");
$('#pbar_innertext').text(y + "%");
}
function animateUpdate() {
if(perc < timeTotal) {
perc++;
updateProgress(perc);
timer = setTimeout(animateUpdate, timeCount);
}
}
$(document).ready(function() {
$('#pbar_outerdiv').click(function() {
if (cFlag == undefined) {
clearTimeout(timer);
perc = 0;
cFlag = true;
animateUpdate();
}
else if (!cFlag) {
cFlag = true;
animateUpdate();
}
else {
clearTimeout(timer);
cFlag = false;
}
});
});
#pbar_outerdiv { cursor: pointer; }
You already have the actual time in the updateProgress() method, so its as simple as changing the line setting the percentage to this:
$('#pbar_innertext').text((percentage / 100).toFixed(2) + " s");
JSFiddle: https://jsfiddle.net/McNetic/hnfRe/395/
Edit: With different browser, I now see the next problem: The animation can take much longer than the advertised time of 2500 ms (because of the very high update frequency of 1000 frames per second). So you should do less animation frames and calculate the percentage base on actual time measuring, like this:
https://jsfiddle.net/McNetic/hnfRe/396/
Check this JSFiddle. You can adjust the CSS: colours, sizes, etc to your needs.
Basically I put the text outside the #pbar_innerdiv in a span box.
<div id="pbar_outerdiv">
<div id="pbar_innerdiv"></div>
<span id="pbar_innertext">Click!</span>
</div>
Edit
So I edited the script and I hope now it matches your needs: JSFiddle Link. This is the script I used:
var timer = 0,
perc = 0,
percIncreaser,
timeTotal = 2500, //Only change this value time according to your need
timeCount = 1,
secondsCount=0,
cFlag;
function updateProgress(percentage,time) {
//var x = (percentage/timeTotal)*100;
$('#pbar_innerdiv').css("width", percentage + "%");
$('#pbar_innertext').text(time/1000 + "s");
}
function animateUpdate() {
if(perc < timeTotal) {
perc+=percIncreaser;
secondsCount+=10;
updateProgress(perc,secondsCount);
if(perc>=100) clearTimeout(timer);
else timer = setTimeout(animateUpdate, timeCount);
}
}
$(document).ready(function() {
$('#pbar_outerdiv').click(function() {
percIncreaser = 100/timeTotal*10;
if (cFlag == undefined) {
clearTimeout(timer);
perc = 0;
cFlag = true;
animateUpdate();
}
else if (!cFlag) {
cFlag = true;
animateUpdate();
}
else {
clearTimeout(timer);
cFlag = false;
}
});
});
I'm making a race where two images move to the right a random number of px's but they won't stop with the clear interval, the alert "stop" works. I'm using a red and green picture with changing z-indexes like a stoplight for the user to start and stop the race.
<script type="text/javascript">
var ship = 0;
var ufo = 0;
function random()
{
var rand = Math.floor((Math.random() * 15) + 1);
var rand2 = Math.floor((Math.random() * 15) + 1);
ship = ship + rand;
ufo = ufo + rand2;
document.getElementById("ufo").style.left = ufo + 'px';
document.getElementById("spaceship").style.left = ship + 'px';
}
function start()
{
if(document.getElementById("red").style.zIndex == 1)
{
document.getElementById("red").style.zIndex = "0";
alert("go");
var timer = setInterval(function() {random()},1000);
}
else
{
document.getElementById("green").style.zIndex = "0";
document.getElementById("red").style.zIndex = "1";
clearInterval(timer);
alert("stop");
}
}
</script>
Because var timer only exists within the if statement. You need to move it outside of the start() function, like this:
var timer;
function start()
{
if(document.getElementById("red").style.zIndex == 1)
{
document.getElementById("red").style.zIndex = "0";
alert("go");
timer = setInterval(function() {random()},1000);
}
else
{
document.getElementById("green").style.zIndex = "0";
document.getElementById("red").style.zIndex = "1";
clearInterval(timer);
alert("stop");
}
}
I am trying to make a slide show in mootools, and was trying delay function to make a periodic effect in slideshow but it was not working. So i am planning to make a timer function, but have no idea how to do that.
here is something which i have done..i little messy i guess
function slideImages(id_new, id_old){
console.log($(id_new));
$(id_old).tween('opacity', [1,0]);
$(id_old).setStyle('display','none');
$(id_old).tween('margin-left', -980);
$(id_new).setStyle('display', 'block');
$(id_new).tween('opacity', [0,1]);
$(id_new).tween('margin-left', 180);
var c = id_new;
var d = id_old;
//timer = setInterval ( "timerFunction()", 5000 );
(slide(c, d)).delay(5000); //this isn't working and browser is getting hanged
}
function slide(c, d){
console.log(c);
if (c.split('_')[1].toInt() > 2){
id_new = 'image_'+ 0 ;
console.log(id_new);
}
else{
id_new = 'image_'+ (c.split('_')[1].toInt()+1);
console.log(id_new);
}
id_old = c;
slideImages(id_new, id_old);
};
there are many ways to use delay or setTimeout. here they are:
function slideImages(id_new, id_old) {
var c = $(id_new);
var d = $(id_old);
d.tween('opacity', [1, 0]);
d.setStyle('display', 'none');
d.tween('margin-left', -980);
c.setStyle('display', 'block');
c.tween('opacity', [0, 1]);
c.tween('margin-left', 180);
// your timer becomes global here, careful. crappy pattern.
// use a closure so it goes in the upper scope, allowing you to stop.
// cancel by clearTimeout(timer)
// pass function to delay, scope = null, arguments
timer = slide.delay(5000, null, [c, d]);
// or
timer = (function() {
slide(c, d);
}).delay(5000);
// or normal js
timer = setTimeout(function() {
slide(c, d);
}, 5000);
}
function slide(c, d) {
if (c.split('_')[1].toInt() > 2) {
id_new = 'image_' + 0;
console.log(id_new);
}
else {
id_new = 'image_' + (c.split('_')[1].toInt() + 1);
console.log(id_new);
}
id_old = c;
slideImages(id_new, id_old);
}
i've adapted this mootools diver scroller. at the moment you have to click the buttons to move left to right. I was wondering if any one could help me put a automated scroll in?
Check with this Link...
Also refer this code...
heres the js code
var totalImages = 3;
var currentImage = 1;
function workSlide(way) {
var currentAmount=$("holder2").getStyle("margin-left");
var myFx = new Fx.Tween('holder2',{duration: 600});
if(way == "right") {
if (currentImage <= totalImages-1) {
currentImage++;
var whichAmount = -(((currentImage-1)) * 920);
myFx.start('margin-left',currentAmount,whichAmount);
}
} else {
if (currentImage > 1) {
currentImage--;
var whichAmount = -(((currentImage-1)) * 920);
myFx.start('margin-left',currentAmount,whichAmount);
}
}
}
I have built a jQuery rotator to rotate through 3 divs and loop them. I would like to add the functionality on mouse over to "freeze" the current div and then start again on mouse out.
I've thought about setting a variable to false at the start of the function and setting it true when it's on it's current frame but I've got my self a bit confused.
I've also tried to use the hover function but when using the in and out handlers, I'm confused as to how to stop, restart the animation.
function ImageRotate() {
var CurrentFeature = "#container" + featureNumber;
$(CurrentFeature).stop(false, true).delay(4500).animate({'top' : '330px'}, 3000);
var featureNumber2 = featureNumber+1;
if ( featureNumber == numberOfFeatures) {featureNumber2 = 1}
var NewFeature = "#container" + featureNumber2;
$(NewFeature).stop(false, true).delay(4500).animate({'top' : '0px'}, 3000);
var featureNumber3 = featureNumber-1;
if ( featureNumber == 1) {featureNumber3 = numberOfFeatures};
var OldFeature = "#container" + featureNumber3;
$(OldFeature).stop(false, true).delay(4500).css('top' , '-330px');
setTimeout('if (featureNumber == numberOfFeatures){featureNumber = 1} else {featureNumber++}; ImageRotate2()', 7500)};
Any help would be greatly appreciated!!
Thanks, Matt
If you were to add this code:
var timerId = null;
function startRotation() {
if (timerId) {
return;
}
timerId = setInterval('if (featureNumber == numberOfFeatures){featureNumber = 1} else {featureNumber++}; ImageRotate2()', 7500);
}
function stopRotation() {
if (!timerId) {
return;
}
clearInterval(timerId);
timerId = null;
}
and replace the last line of your code block with a simple call to startRotation();, then you could call stopRotation and startRotation when the mouse hovers over/leaves your element:
$('your-element-selector').hover(stopRotation, startRotation);
It's not clear what you are trying to do with the three divs without seeing the HTML and more code, so I think a basic example might help you better (demo).
HTML
<div class="test">image: <span></span></div>
Script
$(document).ready(function(){
var indx = 0, loop, numberOfFeatures = 5;
function imageRotate(){
indx++;
if (indx > numberOfFeatures) { indx = 1; }
$('.test span').text(indx);
loop = setTimeout( imageRotate , 1000 );
}
imageRotate();
$('.test').hover(function(){
clearTimeout(loop);
}, function(){
imageRotate();
});
})
changed things up a little bit, here is how I ended up doing it. `
var animRun = false;
var rotateHover = false;
function startRotation() {
rotateHover = false;
ImageRotate();
}
function stopRotation() {
rotateHover = true;
clearTimeout();
}
function ImageRotate() {
if (rotateHover == false){
animRun = true;
var CurrentFeature = "#container" + featureNumber;
$(CurrentFeature).stop(false, true).animate({'top' : '330px'}, featureDuration, function(){animRun = false;});
var featureNumber2 = featureNumber+1;
if ( featureNumber == numberOfFeatures) {featureNumber2 = 1}
var NewFeature = "#container" + featureNumber2;
$(NewFeature).stop(false, true).animate({'top' : '0px'}, featureDuration); /* rotate slide 2 into main frame */
var featureNumber3 = featureNumber-1;
if ( featureNumber == 1) {featureNumber3 = numberOfFeatures};
var OldFeature = "#container" + featureNumber3;
$(OldFeature).stop(false, true).css('top' , '-330px'); /*bring slide 3 to the top*/
//startRotation();
setTimeout('if (featureNumber == numberOfFeatures){featureNumber = 1} else {featureNumber++}; if (rotateHover == false){ImageRotate2()};', featureDelay);
};
};