基于触摸事件在图片上绘制矩形以实现区域选择功能
Got it, let's build a solution that lets users draw rectangles on an image to select specific areas—perfect for marking parking spots like you mentioned! This implementation uses vanilla HTML, CSS, and JavaScript, so no external dependencies are required.
Core Setup: HTML + CSS
First, we'll create a container that holds both the image and a transparent canvas. The canvas sits directly on top of the image, so we can draw rectangles without altering the original image file.
<div class="image-container"> <img src="your-parking-lot-image.jpg" alt="Parking Lot" class="target-image"> <canvas class="drawing-canvas"></canvas> </div>
For the CSS, we need to ensure the canvas perfectly overlays the image:
.image-container { position: relative; display: inline-block; /* Shrink to match the image's size */ } .target-image { display: block; max-width: 100%; height: auto; } .drawing-canvas { position: absolute; top: 0; left: 0; width: 100%; height: 100%; cursor: crosshair; background-color: transparent; }
JavaScript Logic for Drawing Rectangles
Next, we'll add mouse event handlers to track user input, draw rectangles in real-time, and save all selected areas for later use.
const container = document.querySelector('.image-container'); const canvas = document.querySelector('.drawing-canvas'); const ctx = canvas.getContext('2d'); let isDrawing = false; let startX, startY; let tempX, tempY, tempWidth, tempHeight; // Track temporary rectangle during drag const drawnRectangles = []; // Stores all user-selected areas // Resize canvas to match image dimensions (runs on load and window resize) function resizeCanvas() { const img = document.querySelector('.target-image'); canvas.width = img.offsetWidth; canvas.height = img.offsetHeight; } // Initialize canvas size when image finishes loading document.querySelector('.target-image').addEventListener('load', resizeCanvas); // Adjust canvas size if window is resized (for responsive images) window.addEventListener('resize', resizeCanvas); // Start drawing when user clicks the canvas canvas.addEventListener('mousedown', (e) => { isDrawing = true; // Get coordinates relative to the canvas (not the whole window) const rect = canvas.getBoundingClientRect(); startX = e.clientX - rect.left; startY = e.clientY - rect.top; // Clear any temporary rectangle preview redrawRectangles(); }); // Update rectangle preview as user drags the mouse canvas.addEventListener('mousemove', (e) => { if (!isDrawing) return; const rect = canvas.getBoundingClientRect(); const currentX = e.clientX - rect.left; const currentY = e.clientY - rect.top; // Calculate rectangle dimensions (handles dragging left/up from starting point) const width = currentX - startX; const height = currentY - startY; tempX = width < 0 ? currentX : startX; tempY = height < 0 ? currentY : startY; tempWidth = Math.abs(width); tempHeight = Math.abs(height); // Redraw all saved rectangles + the current temporary preview redrawRectangles(); drawSingleRectangle(tempX, tempY, tempWidth, tempHeight, 'rgba(0, 123, 255, 0.3)', '#007bff'); }); // Stop drawing and save the rectangle when user releases the mouse canvas.addEventListener('mouseup', () => { if (!isDrawing) return; isDrawing = false; // Save the final rectangle to our list drawnRectangles.push({ x: tempX, y: tempY, width: tempWidth, height: tempHeight }); redrawRectangles(); // Refresh to ensure consistency // Optional: Log the new rectangle for testing console.log('New selected area:', drawnRectangles[drawnRectangles.length - 1]); }); // Helper: Redraw all saved rectangles function redrawRectangles() { ctx.clearRect(0, 0, canvas.width, canvas.height); drawnRectangles.forEach(rect => { drawSingleRectangle(rect.x, rect.y, rect.width, rect.height, 'rgba(0, 123, 255, 0.3)', '#007bff'); }); } // Helper: Draw a single rectangle with fill and border function drawSingleRectangle(x, y, width, height, fillColor, borderColor) { ctx.fillStyle = fillColor; ctx.strokeStyle = borderColor; ctx.lineWidth = 2; ctx.fillRect(x, y, width, height); ctx.strokeRect(x, y, width, height); }
Key Features Explained
- Canvas Overlay: All drawing happens on a transparent canvas layer, so your original image stays untouched.
- Responsive Alignment: The canvas resizes with the image, ensuring selection rectangles stay correctly positioned even if the image scales.
- Drag Direction Handling: The code works whether users drag right/down or left/up from their starting click.
- Saved Selection Data: The
drawnRectanglesarray stores every selected area—you can use this data for saving to a database, highlighting spots, or other actions.
Quick Enhancements You Can Add
- Let users delete existing rectangles by clicking on them
- Add controls to change rectangle color/opacity
- Label selected areas (e.g., parking spot numbers)
- Restrict rectangle dimensions to match standard parking spot sizes
内容的提问来源于stack exchange,提问作者aahan verma

