psy4 / koleso.html
DmitrMakeev's picture
Update koleso.html
93ac4fe verified
raw
history blame
4.23 kB
<!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>
* {
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>
<script>
const sectors = [
{ color: '#f82', label: 'Stack', probability: 10 },
{ color: '#0bf', label: '10', probability: 20 },
{ color: '#fb0', label: '200', probability: 15 },
{ color: '#0fb', label: '50', probability: 20 },
{ color: '#b0f', label: '100', probability: 15 },
{ color: '#f0b', label: '5', probability: 10 },
{ color: '#bf0', label: '500', probability: 10 }
]
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 // 0.995=soft, 0.99=mid, 0.98=hard
let angVel = 0 // Angular velocity
let ang = 0 // Angle in radians
const getIndex = () => Math.floor(tot - (ang / TAU) * tot) % tot
function drawSector(sector, i) {
const ang = arc * i
ctx.save()
// COLOR
ctx.beginPath()
ctx.fillStyle = sector.color
ctx.moveTo(rad, rad)
ctx.arc(rad, rad, rad, ang, ang + arc)
ctx.lineTo(rad, rad)
ctx.fill()
// TEXT
ctx.translate(rad, rad)
ctx.rotate(ang + arc / 2)
ctx.textAlign = 'right'
ctx.fillStyle = '#fff'
ctx.font = 'bold 21px sans-serif' // Уменьшенный размер шрифта на 30%
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 ? 'SPIN' : sector.label
spinEl.style.background = sector.color
}
function frame() {
if (!angVel) return
angVel *= friction // Decrement velocity by friction
if (angVel < 0.002) {
angVel = 0 // Bring to stop
const sector = sectors[getIndex()]
localStorage.setItem('hasSpun', 'true')
console.log('Result:', sector.label)
}
ang += angVel // Update angle
ang %= TAU // Normalize angle
rotate()
}
function engine() {
frame()
requestAnimationFrame(engine)
}
function init() {
if (!localStorage.getItem('hasSpun')) {
localStorage.setItem('hasSpun', 'false')
}
sectors.forEach(drawSector)
rotate() // Initial rotation
engine() // Start 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
}
}
}
init()
</script>
</body>
</html>