Skip to content

Commit

Permalink
fix: improve UI and dragging with claude
Browse files Browse the repository at this point in the history
  • Loading branch information
Tobias Birmili committed Jul 20, 2024
1 parent 27996c5 commit c808358
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 32 deletions.
12 changes: 8 additions & 4 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,33 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>Image Grid Creator</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}
#canvas {
border: 1px solid black;
}
.upload-container {
margin-bottom: 10px;
margin-bottom: 5px;
}
button, input[type="file"] {
font-size: 16px;
padding: 10px;
padding: 5px;
margin: 5px;
cursor: pointer;
}
</style>
</head>
<body>
<p>Upload 8 images to arrange them in a 2x4 grid. No images will be uploaded.</p>
<div class="upload-container">
<input type="file" id="fileInput" multiple accept="image/*">
<button id="downloadBtn">Download Combined Image</button>
</div>
<canvas id="canvas" width="896" height="672"></canvas>
<canvas id="canvas" width="0" height="0"></canvas>

<script src="script.js"></script>
</body>
Expand Down
79 changes: 51 additions & 28 deletions public/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ const downloadBtn = document.getElementById('downloadBtn');

let images = [];
let imagePositions = [];
let displayGridWidth = 200; // Will be updated based on actual image sizes
let displayGridHeight = 200; // Will be updated based on actual image sizes
let displayGridWidth = 200;
let displayGridHeight = 200;
let draggedImageIndex = null;
let gridCols, gridRows;
let maxCanvasWidth, maxCanvasHeight;

const POSITION_THRESHOLD = 1; // 1 pixel threshold

fileInput.addEventListener('change', handleFileSelect);
downloadBtn.addEventListener('click', downloadImage);
canvas.addEventListener('dragover', handleDragOver);
Expand Down Expand Up @@ -63,10 +65,9 @@ function handleFileSelect(event) {

function calculateMaxCanvasSize() {
maxCanvasWidth = window.innerWidth * 0.9;
maxCanvasHeight = window.innerHeight * 0.9;
maxCanvasHeight = window.innerHeight * 0.8;
}


function updateCanvasSize() {
calculateMaxCanvasSize();

Expand All @@ -81,10 +82,9 @@ function updateCanvasSize() {
let gridWidth = maxWidth * gridCols;
let gridHeight = maxHeight * gridRows;

// Calculate the scaling factor to fit within the maximum canvas size
const scaleX = maxCanvasWidth / gridWidth;
const scaleY = maxCanvasHeight / gridHeight;
const scale = Math.min(scaleX, scaleY, 1); // Don't scale up if images are smaller
const scale = Math.min(scaleX, scaleY, 1);

displayGridWidth = maxWidth * scale;
displayGridHeight = maxHeight * scale;
Expand All @@ -93,12 +93,14 @@ function updateCanvasSize() {
canvas.height = displayGridHeight * gridRows;
}


function repositionImages() {
imagePositions = images.map((img, index) => {
const col = index % gridCols;
const row = Math.floor(index / gridCols);
return { x: col * displayGridWidth, y: row * displayGridHeight };
return {
x: col * displayGridWidth,
y: row * displayGridHeight
};
});
}

Expand Down Expand Up @@ -154,7 +156,6 @@ function drawImages() {
}
}

// Add an event listener for window resize
window.addEventListener('resize', () => {
if (images.length > 0) {
updateCanvasSize();
Expand All @@ -177,13 +178,19 @@ function drawImageWithAspectRatio(img, x, y, maxWidth, maxHeight) {
ctx.drawImage(img, x + offsetX, y + offsetY, newWidth, newHeight);
}


function enableDragAndDrop() {
let offsetX = 0;
let offsetY = 0;

canvas.addEventListener('mousedown', (e) => {
const { offsetX: x, offsetY: y } = e;
function handleStart(e) {
e.preventDefault();
const touch = e.touches ? e.touches[0] : e;
const rect = canvas.getBoundingClientRect();
const x = touch.clientX - rect.left;
const y = touch.clientY - rect.top;

console.log('Touch start:', x, y); // Add this line for debugging

draggedImageIndex = imagePositions
.map((pos, index) => ({ pos, index }))
.filter(({ pos }) => {
Expand All @@ -205,54 +212,72 @@ function enableDragAndDrop() {
offsetX = x - pos.x;
offsetY = y - pos.y;
}
});
}

canvas.addEventListener('mousemove', (e) => {
function handleMove(e) {
if (draggedImageIndex !== null) {
const { offsetX: x, offsetY: y } = e;
e.preventDefault();
const touch = e.touches ? e.touches[0] : e;
const rect = canvas.getBoundingClientRect();
const x = touch.clientX - rect.left;
const y = touch.clientY - rect.top;

const pos = imagePositions[draggedImageIndex];
pos.x = x - offsetX;
pos.y = y - offsetY;
drawImages();
}
});
}

canvas.addEventListener('mouseup', () => {
function handleEnd() {
if (draggedImageIndex !== null) {
snapToGrid(draggedImageIndex);
draggedImageIndex = null;
repositionImages();
drawImages();
}
});
}

canvas.addEventListener('mousedown', handleStart);
canvas.addEventListener('mousemove', handleMove);
canvas.addEventListener('mouseup', handleEnd);

canvas.addEventListener('touchstart', handleStart);
canvas.addEventListener('touchmove', handleMove);
canvas.addEventListener('touchend', handleEnd);
}

function arePositionsEqual(pos1, pos2) {
return Math.abs(pos1.x - pos2.x) < POSITION_THRESHOLD &&
Math.abs(pos1.y - pos2.y) < POSITION_THRESHOLD;
}

function snapToGrid(index) {
const pos = imagePositions[index];
const targetX = Math.round(pos.x / displayGridWidth) * displayGridWidth;
const targetY = Math.round(pos.y / displayGridHeight) * displayGridHeight;

// Ensure the image stays within the canvas bounds
pos.x = Math.max(0, Math.min(targetX, canvas.width - displayGridWidth));
pos.y = Math.max(0, Math.min(targetY, canvas.height - displayGridHeight));

const targetIndex = imagePositions.findIndex((p, i) => i !== index && p.x === pos.x && p.y === pos.y);
const targetIndex = imagePositions.findIndex((p, i) =>
i !== index &&
Math.abs(p.x - pos.x) < displayGridWidth / 2 &&
Math.abs(p.y - pos.y) < displayGridHeight / 2
);

if (targetIndex >= 0) {
// Swap positions
const tempPos = { ...imagePositions[targetIndex] };
imagePositions[targetIndex] = { ...imagePositions[index] };
imagePositions[index] = tempPos;

// Swap images
const tempImg = images[targetIndex];
images[targetIndex] = images[index];
images[index] = tempImg;

// Redraw images immediately after swapping
repositionImages();
drawImages();
}

repositionImages();
drawImages();
}

function downloadImage() {
Expand All @@ -270,15 +295,13 @@ function downloadImage() {
originalCanvas.width = maxWidth * gridCols;
originalCanvas.height = maxHeight * gridRows;

// Draw each image in its original size on the new canvas
images.forEach((img, index) => {
const pos = imagePositions[index];
const x = (pos.x / displayGridWidth) * maxWidth;
const y = (pos.y / displayGridHeight) * maxHeight;
originalCtx.drawImage(img, x, y);
});

// Download the combined image
const link = document.createElement('a');
link.download = 'combined-image.png';
link.href = originalCanvas.toDataURL();
Expand Down

0 comments on commit c808358

Please sign in to comment.