DEV Community

artydev
artydev

Posted on

Rotate images - the closure way...

Sometimes you want to preserve the state of a variable, but don't want to pollute global namespace.

In the following case, I wanted to rotate an image on click event, without introducing a new variable 'current_angle' in global namespace.

Closures come to the rescue.

The value of the rotation angle is preserved between each call, and hided from globals.

Notice how we can apply a rotation on the following images without having to maintain any global state.

I also added a little animation, for better UX.

Here is the code (see the link below to test online).

// allow pausing while rotate
function sleep(ms = 0) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

// returns an object containing the closure and the refrenced image
function rotateImage (id) {
  let angle = 0;
  let prevangle = 0
  let img = document.getElementById(id);
  async function _rotateImg () {
    while (angle < prevangle + 90) {
      angle += 19;
      await sleep(0)
      img.style.transform = `rotate(${angle}deg)` ;
    }
    let rest = angle % 90;
    // we rotated to far...
    if (rest > 0) {
      while (rest > 0) {
         rest -= 1
        await sleep(0)
        img.style.transform = `rotate(${--angle}deg)` ;
      }
    }
    img.dataset.angle = angle
    prevangle = angle
    checkImages()
  }
  return { rotator: _rotateImg, image:img } ;
}

Enter fullscreen mode Exit fullscreen mode

You can test the code here : RotateWithClosure

Top comments (0)