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
16 changes: 10 additions & 6 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,33 +24,37 @@ <h1>Keyforge Coin Flip</h1>

<main>
<div class="coin-container">
<div class="coin" id="coin" onclick="flipCoin()">
<div class="coin" id="coin">
<img src="front-key.png" alt="Keyforge Coin" class="coin-image" id="coinImage">
</div>
<button class="flip-button" onclick="flipCoin()">Flip Coin</button>
<button class="flip-button">Flip Coin</button>
</div>

<div class="custom-images-section">
<button class="toggle-custom-button" id="toggleCustom" aria-expanded="false">
Show Custom Coin Options
</button>

<div class="custom-images-section collapsed" id="customSection">
<h2>Custom Coin Images</h2>
<div class="upload-controls">
<div class="upload-group">
<label for="frontImageInput">Front Image:</label>
<input type="file" id="frontImageInput" accept="image/*" onchange="handleFrontImageUpload(event)">
<input type="file" id="frontImageInput" accept="image/*">
<div class="preview-container">
<img id="frontPreview" class="preview-image" alt="Front preview">
</div>
</div>

<div class="upload-group">
<label for="backImageInput">Back Image:</label>
<input type="file" id="backImageInput" accept="image/*" onchange="handleBackImageUpload(event)">
<input type="file" id="backImageInput" accept="image/*">
<div class="preview-container">
<img id="backPreview" class="preview-image" alt="Back preview">
</div>
</div>
</div>

<button class="reset-button" onclick="resetToDefault()">Reset to Default</button>
<button class="reset-button">Reset to Default</button>
</div>
</main>

Expand Down
213 changes: 125 additions & 88 deletions script.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,79 +6,129 @@ const DEFAULT_BACK_IMAGE = 'back-key.png';
let currentFrontImage = DEFAULT_FRONT_IMAGE;
let currentBackImage = DEFAULT_BACK_IMAGE;

// Load custom images from localStorage on page load
window.addEventListener('DOMContentLoaded', () => {
// DOM elements cache
const elements = {
coin: null,
coinImage: null,
flipButton: null,
toggleButton: null,
customSection: null,
frontInput: null,
backInput: null,
frontPreview: null,
backPreview: null,
resetButton: null
};

// Initialize app when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
initializeElements();
loadCustomImages();
attachEventListeners();
});

