this code work ok can you optimize and make it better <template>
  <div>
    <input type="file" accept="image/*" @change="loadImage" />
    <canvas ref="canvas" @mousedown="handleMouseDown" @mousemove="handleMouseMove" @mouseup="handleMouseUp" @wheel="handleWheel"></canvas>
    <div v-if="rectangles.length">
      <h3>Rectangles:</h3>
      <ul>
        <li v-for="(rect, index) in rectangles" :key="index">
          Rectangle {{ index + 1 }}:
          (x: {{ rect.x.toFixed(2) }}, y: {{ rect.y.toFixed(2) }},
          width: {{ rect.width.toFixed(2) }}, height: {{ rect.height.toFixed(2) }})
          <button @click="deleteRectangle(index)">Delete</button>
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      image: null,
      isDrawing: false,
      isDragging: false,
      isResizing: false,
      startX: 0,
      startY: 0,
      currentX: 0,
      currentY: 0,
      activeRectIndex: null,
      rectangles: [],
      activeHandle: null,
      handleSize: 8, // size of the resize handles
      scale: 1, // Initial scale factor for zoom functionality
      minScale: 0.5, // Minimum scale limit for zooming out
      maxScale: 3 // Maximum scale limit for zooming in
    };
  },
  methods: {
    loadImage(event) {
      const file = event.target.files[0];
      if (!file) return;

      const reader = new FileReader();
      reader.onload = (e) => this.createImage(e.target.result);
      reader.readAsDataURL(file);
    },
    createImage(src) {
      const img = new Image();
      img.onload = () => {
        this.image = img;
        this.setupCanvas();
      };
      img.src = src;
    },
    setupCanvas() {
      const canvas = this.$refs.canvas;
      canvas.width = this.image.width * this.scale;
      canvas.height = this.image.height * this.scale;
      this.drawImage();
    },
    drawImage() {
      const canvas = this.$refs.canvas;
      const ctx = canvas.getContext('2d');
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.drawImage(this.image, 0, 0, canvas.width, canvas.height);
      this.drawRectangles();
    },
    drawRectangles() {
      const ctx = this.$refs.canvas.getContext('2d');
      ctx.strokeStyle = 'red';
      ctx.lineWidth = 2 / this.scale; // Adjust line width based on scale
      this.rectangles.forEach((rect, index) => {
        const rectX = rect.x * this.$refs.canvas.width;
        const rectY = rect.y * this.$refs.canvas.height;
        const rectWidth = rect.width * this.$refs.canvas.width;
        const rectHeight = rect.height * this.$refs.canvas.height;
        ctx.strokeRect(rectX, rectY, rectWidth, rectHeight);
        if (index === this.activeRectIndex) {
          this.drawHandles(ctx, rectX, rectY, rectWidth, rectHeight);
        }
      });
    },
    drawHandles(ctx, x, y, width, height) {
      const halfSize = (this.handleSize / 2) / this.scale; // Adjust handle size
      const positions = [
        { x: x - halfSize, y: y - halfSize }, // top-left
        { x: x + width - halfSize, y: y - halfSize }, // top-right
        { x: x - halfSize, y: y + height - halfSize }, // bottom-left
        { x: x + width - halfSize, y: y + height - halfSize }, // bottom-right
        { x: x + width / 2 - halfSize, y: y - halfSize }, // top-middle
        { x: x + width / 2 - halfSize, y: y + height - halfSize }, // bottom-middle
        { x: x - halfSize, y: y + height / 2 - halfSize }, // middle-left
        { x: x + width - halfSize, y: y + height / 2 - halfSize } // middle-right
      ];

      ctx.fillStyle = 'blue';
      positions.forEach(pos => {
        ctx.fillRect(pos.x, pos.y, this.handleSize / this.scale, this.handleSize / this.scale); // Scale handle size
      });
    },
    handleWheel(event) {
      event.preventDefault();
      const zoomFactor = 1.1; // Adjust zoom sensitivity
      if (event.deltaY < 0) {
        this.scale = Math.min(this.scale * zoomFactor, this.maxScale);
      } else {
        this.scale = Math.max(this.scale / zoomFactor, this.minScale);
      }
      this.setupCanvas();
    },
    handleMouseDown(event) {
      const rect = this.$refs.canvas.getBoundingClientRect();
      const mouseX = (event.clientX - rect.left) * (this.$refs.canvas.width / rect.width);
      const mouseY = (event.clientY - rect.top) * (this.$refs.canvas.height / rect.height);

      this.activeRectIndex = this.hitTest(mouseX, mouseY);

      if (this.activeRectIndex !== null) {
        const handleHit = this.hitTestHandles(mouseX, mouseY);
        if (handleHit) {
          this.isResizing = true;
          this.activeHandle = handleHit;
          this.startX = mouseX;
          this.startY = mouseY;
        } else {
          this.isDragging = true;
          this.startX = mouseX;
          this.startY = mouseY;
        }
      } else {
        this.isDrawing = true;
        this.startX = mouseX;
        this.startY = mouseY;
      }
    },
    handleMouseMove(event) {
      if (!(this.isDrawing || this.isDragging || this.isResizing)) return;

      const rect = this.$refs.canvas.getBoundingClientRect();
      this.currentX = (event.clientX - rect.left) * (this.$refs.canvas.width / rect.width);
      this.currentY = (event.clientY - rect.top) * (this.$refs.canvas.height / rect.height);

      if (this.isResizing && this.activeRectIndex !== null) {
        this.resizeRectangle();
      } else if (this.isDragging && this.activeRectIndex !== null) {
        this.moveRectangle();
      }

      this.drawImage();

      if (this.isDrawing) {
        const ctx = this.$refs.canvas.getContext('2d');
        ctx.strokeStyle = 'red';
        ctx.lineWidth = 2 / this.scale;
        const x = Math.min(this.startX, this.currentX);
        const y = Math.min(this.startY, this.currentY);
        const width = Math.abs(this.currentX - this.startX);
        const height = Math.abs(this.currentY - this.startY);
        ctx.strokeRect(x, y, width, height);
      }
    },
    handleMouseUp() {
      if (this.isDrawing) {
        const canvas = this.$refs.canvas;
        const width = canvas.width;
        const height = canvas.height;

        const x = Math.min(this.startX, this.currentX) / width;
        const y = Math.min(this.startY, this.currentY) / height;
        const rectWidth = Math.abs(this.currentX - this.startX) / width;
        const rectHeight = Math.abs(this.currentY - this.startY) / height;

        this.rectangles.push({ x, y, width: rectWidth, height: rectHeight });
        this.isDrawing = false;
      }

      if (this.isDragging) {
        this.isDragging = false;
      }

      if (this.isResizing) {
        this.isResizing = false;
        this.activeHandle = null;
      }
    },
    hitTest(x, y) {
      for (let i = 0; i < this.rectangles.length; i++) {
        const rect = this.rectangles[i];
        const canvas = this.$refs.canvas;

        const rectX = rect.x * canvas.width;
        const rectY = rect.y * canvas.height;
        const rectWidth = rect.width * canvas.width;
        const rectHeight = rect.height * canvas.height;

        if (x > rectX && x < rectX + rectWidth && y > rectY && y < rectY + rectHeight) {
          return i;
        }
      }
      return null;
    },
    hitTestHandles(x, y) {
      const rect = this.rectangles[this.activeRectIndex];
      const canvas = this.$refs.canvas;

      const rectX = rect.x * canvas.width;
      const rectY = rect.y * canvas.height;
      const rectWidth = rect.width * canvas.width;
      const rectHeight = rect.height * canvas.height;

      const halfSize = this.handleSize / 2;
      const positions = [
        { x: rectX - halfSize, y: rectY - halfSize, handle: 'top-left' },
        { x: rectX + rectWidth - halfSize, y: rectY - halfSize, handle: 'top-right' },
        { x: rectX - halfSize, y: rectY + rectHeight - halfSize, handle: 'bottom-left' },
        { x: rectX + rectWidth - halfSize, y: rectY + rectHeight - halfSize, handle: 'bottom-right' },
        { x: rectX + rectWidth / 2 - halfSize, y: rectY - halfSize, handle: 'top-middle' },
        { x: rectX + rectWidth / 2 - halfSize, y: rectY + rectHeight - halfSize, handle: 'bottom-middle' },
        { x: rectX - halfSize, y: rectY + rectHeight / 2 - halfSize, handle: 'middle-left' },
        { x: rectX + rectWidth - halfSize, y: rectY + rectHeight / 2 - halfSize, handle: 'middle-right' }
      ];

      for (let i = 0; i < positions.length; i++) {
        const pos = positions[i];
        if (x > pos.x && x < pos.x + this.handleSize && y > pos.y && y < pos.y + this.handleSize) {
          return pos.handle;
        }
      }
      return null;
    },
    resizeRectangle() {
      const rect = this.rectangles[this.activeRectIndex];
      const canvas = this.$refs.canvas;

      const deltaX = (this.currentX - this.startX) / canvas.width;
      const deltaY = (this.currentY - this.startY) / canvas.height;

      if (this.activeHandle.includes('left')) {
        rect.x += deltaX;
        rect.width -= deltaX;
      }
      if (this.activeHandle.includes('right')) {
        rect.width += deltaX;
      }
      if (this.activeHandle.includes('top')) {
        rect.y += deltaY;
        rect.height -= deltaY;
      }
      if (this.activeHandle.includes('bottom')) {
        rect.height += deltaY;
      }

      this.startX = this.currentX;
      this.startY = this.currentY;
    },
    moveRectangle() {
      const rect = this.rectangles[this.activeRectIndex];
      const canvas = this.$refs.canvas;

      const offsetX = this.currentX - this.startX;
      const offsetY = this.currentY - this.startY;

      rect.x += offsetX / canvas.width;
      rect.y += offsetY / canvas.height;

      this.startX = this.currentX;
      this.startY = this.currentY;
    },
    deleteRectangle(index) {
      this.rectangles.splice(index, 1);
      this.drawImage();
    }
  }
};
</script>

<style>
canvas {
  border: 1px solid black;
  max-width: 100%;
  height: auto;
  cursor: default;
}
</style>