JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://unpkg.co/gsap@3/dist/gsap.min.js"></script>
<div class="container">
<div class="row">
<div class="text-block">
123
</div>
<div class="img-block">
  <canvas id="main-canvas"></canvas>
</div>
</div>
</div>
<div id="svg-main" style="display: none">
   <svg width="296" height="271" viewBox="0 0 296 271" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M20.0659 160.803L6.99994 163.644C4.66534 164.152 3 166.218 3 168.607V197.393C3 199.782 4.66534 201.848 6.99994 202.356L20.0659 205.197C21.2021 208.675 22.6093 212.068 24.2708 215.337L17.0374 226.588C15.7456 228.599 16.0296 231.238 17.7183 232.927L38.0734 253.282C39.7621 254.972 42.4015 255.254 44.4118 253.963L55.6633 246.729C58.9317 248.391 62.3246 249.798 65.8032 250.934L68.6436 264C69.1507 266.335 71.2182 268 73.6072 268H102.393C104.782 268 106.849 266.335 107.356 264L110.197 250.934C113.675 249.798 117.068 248.391 120.337 246.729L131.588 253.963C133.599 255.254 136.238 254.97 137.927 253.282L158.282 232.927C159.97 231.238 160.254 228.599 158.963 226.588L151.729 215.337C153.391 212.068 154.798 208.675 155.934 205.197L169 202.356C171.335 201.848 173 199.782 173 197.393V168.607C173 166.218 171.335 164.152 169 163.644L155.934 160.803C154.798 157.325 153.391 153.932 151.729 150.663L158.963 139.412C160.254 137.401 159.97 134.762 158.282 133.073L137.927 112.718C136.238 111.03 133.599 110.746 131.588 112.037L120.337 119.271C117.068 117.609 113.675 116.202 110.197 115.066L107.356 102C106.849 99.6653 104.782 98 102.393 98H73.6072C71.2182 98 69.1507 99.6653 68.6436 102L65.8032 115.066C62.3246 116.202 58.9317 117.609 55.6633 119.271L44.4118 112.037C42.4015 110.746 39.7621 111.03 38.0734 112.718L17.7183 133.073C16.0296 134.762 15.7456 137.401 17.0374 139.412L24.2708 150.663C22.6093 153.932 21.2021 157.325 20.0659 160.803ZM25.1397 195.903L13.1594 193.298V172.702L25.141 170.097C26.9815 169.697 28.4484 168.312 28.9542 166.498C30.272 161.776 32.1643 157.209 34.5832...

CSS

.container{
  width:100%;
  height:100vh;
}
.row{
  display:flex;
  justify-content:space-between;
  align-items:center;
}
.text-block{
  width:35%;
}
.img-block{
  width:50%;
}
.canvas{
  width:100%;
  height:100%;
}

JavaScript

const SVG = $('#svg-main').html();

var gridCount = 20;
var circleSize = 10;
var circleDistance = 50;

const imageURL = "data:image/svg+xml;base64," + btoa(SVG);

const canvas = document.querySelector("#main-canvas");
const ctx = canvas.getContext("2d");

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

const gridStep = gridCount;
const circleRadius = circleSize;
const customDistance = circleDistance;

(async function () {
  const points = [];
  const maskImage = await loadImg(imageURL);
  if (maskImage.height === 0) throw new Error("svg mask height is 0");

  const scaleMask = Math.min(
    canvas.width / maskImage.width,
    canvas.height / maskImage.height
  );

  const maskCanvas = document.createElement("canvas");
  const maskCtx = maskCanvas.getContext("2d");
  maskCanvas.width = canvas.width;
  maskCanvas.height = canvas.height;

  maskCtx.save();
  maskCtx.translate(maskCanvas.width / 2, maskCanvas.height / 2);
  maskCtx.scale(scaleMask, scaleMask);
  maskCtx.translate(-maskImage.width / 2, -maskImage.height / 2);
  maskCtx.drawImage(maskImage, 0, 0, maskImage.width, maskImage.height);
  maskCtx.restore();

  const maskData = maskCtx.getImageData(
    0,
    0,
    maskCanvas.width,
    maskCanvas.height
  );

  for (let y = 0; y < maskData.height; y += gridStep) {
    for (let x = 0; x < maskData.width; x += gridStep) {
      const index = (y * maskData.width + x) * 4;
      const alpha = maskData.data[index + 3];

      if (alpha > 128) {
        points.push({ x, y, tx: 0, ty: 0 });
      }
    }
  }

 window.addEventListener("mousemove", (e) => {
    const mx = e.clientX;
    const my = e.clientY;

    points.forEach((p) => {
      const deltaX = Math.floor(p.x - mx) * -0.45;
      const deltaY = Math.floor(p.y - my) * -0.45;
      const distance = Math.hypot(deltaX, deltaY);

      if (distance < customDistance) {
        gsap.to(p, { ty: deltaY, tx: deltaX, duration: 0.5, });
      } else {
        gsap.to(p, { ty: 0, tx: 0,...