function loadCustomImages() {
// Cache DOM elements for better performance
const initializeElements = () => {
elements.coin = document.getElementById('coin');
elements.coinImage = document.getElementById('coinImage');
elements.flipButton = document.querySelector('.flip-button');
elements.toggleButton = document.getElementById('toggleCustom');
elements.customSection = document.getElementById('customSection');
elements.frontInput = document.getElementById('frontImageInput');
elements.backInput = document.getElementById('backImageInput');
elements.frontPreview = document.getElementById('frontPreview');
elements.backPreview = document.getElementById('backPreview');
elements.resetButton = document.querySelector('.reset-button');
};

// Attach all event listeners
const attachEventListeners = () => {
elements.coin?.addEventListener('click', flipCoin);
elements.flipButton?.addEventListener('click', flipCoin);
elements.toggleButton?.addEventListener('click', toggleCustomSection);
elements.frontInput?.addEventListener('change', handleFrontImageUpload);
elements.backInput?.addEventListener('change', handleBackImageUpload);
elements.resetButton?.addEventListener('click', resetToDefault);
};

// Toggle custom section visibility
const toggleCustomSection = () => {
const { customSection, toggleButton } = elements;
if (!customSection || !toggleButton) return;

customSection.classList.toggle('collapsed');
const isCollapsed = customSection.classList.contains('collapsed');
toggleButton.textContent = isCollapsed ? 'Show Custom Coin Options' : 'Hide Custom Coin Options';
toggleButton.setAttribute('aria-expanded', !isCollapsed);
};

// Load custom images from localStorage
const loadCustomImages = () => {
const savedFrontImage = localStorage.getItem('customFrontImage');
const savedBackImage = localStorage.getItem('customBackImage');

if (savedFrontImage) {
currentFrontImage = savedFrontImage;
updatePreview('frontPreview', savedFrontImage);
updatePreview(elements.frontPreview, savedFrontImage);
}

if (savedBackImage) {
currentBackImage = savedBackImage;
updatePreview('backPreview', savedBackImage);
updatePreview(elements.backPreview, savedBackImage);
}

// Update the coin image to show the current front image
const coinImage = document.getElementById('coinImage');
if (coinImage) {
coinImage.src = currentFrontImage;
if (elements.coinImage) {
elements.coinImage.src = currentFrontImage;
}
}

function handleFrontImageUpload(event) {
const file = event.target.files[0];
if (file && file.type.startsWith('image/')) {
const reader = new FileReader();
reader.onload = function(e) {
const imageData = e.target.result;
currentFrontImage = imageData;
localStorage.setItem('customFrontImage', imageData);

// Update preview
updatePreview('frontPreview', imageData);

// Update coin image
const coinImage = document.getElementById('coinImage');
if (coinImage) {
coinImage.src = currentFrontImage;
}
};
reader.readAsDataURL(file);
}
}

function handleBackImageUpload(event) {
const file = event.target.files[0];
if (file && file.type.startsWith('image/')) {
const reader = new FileReader();
reader.onload = function(e) {
const imageData = e.target.result;
currentBackImage = imageData;
localStorage.setItem('customBackImage', imageData);

// Update preview
updatePreview('backPreview', imageData);
};
reader.readAsDataURL(file);
}
}
};

function updatePreview(previewId, imageSrc) {
const preview = document.getElementById(previewId);
if (preview) {
preview.src = imageSrc;
preview.style.display = 'block';
}
}
// Handle front image upload
const handleFrontImageUpload = (event) => {
const file = event.target.files?.[0];
if (!file?.type.startsWith('image/')) return;

const reader = new FileReader();
reader.onload = (e) => {
const imageData = e.target.result;
currentFrontImage = imageData;
localStorage.setItem('customFrontImage', imageData);

function resetToDefault() {
updatePreview(elements.frontPreview, imageData);

if (elements.coinImage) {
elements.coinImage.src = currentFrontImage;
}
};
reader.readAsDataURL(file);
};

// Handle back image upload
const handleBackImageUpload = (event) => {
const file = event.target.files?.[0];
if (!file?.type.startsWith('image/')) return;

const reader = new FileReader();
reader.onload = (e) => {
const imageData = e.target.result;
currentBackImage = imageData;
localStorage.setItem('customBackImage', imageData);

updatePreview(elements.backPreview, imageData);
};
reader.readAsDataURL(file);
};

// Update preview image
const updatePreview = (previewElement, imageSrc) => {
if (!previewElement) return;

previewElement.src = imageSrc;
previewElement.style.display = 'block';
};

// Reset to default images
const resetToDefault = () => {
// Clear localStorage
localStorage.removeItem('customFrontImage');
localStorage.removeItem('customBackImage');
Expand All @@ -88,33 +138,29 @@ function resetToDefault() {
currentBackImage = DEFAULT_BACK_IMAGE;

// Clear file inputs
const frontInput = document.getElementById('frontImageInput');
const backInput = document.getElementById('backImageInput');
if (frontInput) frontInput.value = '';
if (backInput) backInput.value = '';
if (elements.frontInput) elements.frontInput.value = '';
if (elements.backInput) elements.backInput.value = '';

// Clear previews
const frontPreview = document.getElementById('frontPreview');
const backPreview = document.getElementById('backPreview');
if (frontPreview) {
frontPreview.src = '';
frontPreview.style.display = 'none';
if (elements.frontPreview) {
elements.frontPreview.src = '';
elements.frontPreview.style.display = 'none';
}
if (backPreview) {
backPreview.src = '';
backPreview.style.display = 'none';
if (elements.backPreview) {
elements.backPreview.src = '';
elements.backPreview.style.display = 'none';
}

// Update coin image
const coinImage = document.getElementById('coinImage');
if (coinImage) {
coinImage.src = currentFrontImage;
if (elements.coinImage) {
elements.coinImage.src = currentFrontImage;
}
}
};

function flipCoin() {
const coin = document.getElementById('coin');
const coinImage = coin.querySelector('.coin-image');
// Flip coin animation
const flipCoin = () => {
const { coin, coinImage } = elements;
if (!coin || !coinImage) return;

// Remove any existing animation
coin.classList.remove('flipping');
Expand All @@ -123,7 +169,7 @@ function flipCoin() {
const flipDuration = Math.random() * 0.5 + 0.5;

// Set the animation duration
coin.style.animationDuration = flipDuration + 's';
coin.style.animationDuration = `${flipDuration}s`;

// Start flipping animation
setTimeout(() => {
Expand All @@ -133,11 +179,7 @@ function flipCoin() {
// Switch images during flip
let isShowingFront = true;
const flipInterval = setInterval(() => {
if (isShowingFront) {
coinImage.src = currentBackImage;
} else {
coinImage.src = currentFrontImage;
}
coinImage.src = isShowingFront ? currentBackImage : currentFrontImage;
isShowingFront = !isShowingFront;
}, 150); // Switch every 150ms for visual effect

Expand All @@ -148,15 +190,10 @@ function flipCoin() {
// Random final result (50/50 chance)
const finalResult = Math.random() < 0.5;

if (finalResult) {
coinImage.src = currentFrontImage;
console.log('Result: Front');
} else {
coinImage.src = currentBackImage;
console.log('Result: Back');
}
coinImage.src = finalResult ? currentFrontImage : currentBackImage;
console.log(`Result: ${finalResult ? 'Front' : 'Back'}`);

// Remove animation class
coin.classList.remove('flipping');
}, flipDuration * 1000);
}
};
39 changes: 37 additions & 2 deletions styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -121,16 +121,47 @@ main {
100% { transform: rotateY(0deg); }
}

/* Toggle Custom Button */
.toggle-custom-button {
background: linear-gradient(45deg, #4a90e2, #67b8f7);
color: white;
border: none;
padding: 12px 24px;
font-size: 1rem;
font-weight: bold;
border-radius: 25px;
cursor: pointer;
transition: all 0.3s ease;
margin: 20px auto;
display: block;
}

.toggle-custom-button:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(74, 144, 226, 0.4);
}

/* Custom Images Section */
.custom-images-section {
margin-top: 50px;
margin-top: 20px;
padding: 30px;
background-color: #16213e;
border-radius: 15px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
max-width: 600px;
margin-left: auto;
margin-right: auto;
max-height: 1000px;
opacity: 1;
overflow: hidden;
transition: all 0.5s ease-in-out;
}

.custom-images-section.collapsed {
max-height: 0;
opacity: 0;
padding: 0 30px;
margin-top: 0;
}

.custom-images-section h2 {
Expand Down Expand Up @@ -235,9 +266,13 @@ main {
font-size: 1.5rem;
}

.toggle-custom-button {
font-size: 0.9rem;
padding: 10px 20px;
}

.custom-images-section {
padding: 20px;
margin-top: 30px;
}

.custom-images-section h2 {
Expand Down