| | <!DOCTYPE html> |
| | <html lang="en"> |
| | <head> |
| | <meta charset="UTF-8"> |
| | <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| | <title>Wheel of Fortune</title> |
| | <style> |
| | body { |
| | display: flex; |
| | justify-content: center; |
| | align-items: center; |
| | height: 100vh; |
| | background-color: black; |
| | color: white; |
| | font-family: Arial, sans-serif; |
| | } |
| | |
| | .container { |
| | text-align: center; |
| | } |
| | |
| | #wheelOfFortune { |
| | border: 2px solid #f82; |
| | border-radius: 10px; |
| | padding: 20px; |
| | margin-bottom: 20px; |
| | } |
| | |
| | #wheel { |
| | border: 2px solid #f82; |
| | border-radius: 50%; |
| | } |
| | |
| | #spin { |
| | margin-top: 20px; |
| | padding: 10px 20px; |
| | border: 2px solid #f82; |
| | border-radius: 5px; |
| | background-color: black; |
| | color: white; |
| | cursor: pointer; |
| | transition: background-color 0.3s; |
| | } |
| | |
| | #spin:hover { |
| | background-color: #f82; |
| | } |
| | |
| | #registrationForm { |
| | display: none; |
| | background-color: black; |
| | padding: 30px; |
| | border: 2px solid #f82; |
| | border-radius: 10px; |
| | text-align: center; |
| | width: 90%; |
| | max-width: 400px; |
| | } |
| | |
| | #registrationForm h1 { |
| | color: #f82; |
| | margin-bottom: 20px; |
| | } |
| | |
| | #registrationForm input[type="text"], |
| | #registrationForm input[type="email"], |
| | #registrationForm input[type="tel"] { |
| | width: calc(100% - 22px); |
| | padding: 10px; |
| | margin-bottom: 10px; |
| | border: 2px solid #f82; |
| | border-radius: 5px; |
| | background-color: black; |
| | color: lightgray; |
| | } |
| | |
| | #registrationForm input[type="checkbox"] { |
| | margin-right: 5px; |
| | } |
| | |
| | #registrationForm button { |
| | width: 100%; |
| | padding: 15px; |
| | border: none; |
| | border-radius: 5px; |
| | background-color: #f82; |
| | color: black; |
| | font-weight: bold; |
| | cursor: pointer; |
| | transition: background-color 0.3s; |
| | } |
| | |
| | #registrationForm button:hover { |
| | background-color: #ff9900; |
| | } |
| | |
| | @media (max-width: 600px) { |
| | #registrationForm { |
| | width: 95%; |
| | } |
| | } |
| | </style> |
| | </head> |
| | <body> |
| | <div class="container"> |
| | <div id="wheelOfFortune"> |
| | <h1>Ирина Дель Соль</h1> |
| | <canvas id="wheel" width="300" height="300"></canvas> |
| | <div id="spin">Пуск</div> |
| | <p>Текст под колесом</p> |
| | <a href="#">Ссылка под колесом</a> |
| | </div> |
| |
|
| | |
| | <div id="registrationForm" style="display: none;"> |
| | <h1>Ирина Дель Соль</h1> |
| | <form id="registration"> |
| | <input type="text" id="name" name="name" placeholder="Ваше имя" required><br> |
| | <input type="email" id="email" name="email" placeholder="Ваш email" required><br> |
| | <input type="tel" id="phone" name="phone" placeholder="Ваш телефон" required><br> |
| | <label><input type="checkbox" id="newsletter" name="newsletter"> Согласен на рассылку</label><br> |
| | <label><input type="checkbox" id="privacyPolicy" name="privacyPolicy" required> Знаком с политикой конфиденциальности</label><br> |
| | <button type="submit">Зарегистрироваться</button> |
| | </form> |
| | <p>Текст под формой</p> |
| | <a href="#">Ссылка под формой</a> |
| | </div> |
| | </div> |
| |
|
| | <script> |
| | const sectors = [ |
| | { color: '#f82', label: 'VIP', probability: 94 }, |
| | { color: '#0bf', label: '10', probability: 1 }, |
| | { color: '#fb0', label: '200', probability: 1 }, |
| | { color: '#0fb', label: '50', probability: 1 }, |
| | { color: '#b0f', label: '100', probability: 1 }, |
| | { color: '#f0b', label: '5', probability: 1 }, |
| | { color: '#bf0', label: '500', probability: 1 } |
| | ]; |
| | const rand = (m, M) => Math.random() * (M - m) + m; |
| | const tot = sectors.length; |
| | const spinEl = document.querySelector('#spin'); |
| | const ctx = document.querySelector('#wheel').getContext('2d'); |
| | const dia = ctx.canvas.width; |
| | const rad = dia / 2; |
| | const PI = Math.PI; |
| | const TAU = 2 * PI; |
| | const arc = TAU / sectors.length; |
| | const friction = 0.991; |
| | let angVel = 0; |
| | let ang = 0; |
| | const getIndex = () => Math.floor(tot - (ang / TAU) * tot) % tot; |
| | function drawSector(sector, i) { |
| | const ang = arc * i; |
| | ctx.save(); |
| | |
| | ctx.beginPath(); |
| | ctx.fillStyle = sector.color; |
| | ctx.moveTo(rad, rad); |
| | ctx.arc(rad, rad, rad, ang, ang + arc); |
| | ctx.lineTo(rad, rad); |
| | ctx.fill(); |
| | |
| | ctx.translate(rad, rad); |
| | ctx.rotate(ang + arc / 2); |
| | ctx.textAlign = 'right'; |
| | ctx.fillStyle = '#fff'; |
| | ctx.font = 'bold 21px sans-serif'; |
| | ctx.fillText(sector.label, rad - 10, 10); |
| | |
| | ctx.restore(); |
| | } |
| | function rotate() { |
| | const sector = sectors[getIndex()]; |
| | ctx.canvas.style.transform = `rotate(${ang - PI / 2}rad)`; |
| | spinEl.textContent = !angVel ? 'Удача!' : sector.label; |
| | spinEl.style.background = sector.color; |
| | } |
| | function frame() { |
| | if (!angVel) return; |
| | angVel *= friction; |
| | if (angVel < 0.002) { |
| | angVel = 0; |
| | const sector = sectors[getIndex()]; |
| | localStorage.setItem('hasSpun', 'true'); |
| | console.log('Result:', sector.label); |
| | showRegistrationForm(); |
| | } |
| | ang += angVel; |
| | ang %= TAU; |
| | rotate(); |
| | } |
| | function engine() { |
| | frame(); |
| | requestAnimationFrame(engine); |
| | } |
| | function init() { |
| | if (!localStorage.getItem('hasSpun')) { |
| | localStorage.setItem('hasSpun', 'false'); |
| | } |
| | sectors.forEach(drawSector); |
| | rotate(); |
| | engine(); |
| | spinEl.addEventListener('click', () => { |
| | if (localStorage.getItem('hasSpun') === 'false') { |
| | localStorage.setItem('hasSpun', 'true'); |
| | angVel = rand(0.25, 0.45); |
| | spinWheel(); |
| | } else { |
| | console.log('You have already spun the wheel.'); |
| | } |
| | }); |
| | } |
| | function spinWheel() { |
| | const probabilities = sectors.map(sector => sector.probability); |
| | const totalProbability = probabilities.reduce((a, b) => a + b, 0); |
| | const random = Math.random() * totalProbability; |
| | let cumulativeProbability = 0; |
| | for (let i = 0; i < sectors.length; i++) { |
| | cumulativeProbability += sectors[i].probability; |
| | if (random < cumulativeProbability) { |
| | ang = (i + 0.5) * arc; |
| | break; |
| | } |
| | } |
| | } |
| | function showRegistrationForm() { |
| | const wheelOfFortune = document.getElementById('wheelOfFortune'); |
| | const registrationForm = document.getElementById('registrationForm'); |
| | wheelOfFortune.style.display = 'none'; |
| | registrationForm.style.display = 'block'; |
| | } |
| | window.onload = init; |
| | </script> |
| | </body> |
| | </html> |