I’m trying to create a photobooth web application. I’m encountering problems when using custom frames I created.
My problem is that the images and my custom frames are misaligned. I tried to adjust the frames but it also adjust the images so it’s still misaligned. It works perfectly when just choosing colored frames.
Please help me align the frames and my photostrip.
const photoStrip = document.getElementById('photoStrip');
const photos = JSON.parse(localStorage.getItem('photos')) || [];
photos.forEach(photo => {
const img = document.createElement('img');
img.src = photo;
photoStrip.appendChild(img);
});
// Clear photos from localStorage after displaying
localStorage.removeItem('photos');
document.getElementById('downloadBtn').addEventListener('click', () => {
html2canvas(photoStrip, {
onrendered: function(canvas) {
const link = document.createElement('a');
link.href = canvas.toDataURL('image/png');
link.download = 'photo_strip.png';
link.click();
}
});
});
document.getElementById('retakeBtn').addEventListener('click', () => {
window.location.href = 'camera.html';
});
document.querySelectorAll('.frame, .frame1').forEach(frame => {
frame.addEventListener('click', () => {
// Remove selected class from all frames
document.querySelectorAll('.frame, .frame1').forEach(f => f.classList.remove('selected'));
// Add selected class to clicked frame
frame.classList.add('selected');
const color = frame.getAttribute('data-color');
const frameSrc = frame.getAttribute('data-frame');
// Remove existing frame overlay if any
const existingOverlay = photoStrip.querySelector('.frame-overlay');
if (existingOverlay) {
existingOverlay.remove();
}
if (frameSrc) {
photoStrip.style.backgroundColor = 'transparent';
const overlay = document.createElement('img');
overlay.src = frameSrc;
overlay.className = 'frame-overlay';
photoStrip.appendChild(overlay);
// Ensure the overlay gets the correct size
overlay.style.width = "220px";
overlay.style.height = "740px";
// Shift photos and photo-strip 10px lower to match custom color positioning
photoStrip.querySelectorAll('img').forEach(img => {
img.style.marginTop = '10px';
});
photoStrip.style.marginTop = '-10px';
} else {
photoStrip.style.backgroundColor = color;
// Shift photos and photo-strip 10px lower for custom color
photoStrip.querySelectorAll('img').forEach(img => {
img.style.marginTop = '10px';
});
photoStrip.style.marginTop = '10px';
}
});
});
// Add color picker event listener
document.getElementById('colorPicker').addEventListener('input', function(e) {
// Remove selected class from all frames
document.querySelectorAll('.frame, .frame1').forEach(f => f.classList.remove('selected'));
// Remove existing frame overlay if any
const existingOverlay = photoStrip.querySelector('.frame-overlay');
if (existingOverlay) {
existingOverlay.remove();
}
// Apply the selected color
photoStrip.style.backgroundColor = e.target.value;
// Shift photos and photo-strip 10px lower for custom color
photoStrip.querySelectorAll('img').forEach(img => {
img.style.marginTop = '10px';
});
photoStrip.style.marginTop = '10px';
});
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
.banner {
width: 100%;
height: 100vh; /* Ensure it occupies the full viewport height */
background-image: url(bg3.png);
background-size: cover;
background-position: center;
display: flex;
align-items: flex-start;
justify-content: center;
margin: 0; /* Remove any default margin */
padding: 0; /* Remove any default padding */
box-sizing: border-box; /* Include padding and border in height calculation */
}
body {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0; /* Remove default margin */
padding: 0; /* Remove default padding */
font-family: 'Cascadia Code', sans-serif;
overflow: hidden; /* Prevent scrolling if content overflows */
}
.photo-strip {
display: flex;
flex-direction: column;
align-items: center;
padding: 0 !important; /* Remove padding to align the frame properly */
background-color: #91A6F7;
margin-right: 20px;
position: relative;
width: 220px;
height: 740px; /* Ensure it matches the frame overlay */
box-sizing: border-box; /* Include padding and border in height calculation */
margin-top: 0 !important; /* Ensure it starts at the top */
z-index: 5; /* Ensure photos are below the frame overlay */
}
.photo-strip img {
margin: 10px 0;
width: 200px;
height: 150px;
border-radius: 5px;
z-index: 5; /* Ensure photos are below the frame overlay */
}
#downloadBtn, #retakeBtn {
font-family: 'Cascadia Code';
padding: 10px 20px;
background-color: #91A6F7;
color: black;
font-size: 20px;
width: 175px;
height: 60px;
border: none;
border-radius: 30px;
cursor: pointer;
margin: 10px 5px;
}
#retakeBtn {
background-color: #91A6F7;
}
.frame-options {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
margin-bottom: 20px;
justify-content: center;
}
.frame, .frame1 {
top: 0;
width: 60px;
height: 60px;
border-radius: 5px;
cursor: pointer;
background-size: cover;
background-position: center;
}
.color-picker-container {
margin: 10px 0;
display: flex;
align-items: center;
gap: 10px;
}
.color-picker-label {
font-size: 16px;
color: black;
}
#colorPicker {
width: 60px;
height: 60px;
padding: 0;
border: none;
border-radius: 5px;
cursor: pointer;
}
.controls {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 20px; /* Add spacing below the photo strip */
}
.button-row {
display: flex;
justify-content: center;
width: 100%;
}
.frame-overlay {
position: absolute;
top: 0; /* Move the frame overlay to the top */
left: 0;
width: 220px;
height: 740px;
z-index: 10; /* Ensure it's above the photos */
pointer-events: none; /* Prevent interaction with the frame overlay */
}
<div class="banner">
<div class="photo-strip" id="photoStrip">
<!-- Photos will be appended here -->
</div>
<div class="controls">
<div class="frame-options">
<div class="frame1" style="background-image: url('frames/frame1.png')" data-frame="frames/frame1.png"></div>
</div>
<div class="color-picker-container">
<span class="color-picker-label">Custom Color:</span>
<input type="color" id="colorPicker" value="#91A6F7">
</div>
<button id="downloadBtn">Download</button>
<button id="retakeBtn">Retake</button>
</div>
</div>