`createHighlightCanvas` function in react-scan source code.

Ramu NarasingaRamu Narasinga
3 min read

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;
};

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;

“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);

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);

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

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();
};

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

0
Subscribe to my newsletter

Read articles from Ramu Narasinga directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ramu Narasinga
Ramu Narasinga

I study large open-source projects and create content about their codebase architecture and best practices, sharing it through articles, videos.