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';
window.addEventListener('load', () => {
cropper = new Cropper(image, {
aspectRatio: NaN,
viewMode: 1,
ready: function() {
updateRectangleCanvas();
}
});
});
cropModeButton.addEventListener('click', () => {
mode = 'crop';
cropper.enable();
rectangleCanvas.style.pointerEvents = 'none';
});
rectangleModeButton.addEventListener('click', () => {
mode = 'rectangle';
cropper.disable();
rectangleCanvas.style.pointerEvents = 'auto';
setupRectangleDrawing();
});
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);
});
}
function drawRect(x, y, width, height) {
ctx.strokeStyle = 'red';
ctx.lineWidth = 2;
ctx.strokeRect(x, y, width, height);
}
function drawDeleteButton(x, y, index) {
ctx.fillStyle = 'red';
ctx.fillRect(x, y, 20, 20);
ctx.fillStyle = 'white';
ctx.font = '16px Arial';
ctx.fillText('×', x + 5, y + 15);
}
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];
if (mouseX >= r.x + r.width - 20 && mouseX <= r.x + r.width &&
mouseY >= r.y && mouseY <= r.y + 20) {
rectangles.splice(i, 1);
redrawCanvas();
return;
}
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();
}
cropper.container.addEventListener('crop', updateRectangleCanvas);
</script>
</body>
</html>