I’m currently working on a project where I aim to programmatically draw lines on an HTML canvas underlying my webpage content. My objective is to achieve a result similar to the attached screenshot. Here’s what I’ve implemented so far:

let container = document.querySelector(".container");
let canvas = document.querySelector("canvas");

canvas.width = container.offsetWidth;
canvas.height = container.offsetHeight;

let ctx = canvas.getContext("2d");

let photo = document.querySelector(".photo");
let levels = document.querySelectorAll(".levels div");
let colors = getComputedStyle(document.documentElement);

levels.forEach((level, index) => {
  index++;
  ctx.beginPath();
  ctx.strokeStyle = colors.getPropertyValue(`--level-${index}`);
  ctx.moveTo(photo.offsetWidth + index * 10, photo.offsetTop + level.offsetTop - level.offsetHeight / 2);
  ctx.lineTo(photo.offsetWidth, photo.offsetTop + level.offsetTop - level.offsetHeight / 2);
  ctx.stroke();
});

let person = document.querySelector(".person");
let boxes = document.querySelectorAll(".box");
let total = boxes.length;
boxes.forEach((box, index) => {
  let dot = box.querySelector(".dot");
  index++;
  ctx.beginPath();
  ctx.strokeStyle = colors.getPropertyValue(`--level-${index}`);
  ctx.moveTo(person.offsetWidth + dot.offsetLeft + dot.offsetWidth, box.offsetTop - dot.offsetTop + dot.offsetHeight);
  ctx.lineTo(
    person.offsetWidth + dot.offsetLeft + dot.offsetWidth / 2 - total * 10,
    box.offsetTop - dot.offsetTop + dot.offsetHeight
  );
  ctx.stroke();
  total--;
});
:root {
  --level-1: #39a3aa;
  --level-2: #32a993;
  --level-3: #5cb793;
  --level-4: #dbb00c;
  --level-5: #d8750e;
  --level-6: #d4181c;
  --level-7: #b1111d;
}
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
body {
  font-family: "Roboto", sans-serif;
  font-weight: 400;
  font-style: normal;
  color: rgba(0, 0, 0, 0.87);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
.container {
  width: 1080px;
  height: 100%;
  margin: 0 auto;
  padding: 40px 0;
  display: flex;
  position: relative;
}
.person {
  flex-basis: 42%;
  display: flex;
  align-items: center;
}
.person .photo {
  width: 280px;
  height: 280px;
  position: relative;
}
.person .photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.person .photo .levels {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  position: absolute;
  top: 0;
}
.person .photo .levels [class^="level"] {
  flex: 1;
  opacity: 0.8;
}
.questions {
  flex-basis: 58%;
}
.questions .box {
  border: 1px solid;
  padding: 15px 10px;
  position: relative;
  margin-bottom: 24px;
}
.questions .box .dot {
  width: 10px;
  height: 10px;
  border-radius: 100%;
  position: absolute;
  top: 22px;
  left: -24px;
}
.questions .box .arrow {
  border-style: solid;
  border-width: 0 1px 1px 0;
  transform: rotate(45deg);
  padding: 12px;
  position: absolute;
  left: calc(50% - 6px);
  top: calc(100% - 12px);
  background-color: #fff;
}
.questions .box .question {
  margin-bottom: 5px;
}
.questions .box .question span {
  font-weight: 600;
}
.questions .box .answer input {
  padding: 6px 0;
  border: 0;
  outline: 0;
  width: 100%;
  font-family: inherit;
  font-size: inherit;
  position: relative;
  z-index: 1;
  color: inherit;
}
.questions .box .answer input::placeholder {
  color: #acacac;
}
canvas {
  position: absolute;
  z-index: -1;
}
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,400;0,600;&display=swap" rel="stylesheet" />

<div id="app">
  <div class="container">
    <div class="person">
      <div class="photo">
        <img src="headshot.jpeg" alt="" />
        <div class="levels">
          <div class="level-1" style="background-color: var(--level-1)"></div>
          <div class="level-2" style="background-color: var(--level-2)"></div>
          <div class="level-3" style="background-color: var(--level-3)"></div>
          <div class="level-4" style="background-color: var(--level-4)"></div>
          <div class="level-5" style="background-color: var(--level-5)"></div>
          <div class="level-6" style="background-color: var(--level-6)"></div>
          <div class="level-7" style="background-color: var(--level-7)"></div>
        </div>
      </div>
    </div>
    <div class="questions">
      <div class="box question-1" style="border-color: var(--level-1)">
        <div class="dot" style="background-color: var(--level-1)"></div>
        <p class="question">
          <span style="color: var(--level-1)">Level 1: </span>Lorem ipsum dolor sit amet, consectetur adipiscing elit?
        </p>
        <div class="answer">
          <input type="text" placeholder="Type your answer here and press Enter." />
        </div>
        <div class="arrow" style="border-color: var(--level-1)"></div>
      </div>

      <div class="box question-2" style="border-color: var(--level-2)">
        <div class="dot" style="background-color: var(--level-2)"></div>
        <p class="question">
          <span style="color: var(--level-2)">Level 2: </span>Lorem ipsum dolor sit amet, consectetur adipiscing elit?
        </p>
        <div class="answer">
          <input type="text" placeholder="Type your answer here and press Enter." />
        </div>
        <div class="arrow" style="border-color: var(--level-2)"></div>
      </div>

      <div class="box question-3" style="border-color: var(--level-3)">
        <div class="dot" style="background-color: var(--level-3)"></div>
        <p class="question">
          <span style="color: var(--level-3)">Level 3: </span>Lorem ipsum dolor sit amet, consectetur adipiscing elit?
        </p>
        <div class="answer">
          <input type="text" placeholder="Type your answer here and press Enter." />
        </div>
        <div class="arrow" style="border-color: var(--level-3)"></div>
      </div>

      <div class="box question-4" style="border-color: var(--level-4)">
        <div class="dot" style="background-color: var(--level-4)"></div>
        <p class="question">
          <span style="color: var(--level-4)">Level 4: </span>Lorem ipsum dolor sit amet, consectetur adipiscing elit?
        </p>
        <div class="answer">
          <input type="text" placeholder="Type your answer here and press Enter." />
        </div>
        <div class="arrow" style="border-color: var(--level-4)"></div>
      </div>

      <div class="box question-5" style="border-color: var(--level-5)">
        <div class="dot" style="background-color: var(--level-5)"></div>
        <p class="question">
          <span style="color: var(--level-5)">Level 5: </span>Lorem ipsum dolor sit amet, consectetur adipiscing elit?
        </p>
        <div class="answer">
          <input type="text" placeholder="Type your answer here and press Enter." />
        </div>
        <div class="arrow" style="border-color: var(--level-5)"></div>
      </div>

      <div class="box question-6" style="border-color: var(--level-6)">
        <div class="dot" style="background-color: var(--level-6)"></div>
        <p class="question">
          <span style="color: var(--level-6)">Level 6: </span>Lorem ipsum dolor sit amet, consectetur adipiscing elit?
        </p>
        <div class="answer">
          <input type="text" placeholder="Type your answer here and press Enter." />
        </div>
        <div class="arrow" style="border-color: var(--level-6)"></div>
      </div>

      <div class="box question-7" style="border-color: var(--level-7)">
        <div class="dot" style="background-color: var(--level-7)"></div>
        <p class="question">
          <span style="color: var(--level-7)">Level 7: </span>Lorem ipsum dolor sit amet, consectetur adipiscing elit?
        </p>
        <div class="answer">
          <input type="text" placeholder="Type your answer here and press Enter." />
        </div>
        <div class="arrow" style="border-color: var(--level-7)"></div>
      </div>
    </div>
    <canvas></canvas>
  </div>
</div>

However, I’m encountering challenges in making the lines appear as desired. I’m seeking advice on how to improve my code to achieve the intended outcome effectively. Additionally, I’m open to alternative suggestions if there’s a better approach than placing an HTML5 canvas beneath the webpage content.

Any insights or guidance would be greatly appreciated. Thank you!

desired outcome