<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>매일매일 행운 룰렛</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Noto+Sans+KR', sans-serif;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
margin: 0;
overflow-x: hidden;
}
.roulette-container {
position: relative;
width: 320px;
height: 320px;
margin: 0 auto;
}
#wheel {
width: 100%;
height: 100%;
border-radius: 50%;
border: 8px solid #fff;
box-shadow: 0 10px 25px rgba(0,0,0,0.2);
transition: transform 4s cubic-bezier(0.15, 0, 0.15, 1);
position: relative;
overflow: hidden;
}
.pointer {
position: absolute;
top: -20px;
left: 50%;
transform: translateX(-50%);
width: 40px;
height: 40px;
background: #ff4757;
clip-path: polygon(50% 100%, 0 0, 100% 0);
z-index: 10;
}
.center-pin {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 20px;
height: 20px;
background: white;
border-radius: 50%;
box-shadow: 0 0 10px rgba(0,0,0,0.3);
z-index: 5;
}
.confetti {
position: absolute;
width: 10px;
height: 10px;
background-color: #f00;
opacity: 0;
}
@keyframes confetti-fall {
0% { transform: translateY(-100vh) rotate(0deg); opacity: 1; }
100% { transform: translateY(100vh) rotate(720deg); opacity: 0; }
}
.result-box {
opacity: 0;
transform: scale(0.8);
transition: all 0.5s ease-out;
}
.result-box.show {
opacity: 1;
transform: scale(1);
}
</style>
</head>
<body class="p-4">
<div class="bg-white p-8 rounded-3xl shadow-2xl max-w-md w-full text-center">
<h1 class="text-3xl font-bold text-indigo-600 mb-2">🍀 행운 룰렛 🍀</h1>
<p class="text-gray-500 mb-8 text-sm">돌리기만 하면 무조건 행운이 터집니다!</p>
<div class="roulette-container mb-8">
<div class="pointer"></div>
<div class="center-pin"></div>
<canvas id="wheel"></canvas>
</div>
<button id="spinBtn" class="w-full bg-indigo-600 hover:bg-indigo-700 text-white font-bold py-4 rounded-2xl text-xl transition-all active:scale-95 shadow-lg">
행운 돌리기!
</button>
<div id="resultBox" class="result-box mt-8 p-4 rounded-xl bg-indigo-50 border-2 border-indigo-200">
<h2 class="text-lg font-bold text-gray-700">오늘의 행운 메시지</h2>
<p id="resultText" class="text-2xl font-black text-indigo-600 mt-2">행운을 빕니다!</p>
</div>
</div>
<script>
const canvas = document.getElementById('wheel');
const ctx = canvas.getContext('2d');
const spinBtn = document.getElementById('spinBtn');
const resultBox = document.getElementById('resultBox');
const resultText = document.getElementById('resultText');
const rewards = [
"대박운 폭발!", "초특급 행운", "기분좋은 일",
"금전운 상승", "사랑 가득", "건강 에너지",
"뜻밖의 선물", "완벽한 하루"
];
const colors = [
"#FF6B6B", "#FFD93D", "#6BCB77", "#4D96FF",
"#9B59B6", "#FF9F43", "#1DD1A1", "#54A0FF"
];
let currentRotation = 0;
let isSpinning = false;
// 캔버스 초기화 (Retina 대응)
const size = 320;
canvas.width = size;
canvas.height = size;
function drawWheel() {
const centerX = size / 2;
const centerY = size / 2;
const radius = size / 2;
const sliceAngle = (2 * Math.PI) / rewards.length;
ctx.clearRect(0, 0, size, size);
rewards.forEach((reward, i) => {
const angle = i * sliceAngle;
// 조각 그리기
ctx.beginPath();
ctx.fillStyle = colors[i];
ctx.moveTo(centerX, centerY);
ctx.arc(centerX, centerY, radius, angle, angle + sliceAngle);
ctx.fill();
// 텍스트 그리기
ctx.save();
ctx.translate(centerX, centerY);
ctx.rotate(angle + sliceAngle / 2);
ctx.textAlign = "right";
ctx.fillStyle = "white";
ctx.font = "bold 14px Noto Sans KR";
ctx.fillText(reward, radius - 15, 5);
ctx.restore();
});
}
function createConfetti() {
for (let i = 0; i < 50; i++) {
const confetti = document.createElement('div');
confetti.className = 'confetti';
confetti.style.left = Math.random() * 100 + 'vw';
confetti.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)];
confetti.style.opacity = '1';
confetti.style.animation = `confetti-fall ${Math.random() * 2 + 1}s linear forwards`;
document.body.appendChild(confetti);
setTimeout(() => confetti.remove(), 3000);
}
}
function spin() {
if (isSpinning) return;
isSpinning = true;
resultBox.classList.remove('show');
// 무작위 회전 수 (최소 5바퀴 이상)
const extraDegrees = Math.floor(Math.random() * 360);
const totalDegrees = 1800 + extraDegrees;
currentRotation += totalDegrees;
canvas.style.transform = `rotate(${currentRotation}deg)`;
// 애니메이션이 끝난 후 (4초)
setTimeout(() => {
isSpinning = false;
// 결과 계산
const actualDegrees = currentRotation % 360;
// 룰렛은 시계방향으로 돌지만, 인덱스 계산은 역방향 기준 보정 필요
// 포인터가 상단(270도 지점)에 있다고 가정
const sliceAngle = 360 / rewards.length;
const index = Math.floor(((360 - actualDegrees % 360) + 270) % 360 / sliceAngle);
resultText.innerText = `✨ ${rewards[index]} ✨`;
resultBox.classList.add('show');
createConfetti();
}, 4000);
}
spinBtn.addEventListener('click', spin);
// 초기 휠 그리기
drawWheel();
</script>
</body>
</html>
댓글
댓글 쓰기