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 } ;
}
You can test the code here : RotateWithClosure