Sexual Ecologies Survey Tool: Refactored

by jude_pinto

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/interact.js/1.10.27/interact.min.js"></script>
<div id="container">
  <div class="circle" id="circle1" style="left: 250px; top: 50px; width: 150px; height: 150px;">
    <span class="label">Circle 1</span>
    </div>
  
  <div class="circle" id="circle2" style="left: 150px; top: 200px; width: 150px; height: 150px;">
     <span class="label">Circle 2</span>
  </div>

  <div class="circle" id="circle3" style="left: 350px; top: 200px; width: 150px; height: 150px;">
     <span class="label">Circle 3</span>
  </div>
</div>
<div id="instructions">Drag and Resize Circles.</div>
<div id="overlapInfo">Drag and Resize Circles. Overlap Areas:</div>
<button id="resetBtn">Reset</button>

CSS

body {
  margin: 0;
  font-family: sans-serif;
}

#container {
  position: relative;
  width: 100%;
  height: 100vh;
  background: #f0f0f0;
  overflow: hidden;
}

.circle {
  position: absolute;
  border-radius: 50%;
  border: 2px solid #333;
  background-color: rgba(100, 149, 237, 0.4);
  touch-action: none;
  user-select: none;
    display: flex;
  justify-content: center;
  align-items: center;
}
.label {
  pointer-events: none; /* so it doesn't interfere with drag */
}
#instructions {
  position: fixed;
  top: 10px;
  left: 10px;
  background: white;
  border: 1px solid #333;
  padding: 10px;
  max-width: 250px;
  z-index: 1000;
}

#overlapInfo {
  position: fixed;
  top: 60px;
  left: 10px;
  background: white;
  border: 1px solid #333;
  padding: 10px;
  max-width: 250px;
  z-index: 1000;
}

#resetBtn {
  position: fixed;
  bottom: 10px;
  left: 10px;
  padding: 10px 20px;
  font-size: 16px;
  cursor: pointer;
  background-color: #333;
  color: white;
  border: none;
  border-radius: 4px;
  z-index: 1000;
}

JavaScript

//Sexual Ecologies Interactive Survey Tool- Refactored
//By: Jude Pinto

// This code is a refactored version of an interactive survey for Aki Gormezano's study @ van Anders Lab.
//This program has imported the library interact.js, created by Taye. 
//https://interactjs.io/



const originalStates = {};
const circles = document.querySelectorAll('.circle');
const overlapInfo = document.getElementById('overlapInfo');

// Save original states
circles.forEach(circle => {
  originalStates[circle.id] = {
    left: circle.style.left,
    top: circle.style.top,
    width: circle.style.width,
    height: circle.style.height
  };
});

// Enable dragging and resizing
circles.forEach(circle => {
  interact(circle)
    .draggable({
      listeners: {
        move(event) {
          const target = event.target;
          const x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx;
          const y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;

          target.style.transform = `translate(${x}px, ${y}px)`;
          target.setAttribute('data-x', x);
          target.setAttribute('data-y', y);
          updateOverlapInfo();
        }
      }
    })
    .resizable({
      edges: { left: true, right: true, top: true, bottom: true },
      listeners: {
        move(event) {
          const target = event.target;
          let width = parseFloat(target.style.width) || target.offsetWidth;
          let height = parseFloat(target.style.height) || target.offsetHeight;

          width += event.deltaRect.width;
          height += event.deltaRect.height;

          target.style.width = `${width}px`;
          target.style.height = `${height}px`;

          const x = (parseFloat(target.getAttribute('data-x')) || 0) + event.deltaRect.left;
          const y = (parseFloat(target.getAttribute('data-y')) || 0) + event.deltaRect.top;

          target.style.transform = `translate(${x}px, ${y}px)`;
         ...