computer
computer

Reputation: 113

How to use setInterval to enlarge image

I want to achieve when an image is clicked then it will enlarge for a set amount of time. So far I'm up to here in my JS but it doesn't work

 var image =  document.getElementById('pic');

function enlarge() {
    image.style.height="600px";
}

image.onclick =enlarge;

After I tried to implement.

 var image =  document.getElementById('pic');

function enlarge() {
    image.style.height="600px";
}

image.onclick = setInterval(enlarge; 1000);

How should I implement this? JSFIDDLE

Upvotes: 1

Views: 1424

Answers (4)

Ori Drori
Ori Drori

Reputation: 192132

Using setInterval

We want 60fps, so each frame would be 1000 / 60 which equals about 16.667ms long. We need to enlarge the height by 500px. 500 / 60 equals to 8.334. So we need an interval of 16.667 ms, and every iteration, enlarge the image by 8.334px, and stop when the height reaches 600px:

var images = document.querySelectorAll('.pic');

images.forEach(function(image) {
  image.addEventListener('click', enlarge);
});

function enlarge(e) {
  var image = e.target;
  var interval;
  var height = 100;
  
  interval = setInterval(function() {
    height += 8.334;
    
    if(height >= 600) {
      height = 600;
      clearInterval(interval);
    }
    
    image.style.height = height + 'px';
  }, 16.667);
}
.pic {
  width: 100px;
  height: 100px;
  vertical-align: top;
}
<img src='https://placehold.it/100x100' class='pic'>
<img src='https://placehold.it/100x100' class='pic'>


Using requestAnimationFrame

A better way of doing it, will use requestAnimationFrame() that produces smoother animations. According to MDN:

The window.requestAnimationFrame() method tells the browser that you wish to perform an animation and requests that the browser call a specified function to update an animation before the next repaint.

The math stays the same, but requestAnimationFrame will handle the calling the next frame after 16.667ms.

var images = document.querySelectorAll('.pic');

images.forEach(function(image) {
  image.addEventListener('click', enlarge);
});

function enlarge(e) {
  var image = e.target;
  var interval;
  var height = 100;
  
  function enlargeInner() {
    height += 8.334;
    
    if(height >= 600) {
      height = 600;
    }
    
    image.style.height = height + 'px';
    
    height < 600 && requestAnimationFrame(enlargeInner);
  }
  
  enlargeInner();
}
.pic {
  width: 100px;
  height: 100px;
  vertical-align: top;
}
<img src='https://placehold.it/100x100' class='pic'>
<img src='https://placehold.it/100x100' class='pic'>

Upvotes: 3

Bal&#225;zs Orb&#225;n
Bal&#225;zs Orb&#225;n

Reputation: 559

setInterval() only won't work.

Basically what your code is doing, that it waits 1000 milliseconds, and runs the enlarge function.

(by the way, you have a typo, at the last line, there should be a comma between enlarge and 1000)

The way I would do it is to add a css class with an animation, and then add that class to the image on click.

let myImg = document.getElementById("img1");
myImg.addEventListener("click", () => myImg.classList.toggle("enlarge"));


/*

The code above is using ES6 (the newest version of JavaScript) and and a thing called an arrow function. If you don't get it, here is the "normal way" to do it. It will do exactly the same as the above code.

var myImg = document.getElementById("img1");
myImg.addEventListener("click", function(){
  myImg.classList.toggle("enlarge")
});


*/
#img1 {
  transition: 1s
}
.enlarge {
  width: 300px;
  height: 300px;
}
<img id="img1" src="https://foswiki.org/pub/Support/Glossary/600px-Example.svg.png" width="100px" height="100px">

Upvotes: 2

wscourge
wscourge

Reputation: 11291

You just assign same height in an interval. You need to increment it, like:

image.style.height = (+image.style.height + 600) + "px";

But I guess it is not your goal, as it will make your image grow 600px every second. I think what you are looking for is just making it bigger to actual point of size? If so, try using CSS transition combined with javascript, like:

CSS:

img {
  width: 300px;
  height: 300px;
  -webkit-transition: width 1s linear, height 1s linear;
  transition: width 1s linear, height 1s linear;
}
.enlarged {
  width: 600px;
  height: 600px;
}

JS:

document.getElementById('pic').addEventListener("click", function(e){
  this.classList.toggle("enlarged");
}

Upvotes: 2

RamblinRose
RamblinRose

Reputation: 4963

I forked your fiddle.

You need to change the way you're approaching the click event like so:

function enlarge() {
  setInterval(function() {
    // do stuff
  }, 1000)
}

image.onclick = enlarge;

Upvotes: 0

Related Questions