DEV Community

Ramu Narasinga
Ramu Narasinga

Posted on

`createHighlightCanvas` function in react-scan source code.

In this article, we will review the below code snippet from react-scan source code.

export const createHighlightCanvas = (root: HTMLElement) => {
  highlightCanvas = document.createElement('canvas');
  highlightCtx = highlightCanvas.getContext('2d', { alpha: true });
  if (!highlightCtx) return null;

  const dpr = window.devicePixelRatio || 1;
  const { innerWidth, innerHeight } = window;

  highlightCanvas.style.width = `${innerWidth}px`;
  highlightCanvas.style.height = `${innerHeight}px`;
  highlightCanvas.width = innerWidth * dpr;
  highlightCanvas.height = innerHeight * dpr;
  highlightCanvas.style.position = 'fixed';
  highlightCanvas.style.left = '0';
  highlightCanvas.style.top = '0';
  highlightCanvas.style.pointerEvents = 'none';
  highlightCanvas.style.zIndex = '2147483600';

  highlightCtx.scale(dpr, dpr);

  root.appendChild(highlightCanvas);

  if (handleResizeListener) {
    window.removeEventListener('resize', handleResizeListener);
  }

  const handleResize = () => {
    ...
  };
  handleResizeListener = handleResize;

  window.addEventListener('resize', handleResize);

  HighlightStore.subscribe(() => {
    requestAnimationFrame(() => {
      drawHighlights();
    });
  });

  return cleanup;
};
Enter fullscreen mode Exit fullscreen mode

That’s actually a lot of things happening in there, we will go over the code in chunks to get an overview of what it does.

highlightCanvas = document.createElement('canvas');
highlightCtx = highlightCanvas.getContext('2d', { alpha: true });
if (!highlightCtx) return null;
Enter fullscreen mode Exit fullscreen mode

“canvas” element is created and context is assigned to a variable named highlightCtx.

const dpr = window.devicePixelRatio || 1;
const { innerWidth, innerHeight } = window;

highlightCanvas.style.width = `${innerWidth}px`;
highlightCanvas.style.height = `${innerHeight}px`;
highlightCanvas.width = innerWidth * dpr;
highlightCanvas.height = innerHeight * dpr;
highlightCanvas.style.position = 'fixed';
highlightCanvas.style.left = '0';
highlightCanvas.style.top = '0';
highlightCanvas.style.pointerEvents = 'none';
highlightCanvas.style.zIndex = '2147483600';
highlightCtx.scale(dpr, dpr);
root.appendChild(highlightCanvas);
Enter fullscreen mode Exit fullscreen mode

The devicePixelRatio of Window interface returns the ratio of the resolution in physical pixels to the resolution in CSS pixels for the current display device. Read more about devicePixelRatio. Style is updated here and appended to the rootContainer

 

if (handleResizeListener) {
  window.removeEventListener('resize', handleResizeListener);
}

const handleResize = () => {
};
handleResizeListener = handleResize;

window.addEventListener('resize', handleResize);
Enter fullscreen mode Exit fullscreen mode

If there is one thing that I noticed, it is the cleanup involved across the react-scan codebase to avoid memory leaks.

Image description

This is what you will see in the above code snippet, if the resize listener is already registered, it is first removed and then added. This is done so to avoid adding the duplicate resize listeners.

handleResize function

const handleResize = () => {
  if (!highlightCanvas || !highlightCtx) return;
  const dpr = window.devicePixelRatio || 1;
  const { innerWidth, innerHeight } = window;

  highlightCanvas.style.width = `${innerWidth}px`;
  highlightCanvas.style.height = `${innerHeight}px`;
  highlightCanvas.width = innerWidth * dpr;
  highlightCanvas.height = innerHeight * dpr;
  highlightCtx.scale(dpr, dpr);

  drawHighlights();
};
Enter fullscreen mode Exit fullscreen mode

drawHighlights function is called and the canvas style is updated.

You can find the drawHighlights function in outline-overlay.ts

About me:

Hey, my name is Ramu Narasinga. I study large open-source projects and create content about their codebase architecture and best practices, sharing it through articles, videos.

I am open to work on interesting projects. Send me an email at ramu.narasinga@gmail.com

My Github —  https://github.com/ramu-narasinga

My website —  https://ramunarasinga.com

My Youtube channel —  https://www.youtube.com/@thinkthroo

Learning platform —  https://thinkthroo.com

Codebase Architecture —  https://app.thinkthroo.com/architecture

Best practices —  https://app.thinkthroo.com/best-practices

Production-grade projects —  https://app.thinkthroo.com/production-grade-projects

References:

  1. https://github.com/aidenybai/react-scan/blob/main/packages/scan/src/core/notifications/outline-overlay.ts#L156

  2. https://github.com/aidenybai/react-scan/blob/main/packages/scan/src/core/index.ts#L560

  3. https://github.com/aidenybai/react-scan/blob/main/packages/scan/src/core/index.ts#L541

  4. https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio

  5. https://github.com/aidenybai/react-scan/blob/main/packages/scan/src/core/notifications/outline-overlay.ts#L52

Top comments (0)