SOURCE

console 命令行工具 X clear

                    
>
console
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Cropper and Rectangle Tool</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.12/cropper.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.12/cropper.min.js"></script>
    <style>
        #image-container { max-width: 500px; margin: 20px auto; }
        #cropper-container { position: relative; }
        #rectangle-canvas { position: absolute; top: 0; left: 0; pointer-events: none; }
        button { margin: 5px; }
    </style>
</head>
<body>
    <div id="image-container">
        <div id="cropper-container">
            <img id="image" src="https://fengyuanchen.github.io/cropperjs/images/picture.jpg" alt="Image to crop">
            <canvas id="rectangle-canvas"></canvas>
        </div>
    </div>
    <button id="crop-mode">Crop Mode</button>
    <button id="rectangle-mode">Rectangle Mode</button>

    <script>
        const image = document.getElementById('image');
        const cropModeButton = document.getElementById('crop-mode');
        const rectangleModeButton = document.getElementById('rectangle-mode');
        const rectangleCanvas = document.getElementById('rectangle-canvas');
        const ctx = rectangleCanvas.getContext('2d');
        let cropper;
        let rectangles = [];
        let isDrawing = false;
        let startX, startY;
        let selectedRect = null;
        let isDragging = false;
        let mode = 'crop'; // 'crop' or 'rectangle'

        // Initialize Cropper
        window.addEventListener('load', () => {
            cropper = new Cropper(image, {
                aspectRatio: NaN,
                viewMode: 1,
                ready: function() {
                    updateRectangleCanvas();
                }
            });
        });

        // Switch to crop mode
        cropModeButton.addEventListener('click', () => {
            mode = 'crop';
            cropper.enable(); // Enable cropper controls
            rectangleCanvas.style.pointerEvents = 'none'; // Disable rectangle interactions
        });

        // Switch to rectangle mode
        rectangleModeButton.addEventListener('click', () => {
            mode = 'rectangle';
            cropper.disable(); // Disable cropper controls
            rectangleCanvas.style.pointerEvents = 'auto'; // Enable rectangle interactions
            setupRectangleDrawing(); // Setup rectangle drawing events
        });

        // Add rectangle drawing functionality
        function setupRectangleDrawing() {
            rectangleCanvas.onmousedown = startDrawing;
            rectangleCanvas.onmousemove = drawing;
            rectangleCanvas.onmouseup = stopDrawing;
        }

        function startDrawing(e) {
            if (mode !== 'rectangle') return;
            isDrawing = true;
            const rect = rectangleCanvas.getBoundingClientRect();
            startX = e.clientX - rect.left;
            startY = e.clientY - rect.top;
        }

        function drawing(e) {
            if (!isDrawing) return;
            const rect = rectangleCanvas.getBoundingClientRect();
            const x = e.clientX - rect.left;
            const y = e.clientY - rect.top;
            redrawCanvas();
            drawRect(startX, startY, x - startX, y - startY);
        }

        function stopDrawing(e) {
            if (!isDrawing) return;
            isDrawing = false;
            const rect = rectangleCanvas.getBoundingClientRect();
            const x = e.clientX - rect.left;
            const y = e.clientY - rect.top;
            rectangles.push({x: startX, y: startY, width: x - startX, height: y - startY});
            redrawCanvas();
            setupRectangleEditing();
        }

        function redrawCanvas() {
            ctx.clearRect(0, 0, rectangleCanvas.width, rectangleCanvas.height);
            rectangles.forEach((rect, index) => {
                drawRect(rect.x, rect.y, rect.width, rect.height);
                drawDeleteButton(rect.x + rect.width - 20, rect.y, index); // Draw delete button in the top-right corner
            });
        }

        function drawRect(x, y, width, height) {
            ctx.strokeStyle = 'red';
            ctx.lineWidth = 2;
            ctx.strokeRect(x, y, width, height);
        }

        // Draw delete button (small red box with an '×')
        function drawDeleteButton(x, y, index) {
            ctx.fillStyle = 'red';
            ctx.fillRect(x, y, 20, 20); // Small red square
            ctx.fillStyle = 'white';
            ctx.font = '16px Arial';
            ctx.fillText('×', x + 5, y + 15); // Draw '×' inside the red square
        }

        // Setup rectangle editing (move and delete)
        function setupRectangleEditing() {
            rectangleCanvas.onmousedown = startEditingRect;
            rectangleCanvas.onmousemove = editingRect;
            rectangleCanvas.onmouseup = stopEditingRect;
        }

        function startEditingRect(e) {
            const rect = rectangleCanvas.getBoundingClientRect();
            const mouseX = e.clientX - rect.left;
            const mouseY = e.clientY - rect.top;

            for (let i = rectangles.length - 1; i >= 0; i--) {
                const r = rectangles[i];
                // Check if clicking delete button
                if (mouseX >= r.x + r.width - 20 && mouseX <= r.x + r.width &&
                    mouseY >= r.y && mouseY <= r.y + 20) {
                    // Remove the rectangle if delete button is clicked
                    rectangles.splice(i, 1);
                    redrawCanvas();
                    return;
                }

                // Check if clicking inside the rectangle
                if (mouseX >= r.x && mouseX <= r.x + r.width &&
                    mouseY >= r.y && mouseY <= r.y + r.height) {
                    selectedRect = r;
                    startX = mouseX;
                    startY = mouseY;
                    isDragging = true;
                    return;
                }
            }
        }

        function editingRect(e) {
            if (!isDragging) return;
            const rect = rectangleCanvas.getBoundingClientRect();
            const mouseX = e.clientX - rect.left;
            const mouseY = e.clientY - rect.top;

            selectedRect.x += mouseX - startX;
            selectedRect.y += mouseY - startY;
            startX = mouseX;
            startY = mouseY;

            redrawCanvas();
        }

        function stopEditingRect() {
            isDragging = false;
            selectedRect = null;
        }

        function updateRectangleCanvas() {
            const cropBoxData = cropper.getCropBoxData();
            rectangleCanvas.width = cropBoxData.width;
            rectangleCanvas.height = cropBoxData.height;
            rectangleCanvas.style.left = cropBoxData.left + 'px';
            rectangleCanvas.style.top = cropBoxData.top + 'px';
            redrawCanvas();
        }

        // Update rectangle canvas when cropper changes
        cropper.container.addEventListener('crop', updateRectangleCanvas);
    </script>
</body>
</html>