i want load multi image and show them in list this is my code "<template>
  <v-app>
    <v-container>
      <v-row justify="center">
        <v-col cols="2">
          <v-list>
            <v-subheader>Labels</v-subheader>
            <v-list-item v-for="(label, index) in labels" :key="label.name" @click="selectLabel(label)" :class="{ 'active-label': selectedLabel === label.name }" style="cursor: pointer;">
              <v-list-item-content>
                <v-list-item-title>{{ index + 1 }}. {{ label.name }}</v-list-item-title>
              </v-list-item-content>
              <v-list-item-action>
                <v-icon :style="{ color: label.color }">mdi-circle</v-icon>
              </v-list-item-action>
            </v-list-item>
          </v-list>
        </v-col>

        <v-col cols="10">
          <v-row>
            <v-col cols="12" md="8">
              <v-file-input label="Upload an Image" accept="image/*" @change="onImageUpload"
                prepend-icon="mdi-upload"></v-file-input>
              <v-btn color="primary" text="Print" @click="console.log(rectangles)"></v-btn>
            </v-col>
          </v-row>
          <v-row>
            <v-col cols="8">
              <v-card class="my-4">
                <v-card-text>
                  <canvas ref="canvas" :width="canvasWidth" :height="canvasHeight" @wheel.prevent="onMouseWheel"
                    @mousedown="onMouseDown" @mouseup="onMouseUp" @mousemove="onMouseMove"
                    style="border: 1px solid black;"></canvas>
                </v-card-text>
              </v-card>
            </v-col>
            <v-col cols="4">
              <v-btn v-if="rectangles.length" @click="redrawNormalizedRectangles" color="primary" class="mb-2">
                Redraw Normalized Rectangles
              </v-btn>
              <v-btn v-if="selectedRectangle" @click="copyRectangle" color="secondary" class="mb-2">
                Copy Selected
              </v-btn>
              <v-btn v-if="copiedRectangle" @click="pasteRectangle" color="success" class="mb-2">
                Paste
              </v-btn>
              <v-list v-if="rectangles.length">
                <v-subheader>Rectangles</v-subheader>
                <v-list-item v-for="(rect, index) in rectangles" :key="index" @click="selectRectangle(index)"
                  :class="{ active: rect === selectedRectangle }" style="cursor: pointer;">
                  <v-list-item-content>
                    <v-list-item-title>Rect {{ index + 1 }}: {{ rect.label }}</v-list-item-title>
                    <v-list-item-subtitle>
                      [x: {{ rect.x.toFixed(2) }}, y: {{ rect.y.toFixed(2) }}, w: {{ rect.width.toFixed(2) }}, h:
                      {{ rect.height.toFixed(2) }}]
                    </v-list-item-subtitle>
                  </v-list-item-content>
                  <v-list-item-action>
                    <v-btn icon @click.stop="removeRectangle(index)">
                      <v-icon>mdi-delete</v-icon>
                    </v-btn>
                  </v-list-item-action>
                </v-list-item>
              </v-list>
            </v-col>
          </v-row>
        </v-col>
      </v-row>
    </v-container>
  </v-app>
</template>

