0

I have a canvas draws an image onto it. I have added a fade in and out effect with a setinterval so it just keeps on going. I want to be able to stop this effect if the canvas is toggled to hide.

const canvas = document.getElementById('canvas');
  const ctx = canvas.getContext('2d');

  const image = new Image('naturalWidth', 'naturalHeight'); // Using optional size for image
  image.onload = drawImageActualSize; // Draw when image has loaded

  // Load an image of intrinsic size 300x227 in CSS pixels
  image.src = 'picture';

  function drawImageActualSize() {
    // Use the intrinsic size of image in CSS pixels for the canvas element
    canvas.width = this.naturalWidth;
    canvas.height = this.naturalHeight;

    // Will draw the image as 300x227, ignoring the custom size of 60x45
    // given in the constructor
    ctx.drawImage(this, 0, 0);
  }
  
  //FADE EFFECT
  
$(function () {
    var effect = $('#canvas');
    setInterval(function () {
            effect.fadeIn(1000, function () {
                    effect.fadeOut(1500, function () {
                            effect.fadeIn(1500)
                    });
            });
    }, 3000);
});

1 Answers1

0

So, at the top of your code, you can define an interval variable to store the interval in and allow it to be accessible anywhere:

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

const effect = $('#canvas'); // <-- you can also define `effect` here since it'll be used in both functions.
let interval = 0;
...

Since you want to hide and show the element, you can create two functions:

  1. hide(), which will run only if interval != 0, and it will: (1) stop the interval, (2) set interval to 0 so we can check if it was already stopped (so you don't run the function multiple times), and (2) stop the animation and hide the canvas.
  2. show(), which will run only if interval == 0, and it will: (1) unhide the canvas, (2) reset the interval.

Now, at the bottom of your code, where you create the interval, you can create the hide and show functions:

hide()

const hide = () => {
  if(interval) {
    clearInterval(interval);
    interval = 0;
    effect.finish().stop().hide() // finish and stop the effect, and hide the canvas
  }
}

show()

const show = () => {
  if(!interval) { // if `interval` is equal to 0
    effect.show()
    interval = setInterval(function () {
      effect.fadeIn(1000, function () {
        effect.fadeOut(1500, function () {
          effect.fadeIn(1500)
        });
      });
    }, 3000);
  }
}

...and, of course, call show() on load:

$(show);

Here's a demo:

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
let interval = 0;
const effect = $('#canvas');

const image = new Image('naturalWidth', 'naturalHeight'); // Using optional size for image
image.onload = drawImageActualSize; // Draw when image has loaded
// Load an image of intrinsic size 300x227 in CSS pixels
image.src = 'https://via.placeholder.com/100'

function drawImageActualSize() {
  // Use the intrinsic size of image in CSS pixels for the canvas element
  canvas.width = this.naturalWidth;
  canvas.height = this.naturalHeight;

  // Will draw the image as 300x227, ignoring the custom size of 60x45
  // given in the constructor
  ctx.drawImage(this, 0, 0);
}
  


const show = () => {
  if(!interval) { // if `interval` is equal to 0
    effect.show()
    interval = setInterval(function () {
      effect.fadeIn(1000, function () {
        effect.fadeOut(1500, function () {
          effect.fadeIn(1500)
        });
      });
    }, 3000);
  }
}

const hide = () => {
  if(interval) {
    clearInterval(interval);
    interval = 0;
    effect.finish().stop().hide() // finish and stop the effect, and hide the canvas
  }
}

$(show);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<canvas id="canvas"></canvas>
<br>
<button onclick="hide()" />Hide</button>
<button onclick="show()" />Show</button>
marsnebulasoup
  • 2,530
  • 2
  • 16
  • 37