class WheelGame { constructor(banner, wheelSettings) { PIXI.utils.skipHello(); this.wheelImg = null; this.isStopped = false; this.wheelSettings = JSON.parse(wheelSettings).reverse(); this.timeline = ''; this.colors = ['#CE1348', '#17BEEA', '#1E478A', '#12B457', '#FECC00']; this.angle = (2 * Math.PI) / this.wheelSettings.length; this.app, this.wheel, this.background, this.result, this.myReq, this.resultRotate, this.button, this.appCtx; this.banner = banner; this.interval = 0; this.speed = 0.33; this.radius = 300; this._getResult = this._getResult.bind(this); this.startWheel = this.startWheel.bind(this); this._getInterval = this._getInterval.bind(this); this.handleCreateModal = this.openModal.bind(this); this.stop = this.stop.bind(this); this.timerCallback = this.timerCallback.bind(this); this.wheelImagePNG = null; this.isSetWheelStartTimer = false; } getWheelText(sector) { const type = sector.type; if (type === 0) { return ['Удача', 'впереди']; } else if (type === 1) { return ['Крути', 'еще']; } else if (type === 2) { return [new Intl.NumberFormat('ru-RU').format(sector.amount / 100), 'бонусов']; } else if (type === 3) { return [sector.amount / 100 + '%', 'бонусов от', 'пополнения']; } else if (type === 6) { return ['Лото', 'Бокс']; } else { return undefined; } } async createWheel() { const ctx = Object.assign(document.createElement('canvas'), { width: 600, height: 600 }).getContext('2d'); ctx.canvas.style.background = 'transparent'; ctx.translate(85, -68); ctx.rotate((15 * Math.PI) / 180); for (let i in this.wheelSettings) { const item = this.wheelSettings[i]; if (item.type === 4) { const image = await this.addImageProcess(item.picture); this.createSegment(item, i, ctx, image); } if (item.type === 6) { const image = await this.addImageProcess('https://rpo.logycom.kz/tm/static/image/wheel-lotobox.png'); this.createSegment(item, i, ctx, image); } else { this.createSegment(item, i, ctx); } } return ctx.canvas; } createSegment(item, index, ctx, image = null) { const type = item.type; const color = item.type === 6 ? '#A841E7' : this.colors[type]; const texts = this.getWheelText(item); const ang = this.angle * index; //угол секции const textIndent = 170; ctx.save(); //Сохраняем холст ctx.beginPath(); //Начинаем рисовать if (item.color) ctx.fillStyle = item.color; else ctx.fillStyle = color; ctx.moveTo(ctx.canvas.width / 2, ctx.canvas.height / 2); //Выставляем по центру. ctx.arc(ctx.canvas.width / 2, ctx.canvas.height / 2, this.radius - 10, ang, ang + this.angle); //Рисуем секцию ctx.fill(); //Заливка ctx.closePath(); if (type === 4) { ctx.beginPath(); ctx.translate(ctx.canvas.width / 2, ctx.canvas.height / 2); ctx.rotate(ang + this.angle / 2); ctx.drawImage(image, this.radius - 130, -40, 80, 80); ctx.closePath(); } else { ctx.beginPath(); ctx.translate(ctx.canvas.width / 2, ctx.canvas.height / 2); ctx.textAlign = 'left'; ctx.fillStyle = '#fff'; ctx.rotate(ang + this.angle / 2); ctx.textBaseline = 'middle'; if (type === 6) { ctx.drawImage(image, this.radius - 203, -35, 80, 80); ctx.closePath(); } if (type === 2 || type === 3) { ctx.font = 'bold 34px PantonExtra'; ctx.textBaseline = 'middle'; ctx.fillText('+', this.radius - 190, 0); } if (texts) { texts.forEach((text, index) => { if (type === 2 || type === 3) { if (index === 0) { ctx.font = 'bolder 34px PantonExtra'; texts[2] ? ctx.fillText(text, this.radius - textIndent, -10) : ctx.fillText(text, this.radius - textIndent, -10); } else if (index === 1) { ctx.font = '20px Panton'; texts[2] ? ctx.fillText(text, this.radius - textIndent, 10) : ctx.fillText(text, this.radius - textIndent, 15); } else if (index === 2) { ctx.font = '20px Panton'; ctx.fillText(text, this.radius - textIndent, 25); } } else if (type === 0 || type === 1) { ctx.font = 'bold 28px PantonExtra'; if (index === 0) { ctx.fillText(text.toUpperCase(), this.radius - textIndent, -10); } else { ctx.fillText(text.toUpperCase(), this.radius - textIndent, 20); } } else if (type === 6) { ctx.font = 'bold 28px PantonExtra'; if (index === 0) { ctx.fillText(text.toUpperCase(), this.radius - 115, -10); } else { ctx.fillText(text.toUpperCase(), this.radius - 115, 20); } } }); } ctx.closePath(); } ctx.restore(); } async init(container) { this.app = new PIXI.Application({ width: 620, height: 600, antialias: true, transparent: true, resolution: 1, }); this.app.view.style['touch-action'] = 'auto'; this.app.renderer.plugins.interaction.autoPreventDefault = false; container.insertBefore(this.app.view, document.querySelector('.wheel__start')); this._addEvent(); this.setup(); } async setup() { const imageSrc = (await this.createWheel()).toDataURL(); this.wheelImg = await this.addImageProcess(imageSrc); if (typeof this.app === 'undefined') { throw new Error('Игра не проинициализирована.'); } const base = new PIXI.BaseTexture(this.wheelImg); const wheelTexture = new PIXI.Texture(base); const wheelbgTexture = new PIXI.Texture.fromImage('https://rpo.logycom.kz/tm/static/image/wheel/wheel-bg.png', undefined, undefined, 1.0); this.wheel = new PIXI.Sprite(wheelTexture); this.bg = new PIXI.Sprite(wheelbgTexture); this.wheel.anchor.set(0.5); //Выставляем относительно осей изображение по центрку this.bg.anchor.set(0.5); this.wheel.x = this.app._options.width / 2; this.wheel.rotation = Math.random() * (Math.PI * 2); //Каждый раз рандом колеса. this.wheel.y = this.app._options.height / 2; this.bg.x = this.app._options.width / 2; this.bg.y = this.app._options.height / 2; this.timeline = { rotate: 0.5, //Задаем rotate; }; this.app.stage.addChild(this.wheel); this.app.stage.addChild(this.bg); this.app.render(); } addImageProcess(src) { return new Promise((resolve, reject) => { let img = new Image(); img.onload = () => resolve(img); img.crossOrigin = 'anonymous'; // img.onerror = reject img.src = src; }); } startWheel() { this.myReq = requestAnimationFrame(this.startWheel); // Перезапускаем анимацию this.wheel.rotation += this.speed; //Здесь задаем скорость this.limit(); } stop() { this.resultRotate = this.result.winSector * this.angle; this.resultRotate += (0.6 * Math.random() - 0.3) * this.angle; this.resultRotate += 10 * Math.PI; anime({ targets: this.wheel, rotation: this.resultRotate, duration: 3000, easing: 'easeOutQuad', complete: () => { this.isStopped = true; this.button.classList.remove('disabled'); cancelAnimationFrame(this.myReq); setTimeout(() => { this.showWheelResult(); }, 500); }, }); } limit() { while (this.wheel.rotation > 2 * Math.PI) { //Когда значение больше уменьшаем до нормального. this.wheel.rotation -= 2 * Math.PI; } } async _getResult() { this.button.setAttribute('disabled', true); this.button.classList.add('disabled'); this.result = await fetch('https://rpo.logycom.kz/tm/threemen.dll/srv?srv=WheelGetWin&tmUserId=' + getCookie('tmUserId')) .then(res => res.text()) .then(res => { let msg = uparams(res); if (msg['status'] !== 'OK') { showError(msg['msg'] ? msg['msg'] : 'Что-то пошло не так'); return false; } return msg; }); if (this.result) { if (this.isStopped) { //Это для того чтобы начало движения если повторно крутят было с того же места. this.timeline = { rotate: this.wheel.rotation, }; } this.isStopped = false; this.startWheel(); setTimeout(() => { this.stop(); }, 3000); } } async _getInterval(element) { if (istmUserId()) { wheelInterval = await fetch('https://rpo.logycom.kz/tm/threemen.dll/srv?srv=WheelIntervalRefresh') .then(res => res.text()) .then(res => { let msg = uparams(res); if (msg['status'] !== 'OK') { showError(msg['msg'] ? msg['msg'] : 'Что-то пошло не так'); return false; } return msg.wheelInterval; }); this.interval = wheelInterval; if (this.interval > 0) { element.classList.remove('button-yellow'); element.classList.add('wheel__blocked-button'); element.setAttribute('disabled', true); } this.setTimer(this.button, this.timerCallback, this.interval); } } async showWheelResult() { disableScroll(); const setWin = await fetch('https://rpo.logycom.kz/tm/threemen.dll/srv?srv=WheelSetWin&tmUserId=' + getCookie('tmUserId')) .then(res => res.text()) .then(res => { let msg = uparams(res); if (msg['status'] !== 'OK') { showError(msg['msg'] ? msg['msg'] : 'Что-то пошло не так'); return false; } return msg; }); if (this.result.winHeader != '') { this._closeModal(); $('body').append(`
${this.result.winPicture ? `${this.result.winHeader}
${this.result.winText}
${this.result.winPicture ? 'Перейти в профиль' : 'Перейти в кошелек' }${getChancesTitle(chance.type, chance.name)}
${chance.prob}%
${chance.maxAmount ? chance.maxAmount + ` ` : ""}
${chance.name}
${chance.prob}%
${chance.maxAmount ? chance.maxAmount + ` ` : ""}
${lotobox.title} ${lotobox.quantity}