|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<title>Spin N Win</title> |
|
|
|
<link rel="stylesheet" href="https://huggingface.co/spaces/DMTuit/psy4/resolve/main/css/main.css"> |
|
<script src="https://huggingface.co/spaces/DMTuit/psy4/resolve/main/js/main.js"></script> |
|
|
|
<style> |
|
|
|
body { |
|
background-color: black; |
|
color: white; |
|
font-family: Arial, sans-serif; |
|
display: flex; |
|
justify-content: center; |
|
align-items: center; |
|
height: 100vh; |
|
margin: 0; |
|
padding: 0; |
|
} |
|
|
|
#wheelOfFortune { |
|
display: flex; |
|
flex-direction: column; |
|
align-items: center; |
|
justify-content: center; |
|
} |
|
|
|
#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: 20px; |
|
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: 10px; |
|
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%; |
|
} |
|
} |
|
|
|
|
|
|
|
* { |
|
margin: 0; |
|
padding: 0; |
|
box-sizing: border-box; |
|
} |
|
|
|
body { |
|
height: 100vh; |
|
display: grid; |
|
place-items: center; |
|
} |
|
|
|
#wheelOfFortune { |
|
display: inline-block; |
|
position: relative; |
|
overflow: hidden; |
|
} |
|
|
|
#wheel { |
|
display: block; |
|
} |
|
|
|
#spin { |
|
font: 1.5em/0 sans-serif; |
|
user-select: none; |
|
cursor: pointer; |
|
display: flex; |
|
justify-content: center; |
|
align-items: center; |
|
position: absolute; |
|
top: 50%; |
|
left: 50%; |
|
width: 30%; |
|
height: 30%; |
|
margin: -15%; |
|
background: #fff; |
|
color: #fff; |
|
box-shadow: 0 0 0 8px currentColor, 0 0px 15px 5px rgba(0, 0, 0, 0.6); |
|
border-radius: 50%; |
|
transition: 0.8s; |
|
} |
|
|
|
#spin::after { |
|
content: ''; |
|
position: absolute; |
|
top: -17px; |
|
border: 10px solid transparent; |
|
border-bottom-color: currentColor; |
|
border-top: none; |
|
} |
|
|
|
|
|
|
|
|
|
</style> |
|
|
|
|
|
|
|
</head> |
|
|
|
<body> |
|
<div id="wheelOfFortune"> |
|
<canvas id="wheel" width="300" height="300"></canvas> |
|
<div id="spin">Пуск</div> |
|
</div> |
|
|
|
|
|
<div id="registrationForm" style="display: none;"> |
|
<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> |
|
</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> |
|
|