0

I am trying to create a rotating fan simulation using JavaScript & Jquery. My output runs fine 1st time, but when I first stop the fan rotation to zero, and start again the counter value starts from last position of setInterval, is there any way to set it to zero, if once I have reduced the fan speed to zero or how can I use static variable(like in Java) where any operation on the variable reflects throughout program ? I tried windows.variable, .variable, but result is the same. Please help My JS and jquery code:

var angle = 0;
var movement;


$(".fan-start").click(function(){
  $(".counter").html(window.movement);
  window.movement = setInterval(fanOps,1);
});

$(".fan-stop").click(function(){

    clearInterval(window.movement);
      window.movement--;

    if(window.movement>=0)
    {
        $(".counter").html(window.movement);
    }
});

function fanOps()
{

  if(angle<360)
  {
  angle ++;
  }
  else{
    angle = 0;
  }
    $("img").css("transform","rotate("+angle+"deg)");

}

.counter is the class of the counter value. A screenshot is attached of the page..

web page screenshot

My fan operation is working absolutely fine, my issue is setting the counter value back at zero from setInterval, when I start again after bringing it to zero once.

VMi
  • 346
  • 3
  • 16
  • You should click the start button once and not multiple times . else the id returned from setInterval will change and and help in clearInterval – Harmandeep Singh Kalsi Jun 30 '20 at 11:41
  • I am already using it, my problem is not in operation, but setting the counter value when starting again from zero. – VMi Jun 30 '20 at 11:42
  • Please check what does setInterval returns. It returns the unique id which can then be used to clearInterval. You should not use it for calculating the movements. Check this https://www.bitdegree.org/learn/javascript-setinterval#:~:text=The%20setInterval()%20returns%20a,stop%20setInterval()%20from%20running. – Harmandeep Singh Kalsi Jun 30 '20 at 11:44
  • You are using what is essentially a random ID returned from `setInterval` to perform some kind of calculation. This is a bad idea. See [setInterval/setTimeout return value](https://stackoverflow.com/q/940120/215552) and [MDN's documentation](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval). Use a separate variable. – Heretic Monkey Jun 30 '20 at 11:51
  • `window.movement` is the timer, for start click it needs a clearInterval, stop looks fine but doesn't need `window.movement--;`, current speed looks like it needs hooking into the `1`ms, you should use requestanimationframe instead, add the dom and css – Lawrence Cherone Jun 30 '20 at 11:53
  • `setItnterval` return a reference, not a counter ! and you may also use a css varaible to do that. I would prefer from you to show the html part of this – Mister Jojo Jun 30 '20 at 11:53
  • Thanks...Used another variable instead of setInterval one & its working like a charm...chk it out https://vineetmishra82.github.io/rotatingFan/ – VMi Jun 30 '20 at 11:57

2 Answers2

0

You can use requestAnimationFrame, which is more performant than setInterval (It'll also look better) for this, like so:

var globalID;
var angle = 0;
var speed = 0.1;


function repeatOften() {
   if(angle<360)
    {
    angle+=speed;
    }
    else{
      angle = 0;
    }
        console.log(Math.floor(angle));
    globalID = requestAnimationFrame(repeatOften);
}

  globalID = requestAnimationFrame(repeatOften);
$("#faster").on("click", function() {
  speed+=0.1;
});

$("#stop").on("click", function() {
  cancelAnimationFrame(globalID);
});
$("#start").on("click", function() {
  globalID = requestAnimationFrame(repeatOften);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="start">start</button>
<button id="stop">stop</button>
<button id="faster">faster</button>
Kudlas
  • 659
  • 7
  • 24
  • Thanks...Used another variable instead of setInterval one & its working like a charm...chk it out vineetmishra82.github.io/rotatingFan – VMi Jun 30 '20 at 11:59
  • Looking good, maybe you should use transform-origin css property, to center rotation to the fan center. Btw. the requestAnimationFrame is more performant than setInterval (It'll also look better). – Kudlas Jun 30 '20 at 12:03
  • I tried transform-origin, no effect..any idea how to implement it ? – VMi Jun 30 '20 at 12:21
  • https://www.w3schools.com/CSSref/css3_pr_transform-origin.asp – Kudlas Jun 30 '20 at 12:41
0

you need to hold the setInterval handler and check the movement value to start and stop the fan

var angle = 0;
var movement;
var handler; // this keeps the setInterval handler

$('.fan-start').click(function () {
  // if the fan is working ,it doesn't need to be started again
  if (handler === undefined) {
    handler = setInterval(fanOps, 1);
    window.movement = 0;
  }
  window.movement++;
  $('.counter').html(window.movement);
});

$('.fan-stop').click(function () {
  if (!handler) return;
  if (window.movement > 0) {
    window.movement--;
  }
  if (window.movement === 0) {
    clearInterval(handler);
    handler = undefined;
  }
  $('.counter').html(window.movement);
});

function fanOps() {
  if (angle < 360) {
    angle += window.movement;
  } else {
    angle = 0;
  }
  $('img').css('transform', 'rotate(' + angle + 'deg)');
}
Ehsan Nazeri
  • 771
  • 1
  • 6
  • 10