Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# panosplitter

Split your horizontal images into 4x5 images for Instagram carousel posts.
Split your horizontal images into 4images of variable aspect ratio (4x5, 1x1, 9x16) for Instagram carousel posts.

# License
The code in this project is licensed under GPLv3. Except for all images which are not free to use.
11 changes: 10 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,17 @@
<img src="images/logo.svg" alt="FUTC Bird Logo" width="100" height="100" class="logo">
</div>
<h1>FUTC's Instagram Panorama Slicer</h1>
<p>Split your panorama images into Instagram-friendly carousel posts (4:5 aspect ratio)</p>
<p>Split your panorama images into Instagram-friendly carousel posts (standard is 4:5 aspect ratio, choose yours below)</p>
<p>Your photos never leave your computer, all processing is done locally</p>

<div class="aspect-ratio-selector">
<label for="aspect-ratio">Choose aspect ratio:</label>
<select id="aspect-ratio" name="aspect-ratio">
<option value="4:5" selected>4:5 (Instagram standard portrait)</option>
<option value="1:1">1:1 (Square)</option>
<option value="9:16">9:16 (Stories/Reels)</option>
</select>
</div>
</header>

<!-- Loading overlay -->
Expand Down
28 changes: 23 additions & 5 deletions script.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
function getAspectRatio(aspectRatioSelect) {
const value = aspectRatioSelect.value;
const [w, h] = value.split(":").map(Number);
return w / h; // returns numerical ratio
}

document.addEventListener('DOMContentLoaded', () => {
// DOM Elements
const uploadArea = document.getElementById('upload-area');
Expand All @@ -21,18 +27,18 @@ document.addEventListener('DOMContentLoaded', () => {
const loadingText = document.getElementById('loading-text');
const downloadBtnText = document.querySelector('.btn-text');
const downloadBtnLoader = document.querySelector('.btn-loader');

// variable aspectRatio
let aspectRatio = getAspectRatio(document.getElementById("aspect-ratio"));

// Variables to store image data
let originalImage = null;
let slicedImages = [];
let fullViewImage = null;

// Standard Instagram 4:5 aspect ratio
const aspectRatio = 4/5; // width:height ratio

// Standard resolution (for standard mode)
const standardWidth = 1080;
const standardHeight = Math.round(standardWidth / aspectRatio); // Should be 1350
let standardHeight = Math.round(standardWidth / aspectRatio); // Should be 1350

const minSlices = 2;
const halfSliceWidth = standardWidth / 2;
Expand Down Expand Up @@ -137,6 +143,16 @@ document.addEventListener('DOMContentLoaded', () => {
updateImageDetails();
}
});

// Aspect ratio change
aspectRatioSelect = document.getElementById("aspect-ratio");
aspectRatioSelect.addEventListener('change', () => {
if (originalImage) {
aspectRatio = getAspectRatio(aspectRatioSelect);
standardHeight = Math.round(standardWidth / aspectRatio);
updateImageDetails();
}
});

// Handle file upload
function handleFile(file) {
Expand Down Expand Up @@ -405,6 +421,7 @@ document.addEventListener('DOMContentLoaded', () => {
if (fullViewImage) {
const fullViewItem = document.createElement('div');
fullViewItem.className = 'slice-item full-view-item';
fullViewItem.style.aspectRatio = `${fullViewImage.width}/${fullViewImage.height}`;

const img = document.createElement('img');
img.src = fullViewImage.dataURL;
Expand All @@ -428,11 +445,12 @@ document.addEventListener('DOMContentLoaded', () => {
slicedImages.forEach(slice => {
const sliceItem = document.createElement('div');
sliceItem.className = 'slice-item';
sliceItem.style.aspectRatio = `${slice.width} / ${slice.height}`;

const img = document.createElement('img');
img.src = slice.dataURL;
img.alt = `Slice ${slice.number}`;

const number = document.createElement('div');
number.className = 'slice-number';
number.textContent = slice.number;
Expand Down
33 changes: 33 additions & 0 deletions styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -676,4 +676,37 @@ footer {
flex-direction: row;
justify-content: space-between;
}
}

/* Style for aspect ratio selector */
.aspect-ratio-selector {
margin-top: 1.5rem;
}

.aspect-ratio-selector label {
font-weight: 600;
margin-right: 0.5rem;
color: #333;
}

.aspect-ratio-selector select {
padding: 0.5rem 1rem;
font-size: 1rem;
border: 2px solid #ccc;
border-radius: 8px;
background: white;
color: #333;
cursor: pointer;
transition: all 0.2s ease-in-out;
}

.aspect-ratio-selector select:hover {
border-color: #007bff;
box-shadow: 0 0 6px rgba(0, 123, 255, 0.3);
}

.aspect-ratio-selector select:focus {
outline: none;
border-color: #0056b3;
box-shadow: 0 0 6px rgba(0, 86, 179, 0.3);
}