Skip to content

Instantly share code, notes, and snippets.

@simonw
Created March 1, 2025 00:01
Show Gist options
  • Save simonw/e23917eddcbb368c9b6180d581f8f40a to your computer and use it in GitHub Desktop.
Save simonw/e23917eddcbb368c9b6180d581f8f40a to your computer and use it in GitHub Desktop.
╭────────────────────────────────────────────────╮
│ ✻ Welcome to Claude Code research preview! │
│ │
│ /help for help │
│ │
│ cwd: /Users/simon/Dropbox/Development/tools │
╰────────────────────────────────────────────────╯
Tips for getting started:
1. Run /init to create a CLAUDE.md file with instructions for Claude.
2. Ask Claude questions about your codebase.
3. Ask Claude to implement changes to your codebase.
> Modify social-media-cropper to add a picker where you can pick between 2:1
or 14:10 ratio
⏺ Read(file_path: …
"/Users/simon/Dropbox/Development/tools/social-media-cropper.html")
  ⎿  <!DOCTYPE html>
<html>
<head>
<title>Social Media Card Cropper</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/lib
/cropperjs/1.5.13/cropper.min.css">
<style>
body {
font-family: system-ui, -apple-system, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background: #f5f5f5;
}
.container {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.drop-zone {
border: 2px dashed #ccc;
border-radius: 4px;
padding: 20px;
text-align: center;
margin-bottom: 20px;
background: #fafafa;
cursor: pointer;
}
.drop-zone.dragover {
border-color: #666;
background: #eee;
}
.img-container {
max-width: 100%;
margin-bottom: 20px;
}
#image {
display: block;
max-width: 100%;
}
.preview-container {
margin-top: 20px;
padding: 10px;
background: #fafafa;
border-radius: 4px;
}
#preview {
width: 100%;
max-width: 600px;
margin: 0 auto;
display: block;
}
.download-btn {
display: inline-block;
padding: 10px 20px;
background: #0066cc;
color: white;
text-decoration: none;
border-radius: 4px;
margin-top: 10px;
}
.download-btn:hover {
background: #0052a3;
}
.hidden {
display: none;
}
</style>
</head>
<body>
<div class="container">
<h1>Social Media Card Cropper</h1>
<p>Drop an image or click to select. The crop area is fixed to
2:1 ratio.</p>
<div class="drop-zone" id="dropZone">
Drop image here, click to select, or paste from clipboard
<input type="file" id="fileInput" accept="image/*"
class="hidden">
</div>
<div class="img-container">
<img id="image" class="hidden">
</div>
<div class="preview-container hidden" id="previewContainer">
<h3>Preview (0.7 quality JPEG)</h3>
<img id="preview">
<div style="text-align: center; margin-top: 10px;">
<a href="#" id="downloadBtn"
class="download-btn">Download Social Media Card</a>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.
3/cropper.min.js"></script>
<script>
let cropper = null;
const dropZone = document.getElementById('dropZone');
const fileInput = document.getElementById('fileInput');
// Handle paste events
document.addEventListener('paste', (e) => {
e.preventDefault();
const items = (e.clipboardData ||
e.originalEvent.clipboardData).items;
for (const item of items) {
if (item.type.indexOf('image') === 0) {
const file = item.getAsFile();
handleFile(file);
break;
}
}
});
const image = document.getElementById('image');
const preview = document.getElementById('preview');
const previewContainer =
document.getElementById('previewContainer');
const downloadBtn = document.getElementById('downloadBtn');
// Handle drag and drop
dropZone.addEventListener('dragover', (e) => {
e.preventDefault();
dropZone.classList.add('dragover');
});
dropZone.addEventListener('dragleave', () => {
dropZone.classList.remove('dragover');
});
dropZone.addEventListener('drop', (e) => {
e.preventDefault();
dropZone.classList.remove('dragover');
handleFile(e.dataTransfer.files[0]);
});
// Handle click to select
dropZone.addEventListener('click', () => {
fileInput.click();
});
fileInput.addEventListener('change', (e) => {
if (e.target.files.length) {
handleFile(e.target.files[0]);
}
});
function handleFile(file) {
if (!file.type.startsWith('image/')) {
alert('Please select an image file.');
return;
}
const reader = new FileReader();
reader.onload = (e) => {
image.src = e.target.result;
image.classList.remove('hidden');
initCropper();
};
reader.readAsDataURL(file);
}
function initCropper() {
if (cropper) {
cropper.destroy();
}
cropper = new Cropper(image, {
aspectRatio: 2,
viewMode: 1,
dragMode: 'move',
autoCropArea: 1,
restore: false,
guides: true,
center: true,
highlight: false,
cropBoxMovable: true,
cropBoxResizable: false,
toggleDragModeOnDblclick: false,
crop: updatePreview
});
}
function updatePreview() {
if (!cropper) return;
const canvas = cropper.getCroppedCanvas();
if (!canvas) return;
// Convert to JPEG with 0.7 quality
const previewUrl = canvas.toDataURL('image/jpeg', 0.7);
preview.src = previewUrl;
previewContainer.classList.remove('hidden');
// Update download link
downloadBtn.href = previewUrl;
downloadBtn.download = 'social-media-card.jpg';
}
</script>
</body>
</html>
⏺ Update(file_path: /Users/simon/Dropbox/Development/tools/social-media-cropper.html)…
⎿ Updated /Users/simon/Dropbox/Development/tools/social-media-cropper.html with 10 additions and 1 removal
70 <body>
71 <div class="container">
72 <h1>Social Media Card Cropper</h1>
73 <p>Drop an image or click to select. The crop area is fixed to 2:1 ratio.</p>
73 <p>Drop an image or click to select. Select your preferred aspect ratio below.</p>
74
75 <div style="margin-bottom: 15px;">
76 <label style="margin-right: 10px;">
77 <input type="radio" name="aspectRatio" value="2" checked> 2:1 ratio
78 </label>
79 <label>
80 <input type="radio" name="aspectRatio" value="1.4"> 14:10 ratio
81 </label>
82 </div>
83
84 <div class="drop-zone" id="dropZone">
85 Drop image here, click to select, or paste from clipboard
86 <input type="file" id="fileInput" accept="image/*" class="hidden">
⏺ Update(file_path: /Users/simon/Dropbox/Development/tools/social-media-cropper.html)…
⎿ Updated /Users/simon/Dropbox/Development/tools/social-media-cropper.html with 5 additions and 1 removal
169 cropper.destroy();
170 }
171
172 // Get the selected aspect ratio
173 const aspectRatioValue = document.querySelector('input[name="aspectRatio"]:checked').value;
174 const ratio = parseFloat(aspectRatioValue);
175
176 cropper = new Cropper(image, {
177 aspectRatio: 2,
177 aspectRatio: ratio,
178 viewMode: 1,
179 dragMode: 'move',
180 autoCropArea: 1,
⏺ Update(file_path: /Users/simon/Dropbox/Development/tools/social-media-cropper.html)…
⎿ Updated /Users/simon/Dropbox/Development/tools/social-media-cropper.html with 9 additions
148 handleFile(e.target.files[0]);
149 }
150 });
151
152 // Listen for aspect ratio changes and update the cropper
153 document.querySelectorAll('input[name="aspectRatio"]').forEach(radio => {
154 radio.addEventListener('change', () => {
155 if (cropper) {
156 initCropper();
157 }
158 });
159 });
160
161 function handleFile(file) {
162 if (!file.type.startsWith('image/')) {
⏺ Update(file_path: /Users/simon/Dropbox/Development/tools/social-media-cropper.html)…
⎿ Updated /Users/simon/Dropbox/Development/tools/social-media-cropper.html with 1 addition
93 <div class="preview-container hidden" id="previewContainer">
94 <h3>Preview (0.7 quality JPEG)</h3>
95 <img id="preview">
96 <div id="dimensionsInfo" style="text-align: center; margin-top: 5px; font-size: 14px; color: #666;
"></div>
97 <div style="text-align: center; margin-top: 10px;">
98 <a href="#" id="downloadBtn" class="download-btn">Download Social Media Card</a>
99 </div>
⏺ Update(file_path: /Users/simon/Dropbox/Development/tools/social-media-cropper.html)…
⎿ Updated /Users/simon/Dropbox/Development/tools/social-media-cropper.html with 4 additions
210 preview.src = previewUrl;
211 previewContainer.classList.remove('hidden');
212
213 // Show dimensions
214 const dimensionsInfo = document.getElementById('dimensionsInfo');
215 dimensionsInfo.textContent = `Dimensions: ${canvas.width} × ${canvas.height} pixels`;
216
217 // Update download link
218 downloadBtn.href = previewUrl;
219 downloadBtn.download = 'social-media-card.jpg';
⏺ Added radio button selector for 2:1 and 14:10 aspect ratios, updated the cropper to use the selected ratio, and added
dimensions display to the preview.
╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ >  │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
Press Ctrl-C again to exit \⏎ for newline
Total cost: $0.1260
Total duration (API): 36.3s
Total duration (wall): 1m 2.3s
(base) simon@Simons-MacBook-Pro-7 tools %
(base) simon@Simons-MacBook-Pro-7 tools %
(base) simon@Simons-MacBook-Pro-7 tools % git diff
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment