<html><head><base href="about:blank">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cryptocurrency Wheel of Fortune</title>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Poppins', sans-serif;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d);
background-size: 400% 400%;
animation: gradientBG 15s ease infinite;
color: #ffffff;
}
@keyframes gradientBG {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
.title-container {
margin-bottom: 20px;
text-align: center;
}
#wheelTitle {
font-size: 2.8em;
font-weight: bold;
color: #ffffff;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3), 0 0 10px rgba(255, 255, 255, 0.5);
margin: 0;
padding: 10px;
border: none;
background: none;
text-align: center;
width: 100%;
outline: none;
transition: all 0.3s ease;
}
#wheelTitle:hover, #wheelTitle:focus {
transform: scale(1.05);
text-shadow: 0 4px 8px rgba(0, 0, 0, 0.5), 0 0 20px rgba(255, 255, 255, 0.7);
}
.container {
display: flex;
gap: 40px;
padding: 30px;
background-color: rgba(255, 255, 255, 0.1);
border-radius: 20px;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.3);
backdrop-filter: blur(10px);
position: relative;
transition: all 0.3s ease;
}
.container:hover {
transform: translateY(-5px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4);
}
.wheels-container {
display: flex;
gap: 40px;
}
.wheel-container {
width: 500px;
height: 500px;
position: relative;
perspective: 1000px;
}
.wheel {
width: 100%;
height: 100%;
border-radius: 50%;
transition: transform 5s cubic-bezier(0.25, 0.1, 0.25, 1);
box-shadow: 0 0 30px rgba(0, 0, 0, 0.3), 0 0 60px rgba(255, 255, 255, 0.1);
transform-style: preserve-3d;
}
.controls {
display: flex;
flex-direction: column;
gap: 20px;
width: 350px;
}
#entryList, #entryList2 {
width: 100%;
height: 200px;
overflow-y: auto;
padding: 15px;
border: 2px solid #3498db;
border-radius: 10px;
font-family: 'Poppins', sans-serif;
font-size: 14px;
background-color: rgba(255, 255, 255, 0.1);
color: #ffffff;
transition: all 0.3s ease;
}
#entryList:hover, #entryList2:hover {
border-color: #2ecc71;
box-shadow: 0 0 15px rgba(46, 204, 113, 0.5);
}
.entry-input {
width: calc(100% - 20px);
margin-bottom: 10px;
padding: 8px;
border: 1px solid #3498db;
border-radius: 5px;
background-color: rgba(255, 255, 255, 0.2);
color: #ffffff;
font-family: 'Poppins', sans-serif;
font-size: 14px;
transition: all 0.3s ease;
}
.entry-input:focus {
border-color: #2ecc71;
box-shadow: 0 0 10px rgba(46, 204, 113, 0.5);
}
#spinButton {
font-size: 1.3em;
padding: 15px 30px;
cursor: pointer;
background-color: #2ecc71;
color: white;
border: none;
border-radius: 50px;
transition: all 0.3s ease;
transform-style: preserve-3d;
transform: perspective(1000px) translateZ(0);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
}
#spinButton:hover {
background-color: #27ae60;
transform: perspective(1000px) translateZ(20px) scale(1.05);
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.3);
}
#spinButton:active {
transform: perspective(1000px) translateZ(10px) scale(0.98);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
}
#result {
font-size: 1.5em;
font-weight: bold;
text-align: center;
margin-top: 20px;
color: #ffffff;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3), 0 0 10px rgba(255, 255, 255, 0.5);
}
#winnerModal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.8);
}
.modal-content {
background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d);
margin: 15% auto;
padding: 30px;
border-radius: 15px;
width: 80%;
max-width: 500px;
text-align: center;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.5);
color: #ffffff;
animation: modalAppear 0.5s ease;
}
@keyframes modalAppear {
from { opacity: 0; transform: scale(0.8); }
to { opacity: 1; transform: scale(1); }
}
.close {
color: #ffffff;
float: right;
font-size: 28px;
font-weight: bold;
cursor: pointer;
transition: color 0.3s;
}
.close:hover,
.close:focus {
color: #2ecc71;
}
.modal-button {
padding: 10px 20px;
margin: 10px;
border: none;
border-radius: 50px;
cursor: pointer;
font-size: 1em;
transition: all 0.3s;
transform-style: preserve-3d;
transform: perspective(1000px) translateZ(0);
}
#keepEntry {
background-color: #3498db;
color: white;
box-shadow: 0 5px 15px rgba(52, 152, 219, 0.4);
}
#keepEntry:hover {
background-color: #2980b9;
transform: perspective(1000px) translateZ(10px) scale(1.05);
}
#removeEntry {
background-color: #e74c3c;
color: white;
box-shadow: 0 5px 15px rgba(231, 76, 60, 0.4);
}
#removeEntry:hover {
background-color: #c0392b;
transform: perspective(1000px) translateZ(10px) scale(1.05);
}
.modal-button:active {
transform: perspective(1000px) translateZ(5px) scale(0.98);
}
.slot-controls {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}
.slot-button {
padding: 8px 15px;
border: none;
border-radius: 25px;
cursor: pointer;
font-size: 0.9em;
transition: all 0.3s;
background-color: #3498db;
color: white;
}
.slot-button:hover {
background-color: #2980b9;
transform: translateY(-2px);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
}
.slot-button:active {
transform: translateY(0);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}
.slot-button:disabled {
background-color: #95a5a6;
cursor: not-allowed;
}
.triangle {
position: absolute;
top: 50%;
right: -30px;
transform: translateY(-50%);
width: 0;
height: 0;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
border-right: 30px solid #ffffff;
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3));
}
#modeSelector {
margin-bottom: 20px;
display: flex;
justify-content: center;
gap: 20px;
}
.mode-button {
padding: 10px 20px;
border: none;
border-radius: 25px;
cursor: pointer;
font-size: 1em;
transition: all 0.3s;
background-color: #3498db;
color: white;
}
.mode-button:hover {
background-color: #2980b9;
transform: translateY(-2px);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
}
.mode-button.active {
background-color: #2ecc71;
}
.wheel-label {
text-align: center;
font-weight: bold;
margin-bottom: 10px;
}
.wheel-label-input {
font-size: 1.2em;
font-weight: bold;
color: #ffffff;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
margin: 0;
padding: 5px;
border: none;
background: none;
text-align: center;
width: 100%;
outline: none;
transition: all 0.3s ease;
}
.wheel-label-input:hover, .wheel-label-input:focus {
background-color: rgba(255, 255, 255, 0.1);
border-radius: 5px;
transform: scale(1.05);
}
</style>
</head>
<body>
<div class="title-container">
<input type="text" id="wheelTitle" value="Cryptocurrency Wheel of Fortune" maxlength="50">
</div>
<div id="modeSelector">
<button id="simpleMode" class="mode-button active">Simple</button>
<button id="doubleMode" class="mode-button">Double</button>
</div>
<div class="container">
<div class="wheels-container">
<div>
<div class="wheel-label">
<input type="text" class="wheel-label-input" id="wheelLabel1" value="Wheel 1" maxlength="20">
</div>
<div class="wheel-container">
<div class="triangle"></div>
<svg id="wheel" class="wheel" viewBox="0 0 100 100">
<!-- Wheel segments will be dynamically added here -->
</svg>
</div>
</div>
<div id="secondWheelContainer" style="display: none;">
<div class="wheel-label">
<input type="text" class="wheel-label-input" id="wheelLabel2" value="Wheel 2" maxlength="20">
</div>
<div class="wheel-container">
<div class="triangle"></div>
<svg id="wheel2" class="wheel" viewBox="0 0 100 100">
<!-- Wheel segments will be dynamically added here -->
</svg>
</div>
</div>
</div>
<div class="controls">
<div class="slot-controls">
<button id="addSlot" class="slot-button">Add Slot</button>
<button id="removeSlot" class="slot-button">Remove Slot</button>
</div>
<div id="entryList">
<!-- Entry inputs will be dynamically added here -->
</div>
<div id="entryList2" style="display: none;">
<!-- Entry inputs for second wheel will be dynamically added here -->
</div>
<button id="spinButton">Spin</button>
<div id="result"></div>
</div>
</div>
<div id="winnerModal">
<div class="modal-content">
<span class="close">×</span>
<h2>We Have a Winner!</h2>
<p id="winnerText"></p>
<button id="keepEntry" class="modal-button">Keep Entry</button>
<button id="removeEntry" class="modal-button">Remove Entry</button>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/howler/2.2.3/howler.min.js"></script>
<script>
const wheel = document.getElementById('wheel');
const wheel2 = document.getElementById('wheel2');
const spinButton = document.getElementById('spinButton');
const entryList = document.getElementById('entryList');
const entryList2 = document.getElementById('entryList2');
const result = document.getElementById('result');
const winnerModal = document.getElementById('winnerModal');
const winnerText = document.getElementById('winnerText');
const keepEntryBtn = document.getElementById('keepEntry');
const removeEntryBtn = document.getElementById('removeEntry');
const closeBtn = document.querySelector('.close');
const addSlotBtn = document.getElementById('addSlot');
const removeSlotBtn = document.getElementById('removeSlot');
const wheelTitle = document.getElementById('wheelTitle');
const simpleModeBtn = document.getElementById('simpleMode');
const doubleModeBtn = document.getElementById('doubleMode');
const secondWheelContainer = document.getElementById('secondWheelContainer');
const wheelLabel1 = document.getElementById('wheelLabel1');
const wheelLabel2 = document.getElementById('wheelLabel2');
let entries = [
'BTC',
'ETH',
'ADA',
'SOL',
'DOGE',
'QQ',
'NO',
'PEPE',
'GF',
'PANDA',
'YAYA',
'SATOSHI',
'CAT',
'ORD',
'CLOWN',
'YY',
'JUMP',
'DONALD',
'A',
'MIMI',
'MIQI',
'RABBIT',
'SHEEP',
'SNAKE',
'PEACE',
'RAT',
'MONKEY',
'DRAGON',
'X',
'SEAL',
'COW',
'OTTER',
'ORD(',
'ORD{',
'ORD%',
'ORD<'
];
let entries2 = [...entries];
let spinning = false;
let currentRotation = 0;
let currentRotation2 = 0;
let doubleMode = false;
const spinSound = new Howl({
src: ['https://assets.mixkit.co/sfx/preview/mixkit-game-ball-spin-2460.mp3'],
loop: true
});
const winSound = new Howl({
src: ['https://assets.mixkit.co/sfx/preview/mixkit-achievement-bell-600.mp3']
});
wheelTitle.addEventListener('focus', function() {
this.select();
});
wheelTitle.addEventListener('blur', function() {
if (this.value.trim() === '') {
this.value = 'Cryptocurrency Wheel of Fortune';
}
});
wheelTitle.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
e.preventDefault();
this.blur();
}
});
wheelLabel1.addEventListener('focus', function() {
this.select();
});
wheelLabel1.addEventListener('blur', function() {
if (this.value.trim() === '') {
this.value = 'Wheel 1';
}
});
wheelLabel1.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
e.preventDefault();
this.blur();
}
});
wheelLabel2.addEventListener('focus', function() {
this.select();
});
wheelLabel2.addEventListener('blur', function() {
if (this.value.trim() === '') {
this.value = 'Wheel 2';
}
});
wheelLabel2.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
e.preventDefault();
this.blur();
}
});
function updateWheel(wheelElement, entriesArray) {
wheelElement.innerHTML = '';
const segmentAngle = 360 / entriesArray.length;
entriesArray.forEach((entry, index) => {
const startAngle = index * segmentAngle;
const endAngle = (index + 1) * segmentAngle;
const midAngle = (startAngle + endAngle) / 2;
const largeArcFlag = endAngle - startAngle <= 180 ? 0 : 1;
const startX = 50 + 50 * Math.cos(Math.PI * startAngle / 180);
const startY = 50 + 50 * Math.sin(Math.PI * startAngle / 180);
const endX = 50 + 50 * Math.cos(Math.PI * endAngle / 180);
const endY = 50 + 50 * Math.sin(Math.PI * endAngle / 180);
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path.setAttribute('d', `M50,50 L${startX},${startY} A50,50 0 ${largeArcFlag},1 ${endX},${endY} Z`);
path.setAttribute('fill', `hsl(${index * 360 / entriesArray.length}, 70%, 50%)`);
wheelElement.appendChild(path);
const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
const textX = 50 + 40 * Math.cos(Math.PI * midAngle / 180);
const textY = 50 + 40 * Math.sin(Math.PI * midAngle / 180);
text.setAttribute('x', textX);
text.setAttribute('y', textY);
text.setAttribute('text-anchor', 'middle');
text.setAttribute('dominant-baseline', 'middle');
text.setAttribute('transform', `rotate(${midAngle}, ${textX}, ${textY})`);
text.textContent = entry.length > 20 ? entry.substring(0, 17) + '...' : entry;
text.style.fontSize = '3px';
text.style.fontFamily = 'Poppins, sans-serif';
text.style.fontWeight = 'bold';
text.style.fill = 'white';
wheelElement.appendChild(text);
});
}
function updateEntryList(listElement, entriesArray) {
listElement.innerHTML = '';
entriesArray.forEach((entry, index) => {
const input = document.createElement('input');
input.type = 'text';
input.value = entry;
input.className = 'entry-input';
input.maxLength = 250;
input.placeholder = `Entry ${index + 1}`;
input.addEventListener('input', (e) => {
entriesArray[index] = e.target.value;
updateWheel(listElement === entryList ? wheel : wheel2, entriesArray);
});
input.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
e.preventDefault();
if (index === entriesArray.length - 1 && entriesArray.length < 1000) {
entriesArray.push('');
updateEntryList(listElement, entriesArray);
updateWheel(listElement === entryList ? wheel : wheel2, entriesArray);
listElement.lastElementChild.focus();
} else if (index < entriesArray.length - 1) {
listElement.children[index + 1].focus();
}
}
});
listElement.appendChild(input);
});
updateSlotButtons();
}
function updateSlotButtons() {
addSlotBtn.disabled = entries.length >= 1000;
removeSlotBtn.disabled = entries.length <= 1;
}
function spin() {
if (spinning || entries.length === 0) return;
spinning = true;
spinSound.play();
const rotations = 5;
const degrees = rotations * 360 + Math.floor(Math.random() * 360);
currentRotation += degrees;
wheel.style.transform = `rotate(${currentRotation}deg)`;
if (doubleMode) {
const degrees2 = rotations * 360 + Math.floor(Math.random() * 360);
currentRotation2 += degrees2;
wheel2.style.transform = `rotate(${currentRotation2}deg)`;
}
setTimeout(() => {
spinning = false;
spinSound.stop();
winSound.play();
const winningIndex = Math.floor(((currentRotation % 360) / 360) * entries.length);
const winner = entries[entries.length - 1 - winningIndex];
if (doubleMode) {
const winningIndex2 = Math.floor(((currentRotation2 % 360) / 360) * entries2.length);
const winner2 = entries2[entries2.length - 1 - winningIndex2];
winnerText.textContent = `${wheelLabel1.value}: ${winner || 'Empty slot'}\n${wheelLabel2.value}: ${winner2 || 'Empty slot'}`;
} else {
winnerText.textContent = `${wheelLabel1.value}: ${winner || 'Empty slot'}`;
}
winnerModal.style.display = 'block';
createConfetti();
}, 5000);
}
spinButton.addEventListener('click', spin);
keepEntryBtn.addEventListener('click', () => {
winnerModal.style.display = 'none';
});
removeEntryBtn.addEventListener('click', () => {
const winningIndex = Math.floor(((currentRotation % 360) / 360) * entries.length);
entries.splice(entries.length - 1 - winningIndex, 1);
updateEntryList(entryList, entries);
updateWheel(wheel, entries);
if (doubleMode) {
const winningIndex2 = Math.floor(((currentRotation2 % 360) / 360) * entries2.length);
entries2.splice(entries2.length - 1 - winningIndex2, 1);
updateEntryList(entryList2, entries2);
updateWheel(wheel2, entries2);
}
winnerModal.style.display = 'none';
});
closeBtn.addEventListener('click', () => {
winnerModal.style.display = 'none';
});
window.addEventListener('click', (event) => {
if (event.target === winnerModal) {
winnerModal.style.display = 'none';
}
});
addSlotBtn.addEventListener('click', () => {
if (entries.length < 1000) {
entries.push('');
updateEntryList(entryList, entries);
updateWheel(wheel, entries);
entryList.lastElementChild.focus();
if (doubleMode) {
entries2.push('');
updateEntryList(entryList2, entries2);
updateWheel(wheel2, entries2);
}
}
});
removeSlotBtn.addEventListener('click', () => {
if (entries.length > 1) {
entries.pop();
updateEntryList(entryList, entries);
updateWheel(wheel, entries);
if (doubleMode) {
entries2.pop();
updateEntryList(entryList2, entries2);
updateWheel(wheel2, entries2);
}
}
});
simpleModeBtn.addEventListener('click', () => {
doubleMode = false;
simpleModeBtn.classList.add('active');
doubleModeBtn.classList.remove('active');
secondWheelContainer.style.display = 'none';
entryList2.style.display = 'none';
});
doubleModeBtn.addEventListener('click', () => {
doubleMode = true;
doubleModeBtn.classList.add('active');
simpleModeBtn.classList.remove('active');
secondWheelContainer.style.display = 'block';
entryList2.style.display = 'block';
updateEntryList(entryList2, entries2);
updateWheel(wheel2, entries2);
});
function createConfetti() {
const confettiCount = 200;
const confettiColors = ['#f39c12', '#e74c3c', '#3498db', '#2ecc71', '#9b59b6'];
for (let i = 0; i < confettiCount; i++) {
const confetti = document.createElement('div');
confetti.style.position = 'fixed';
confetti.style.width = '10px';
confetti.style.height = '10px';
confetti.style.backgroundColor = confettiColors[Math.floor(Math.random() * confettiColors.length)];
confetti.style.left = Math.random() * 100 + 'vw';
confetti.style.top = -20 + 'px';
confetti.style.borderRadius = '50%';
confetti.style.zIndex = 1000;
document.body.appendChild(confetti);
const animation = confetti.animate(
[
{ transform: 'translate3d(0, 0, 0) rotate(0deg)', opacity: 1 },
{ transform: `translate3d(${Math.random() * 200 - 100}px, 100vh, ${Math.random() * 200 - 100}px) rotate(${Math.random() * 720}deg)`, opacity: 0 }
],
{
duration: Math.random() * 3000 + 2000,
easing: 'cubic-bezier(0, .9, .57, 1)',
delay: Math.random() * 1000
}
);
animation.onfinish = () => confetti.remove();
}
}
updateEntryList(entryList, entries);
updateWheel(wheel, entries);
</script>
</body>
</html>