<script>
export default {
  data() {
    return {
      canvasWidth: 800,
      canvasHeight: 600,
      image: null,
      context: null,
      scale: 1,
      minScale: 0.1,
      maxScale: 12,
      scaleStep: 0.1,
      originX: 0,
      originY: 0,
      rectangles: [],
      labels: [
        { id: 0, name: "Person", color: "blue", key: "Digit1" },
        { id: 1, name: "Car", color: "green", key: "Digit2" },
        { id: 2, name: "Dog", color: "orange", key: "Digit3" }
      ],
      selectedLabel: "Person",
      selectedRectangle: null,
      copiedRectangle: null,
      drawStartX: 0,
      drawStartY: 0,
      drawing: false,
      isDraggingImage: false,
      isDraggingRectangle: false,
      isResizing: false,
      selectedResizeHandle: null,
      resizeHandleSize: 8,
      lastMouseX: 0,
      lastMouseY: 0,
    };
  },
  mounted() {
    this.context = this.$refs.canvas.getContext('2d');
    window.addEventListener('keydown', this.handleKeyDown);
  },
  beforeDestroy() {
    window.removeEventListener('keydown', this.handleKeyDown);
  },
  methods: {
    handleKeyDown(event) {
      if (event.ctrlKey && event.code === 'KeyC') {
        this.copyRectangle();
      }
      if (event.ctrlKey && event.code === 'KeyV') {
        this.pasteRectangle();
      }

      // Check if a label key is pressed
      const label = this.labels.find((label) => label.key === event.code);
      if (label) {
        this.selectLabel(label);
      }
    },
    onImageUpload(event) {
      const file = event.target.files[0];
      if (file) {
        const reader = new FileReader();
        reader.onload = (e) => {
          this.loadImage(e.target.result);
        };
        reader.readAsDataURL(file);
      }
    },
    loadImage(src) {
      this.image = new Image();
      this.image.onload = () => {
        const widthScale = this.canvasWidth / this.image.width;
        const heightScale = this.canvasHeight / this.image.height;
        this.scale = Math.min(widthScale, heightScale);

        const width = this.image.width * this.scale;
        const height = this.image.height * this.scale;
        this.originX = (this.canvasWidth - width) / 2;
        this.originY = (this.canvasHeight - height) / 2;

        this.draw();
      };
      this.image.src = src;
    },
    draw() {
      if (!this.image) return;

      this.context.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
      const width = this.image.width * this.scale;
      const height = this.image.height * this.scale;
      this.context.drawImage(this.image, this.originX, this.originY, width, height);

      this.redrawRectangles();

      if (this.drawing) {
        this.context.strokeStyle = 'green';
        const drawWidth = this.currentMouseX - this.drawStartX;
        const drawHeight = this.currentMouseY - this.drawStartY;
        this.context.strokeRect(this.drawStartX, this.drawStartY, drawWidth, drawHeight);
      }
    },
    redrawRectangles() {
      const width = this.image.width * this.scale;
      const height = this.image.height * this.scale;

      this.rectangles.forEach((rect) => {
        const rectX = this.originX + rect.x * width;
        const rectY = this.originY + rect.y * height;
        const rectW = rect.width * width;
        const rectH = rect.height * height;

        this.context.strokeStyle = rect.color;
        this.context.strokeRect(rectX, rectY, rectW, rectH);

        if (rect === this.selectedRectangle) {
          this.context.fillStyle = 'red';
          this.drawResizeHandles(rectX, rectY, rectW, rectH);
        }
      });
    },
    drawResizeHandles(rectX, rectY, rectW, rectH) {
      const handleSize = this.resizeHandleSize;
      const halfSize = handleSize / 2;
      this.context.fillRect(rectX - halfSize, rectY - halfSize, handleSize, handleSize); // Top-left
      this.context.fillRect(rectX + rectW - halfSize, rectY - halfSize, handleSize, handleSize); // Top-right
      this.context.fillRect(rectX - halfSize, rectY + rectH - halfSize, handleSize, handleSize); // Bottom-left
      this.context.fillRect(rectX + rectW - halfSize, rectY + rectH - halfSize, handleSize, handleSize); // Bottom-right
    },
    onMouseWheel(event) {
      const { offsetX, offsetY } = event;
      const oldScale = this.scale;
      const newScale = event.deltaY > 0
        ? Math.max(this.scale - this.scaleStep, this.minScale)
        : Math.min(this.scale + this.scaleStep, this.maxScale);

      if (newScale !== oldScale) {
        const scaleRatio = newScale / oldScale;
        this.originX = offsetX - (offsetX - this.originX) * scaleRatio;
        this.originY = offsetY - (offsetY - this.originY) * scaleRatio;
        this.scale = newScale;
        this.draw();
      }
    },
    onMouseDown(event) {
      const mouseX = event.offsetX;
      const mouseY = event.offsetY;

      if (event.button === 1) { // Middle mouse button for dragging
        this.isDraggingImage = true;
        this.lastMouseX = mouseX;
        this.lastMouseY = mouseY;
      }
      else if (event.button === 0) { // Left mouse button for actions
        this.selectedResizeHandle = this.getResizeHandle(mouseX, mouseY);
        if (this.selectedResizeHandle) {
          this.isResizing = true;
          this.lastMouseX = mouseX;
          this.lastMouseY = mouseY;
          return;
        }

        this.selectedRectangle = this.rectangles.find(rect =>
          mouseX >= this.originX + rect.x * this.image.width * this.scale &&
          mouseX <= this.originX + (rect.x + rect.width) * this.image.width * this.scale &&
          mouseY >= this.originY + rect.y * this.image.height * this.scale &&
          mouseY <= this.originY + (rect.y + rect.height) * this.image.height * this.scale
        );

        if (this.selectedRectangle) {
          this.isDraggingRectangle = true;
          this.lastMouseX = mouseX;
          this.lastMouseY = mouseY;
        } else {
          this.drawing = true;
          this.drawStartX = mouseX;
          this.drawStartY = mouseY;
          this.currentMouseX = mouseX;
          this.currentMouseY = mouseY;
        }
      }
      this.draw();
    },
    onMouseMove(event) {
      this.currentMouseX = event.offsetX;
      this.currentMouseY = event.offsetY;

      if (this.isDraggingImage) {
        const deltaX = this.currentMouseX - this.lastMouseX;
        const deltaY = this.currentMouseY - this.lastMouseY;
        this.originX += deltaX;
        this.originY += deltaY;
        this.lastMouseX = this.currentMouseX;
        this.lastMouseY = this.currentMouseY;
        this.draw();
      } else if (this.isDraggingRectangle && this.selectedRectangle) {
        const deltaX = (this.currentMouseX - this.lastMouseX) / (this.image.width * this.scale);
        const deltaY = (this.currentMouseY - this.lastMouseY) / (this.image.height * this.scale);
        this.selectedRectangle.x += deltaX;
        this.selectedRectangle.y += deltaY;
        this.lastMouseX = this.currentMouseX;
        this.lastMouseY = this.currentMouseY;
        this.draw();
      } else if (this.isResizing && this.selectedRectangle) {
        const deltaX = this.currentMouseX - this.lastMouseX;
        const deltaY = this.currentMouseY - this.lastMouseY;
        this.resizeRectangle(deltaX, deltaY);
        this.lastMouseX = this.currentMouseX;
        this.lastMouseY = this.currentMouseY;
        this.draw();
      } else if (this.drawing) {
        this.draw();
      }
    },
    onMouseUp(event) {
      if (event.button === 1) {
        this.isDraggingImage = false;
      }
      if (event.button === 0) {
        if (this.drawing) {
          const mouseX = this.currentMouseX;
          const mouseY = this.currentMouseY;

          if (Math.abs(mouseX - this.drawStartX) > 0 && Math.abs(mouseY - this.drawStartY) > 0) {
            this.addRectangle(mouseX, mouseY);
          }
          this.drawing = false;
        }
        this.isDraggingRectangle = false;
        this.isResizing = false;
        this.selectedResizeHandle = null;
        this.draw();
      }
    },
    addRectangle(mouseX, mouseY) {
      const selectedLabelInfo = this.labels.find(
        (label) => label.name === this.selectedLabel
      );

      const rect = {
        x: (Math.min(this.drawStartX, mouseX) - this.originX) / (this.image.width * this.scale),
        y: (Math.min(this.drawStartY, mouseY) - this.originY) / (this.image.height * this.scale),
        width: Math.abs(mouseX - this.drawStartX) / (this.image.width * this.scale),
        height: Math.abs(mouseY - this.drawStartY) / (this.image.height * this.scale),
        labelid: selectedLabelInfo.id,
        label: selectedLabelInfo.name,
        color: selectedLabelInfo.color,
      };
      this.rectangles.push(rect);
    },
    resizeRectangle(deltaX, deltaY) {
      switch (this.selectedResizeHandle) {
        case 'top-left':
          this.selectedRectangle.x += deltaX / (this.image.width * this.scale);
          this.selectedRectangle.y += deltaY / (this.image.height * this.scale);
          this.selectedRectangle.width -= deltaX / (this.image.width * this.scale);
          this.selectedRectangle.height -= deltaY / (this.image.height * this.scale);
          break;
        case 'top-right':
          this.selectedRectangle.y += deltaY / (this.image.height * this.scale);
          this.selectedRectangle.width += deltaX / (this.image.width * this.scale);
          this.selectedRectangle.height -= deltaY / (this.image.height * this.scale);
          break;
        case 'bottom-left':
          this.selectedRectangle.x += deltaX / (this.image.width * this.scale);
          this.selectedRectangle.width -= deltaX / (this.image.width * this.scale);
          this.selectedRectangle.height += deltaY / (this.image.height * this.scale);
          break;
        case 'bottom-right':
          this.selectedRectangle.width += deltaX / (this.image.width * this.scale);
          this.selectedRectangle.height += deltaY / (this.image.height * this.scale);
          break;
      }
    },
    getResizeHandle(mouseX, mouseY) {
      if (!this.selectedRectangle) return null;
      const { x, y, width, height } = this.selectedRectangle;
      const rectX = this.originX + x * this.image.width * this.scale;
      const rectY = this.originY + y * this.image.height * this.scale;
      const rectW = width * this.image.width * this.scale;
      const rectH = height * this.image.height * this.scale;
      const handleSize = this.resizeHandleSize / this.scale;

      if (this.isWithinBounds(mouseX, mouseY, rectX, rectY, handleSize)) return 'top-left';
      if (this.isWithinBounds(mouseX, mouseY, rectX + rectW, rectY, handleSize)) return 'top-right';
      if (this.isWithinBounds(mouseX, mouseY, rectX, rectY + rectH, handleSize)) return 'bottom-left';
      if (this.isWithinBounds(mouseX, mouseY, rectX + rectW, rectY + rectH, handleSize)) return 'bottom-right';

      return null;
    },
    isWithinBounds(mouseX, mouseY, targetX, targetY, size) {
      return (
        mouseX >= targetX - size / 2 &&
        mouseX <= targetX + size / 2 &&
        mouseY >= targetY - size / 2 &&
        mouseY <= targetY + size / 2
      );
    },
    selectRectangle(index) {
      this.selectedRectangle = this.rectangles[index];
      this.draw();
    },
    selectLabel(label) {
      this.selectedLabel = label.name;
      if (this.selectedRectangle) {
        this.selectedRectangle.label = label.name;
        this.selectedRectangle.color = label.color;
        this.selectedRectangle.labelid = label.id;
        this.draw();
      }
    },
    removeRectangle(index) {
      this.rectangles.splice(index, 1);
      if (this.selectedRectangle && this.selectedRectangle === this.rectangles[index]) {
        this.selectedRectangle = null;
      }
      this.draw();
    },
    redrawNormalizedRectangles() {
      if (!this.image) return;

      this.context.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
      this.context.drawImage(this.image, this.originX, this.originY, this.image.width * this.scale, this.image.height * this.scale);

      this.rectangles.forEach((rect) => {
        const rectX = rect.x * this.image.width;
        const rectY = rect.y * this.image.height;
        const rectWidth = rect.width * this.image.width;
        const rectHeight = rect.height * this.image.height;

        this.context.strokeStyle = 'black';
        this.context.strokeRect(
          this.originX + rectX * this.scale,
          this.originY + rectY * this.scale,
          rectWidth * this.scale,
          rectHeight * this.scale
        );
      });
    },
    copyRectangle() {
      if (this.selectedRectangle) {
        this.copiedRectangle = { ...this.selectedRectangle };
      }
    },
    pasteRectangle() {
      if (this.copiedRectangle) {
        const newRect = {
          ...this.copiedRectangle,
          x: this.copiedRectangle.x + 0.05,
          y: this.copiedRectangle.y + 0.05,
        };
        this.rectangles.push(newRect);
        this.selectedRectangle = newRect;
        this.draw();
      }
    },
  },
};
</script>

<style scoped>
canvas {
  display: block;
  cursor: crosshair;
  margin-bottom: 16px;
}

.active {
  background-color: rgba(0, 0, 255, 0.1);
}

.active-label {
  background-color: rgba(0, 128, 0, 0.1);
}
</style>"