Slider values not read when inside requestAnimationFrame event

I’m working on a visual for Black History Month and don’t know why the sliders are not changing the way that openCV canny is working. I have tried referencing them directly. The two sliders are called T1 and T2.

The change only happens if I pause and re-start the video, which causes the requestAnimationFrame() to be canceled via cancelAnimationFrame() and restarted.

function tick() {
  vid.cap.read(vid.src)

  cv.cvtColor(vid.src, vid.gry, cv.COLOR_RGBA2GRAY, cv.CV_8UC1)
  cv.Canny(vid.gry, vid.gry, T1, T2, 3);

  cv.imshow('canvasOutput', vid.gry);

  vid.event = requestAnimationFrame(tick);
};

Update: I have added an invalidation promise to the play function, that stops the tick() animation loop when a slider is changed, but I can’t use the invalidation promise to restart the play() function.

function play () {
  if (vid.event != null) { 
    cancelAnimationFrame(vid.event)
    vid.event = null
  }

  vid.streaming = true;
  vid.stopped = false;
  
  const width = video.width;
  const height = video.height;
  
  vid.src = new cv.Mat(height, width, cv.CV_8UC4);
  vid.dst = new cv.Mat(height, width, cv.CV_8UC1);
  vid.gry = new cv.Mat(height, width, cv.CV_8UC1);
  vid.cap = new cv.VideoCapture(video);
  
  tick();  // start requestAnimationFrame event

  invalidation.then(() => {  
    cancelAnimationFrame(vid.event);
    vid.event = null
    vid.streaming = false
    vid.stopped = true
    // play()   // doesn't work
  }) // .then(play())  // doesn't work too
}

Here’s my take on how to do this in an idiomatic, dataflow-centric way:

The key parts are:

  1. Setup a video element and a canvas.
  2. Use an async generator to listen for when the video time changes.
  3. When the video time changes, apply the Canny edge detector.

And that’s it. This way, regardless of how the displayed video frame changes (whether the user is moving the playhead, or whether they’ve clicked play or pause, or the video is autolooping), and likewise regardless of how the thresholds tmin and tmax are defined, anything that affects the Canny edge detection will automatically trigger the Canny edge detection to run again. This approach hopefully minimizes the amount of coordination, event listeners, invalidation, imperative side effects, etc.

3 Likes

Thanks @mbostock that really helped a lot and the use of the Generator was very educational.