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 ? ` ` : ` ` } `); $('.wheel__bg, .lotobox-popup__close').on('click', () => { $('.wheel__bg').remove(); $('.modal__wheel-result').remove(); enableScroll(); }); } this.interval = setWin.wheelInterval; if (this.interval == 0) { this.button.classList.add('button-yellow'); this.button.classList.remove('disabled'); this.button.removeAttribute('disabled'); } else if (this.interval > 0) { const timerButtons = checkMobileDevice() ? document.querySelectorAll('.wheel__banner-button-mobile') : document.querySelectorAll('.wheel__banner-button'); timerButtons.forEach(timerButton => { this.setGrayScale(timerButton) timerButton.classList.add('waiting'); this._removeHandleModalOpen(); this.setTimer(timerButton, () => { this.removeGrayScale(timerButton) timerButton.classList.remove('waiting'); timerButton.classList.add('enabled'); timerButton.textContent = 'крутить'; this.createModal(); }); }); this.setTimer(this.button, this.timerCallback); this.button.classList.remove('button-yellow'); this.button.classList.add('wheel__blocked-button'); this.removeBannerModalOpen(document.querySelector('#anotherWheelBanner')); } } setGrayScale(element) { if (element.classList.contains('wheel__banner-button')) { element.previousElementSibling.classList.add('waitingGrayScale'); } } removeGrayScale(element) { if (element.classList.contains('wheel__banner-button')) { element.previousElementSibling.classList.remove('waitingGrayScale'); } } _addEvent() { this.button.addEventListener('click', this._getResult); } _removeEvent() { this.button.removeEventListener('click', this._getInterval); } handleModalOpen() { this.banner && this.banner.addEventListener('click', this.handleCreateModal); } handeBannerModalOpen(banner) { banner && banner.addEventListener('click', this.handleCreateModal); } removeBannerModalOpen(banner) { banner && banner.removeEventListener('click', this.handleCreateModal); } _removeHandleModalOpen() { this.banner && this.banner.removeEventListener('click', this.handleCreateModal); } _setWheel() { let container = document.querySelector('.modal__wheelInner'); if (istmUserId()) { this.init(container); } } _checkWheel() { if (istmUserId()) return this.app ? true : false; else return this.wheelImagePNG ? true : false; } async openModal() { disableScroll(); await $.ajax({ url: 'https://rpo.logycom.kz/tm/threemen.dll/srvNew', type: 'POST', data: { srv: 'wheelInfo' }, dataType: 'text', success: function () { }, error: function () { }, complete: function (data) { $('#wheelProbsContainer').html(''); $('#wheelLotoboxRewars').html(''); let msg = JSON.parse(data.responseText); if (msg["status"] !== "OK") { showError(msg['msg'] ? msg['msg'] : 'Что-то пошло не так'); return; } $('.modal__contents').hide(); (msg && msg.wheel) ? msg.wheel.forEach((chance, idx) => { let template = ''; if ((idx + 1) % 2) { template = `
${sectionBall(chance.type, chance.name)}

${getChancesTitle(chance.type, chance.name)}

${chance.prob}%

${chance.maxAmount ? chance.maxAmount + ` ` : ""}

` } else { template = `
${sectionBall(chance.type, chance.name)}

${chance.name}

${chance.prob}%

${chance.maxAmount ? chance.maxAmount + ` ` : ""}

` } $('#wheelProbsContainer').append(template); }) : ''; (msg && msg.lotoBox) ? msg.lotoBox.forEach(lotobox => { let template = `
lotobox

${lotobox.title}   ${lotobox.quantity}

`; $('#wheelLotoboxRewars').append(template); }) : ""; } }) window.addEventListener("resize", () => { resize(".modal__contents") }) $('.modal__contents').fadeIn(280) resize(".modal__contents"); $('.modal__wheelScroll').click(() => { // console.log("sdsadasdas") // document.querySelector('.modal__main').scrollTo({top: document.querySelector(".modal__main").scrollHeight, behavior: "smooth"}) document.querySelector('.modal__main').scrollTop = document.querySelector('.modal__main').scrollHeight; }) $('#wheelModalToTop').on('click', () => { if (!istmUserId()) { location.href = "https://rpo.logycom.kz/tm/threemen.dll/login" } else { document.querySelector('.modal__main').scrollTo(0, 0) } }) $('.modal, .modal__close-wheel, .modal__close-mobile, .modal__topCloseBtn').click(event => this._closeModal(true)); $('.wheel__bg-modal').fadeIn(280); const iosVer = checkIOS(); if (iosVer && iosVer[0] < 15) { $('body').addClass('modal__is-openedIOS14'); } this.button = document.querySelector('.wheel__start'); if (!this.isSetWheelStartTimer) this._getInterval(this.button) if (!this._checkWheel()) this._setWheel() if (!istmUserId()) { const imageSrc = (await this.createWheel()).toDataURL(); const wheelImage = document.querySelector('.wheelImagePNG') wheelImage.src = imageSrc; wheelImage.style.width = '300px'; wheelImage.style.height = '300px'; $('.wheel__logo-img').css({ opacity: 0.5 }); } } _closeModal(scrollOff) { $('.wheel__bg-modal').fadeOut(280); $(".modal__contents").fadeOut(200); clearInterval(this.interval); this._removeEvent(); $('.modal').fadeOut(200, '', () => { if (scrollOff) enableScroll(); const iosVer = checkIOS(); if (iosVer && iosVer[0] < 15) { $('body').removeClass('modal__is-openedIOS14'); } }); } timerCallback() { if (this.button) { this.button.textContent = 'Крутить'; this.button.classList.remove('wheel__blocked-button'); this.button.classList.add('button-yellow'); this.button.removeAttribute('disabled'); } } setTimer(element, callback, interval = false, exTimer) { let sec = interval || this.interval; let hours, minutes, seconds; let timer = exTimer; if (element.classList.contains('wheel__start') && this.isSetWheelStartTimer) { console.log('wtf'); return; } if (interval === "-1") { element.textContent = "Недоступно" return; } timer = setInterval(() => { if (sec == 0) { wheelInterval = 0; this.isSetWheelStartTimer = false; clearInterval(timer); if (typeof callback === 'function') { callback(element); } this.handeBannerModalOpen(document.querySelector('#anotherWheelBanner')); return; } hours = Math.floor(sec / 3600); //делаем час minutes = Math.floor((sec % 3600) / 60); //делаем минуты seconds = sec % 60; //секунды if (minutes.toString().length == 1) { // добавляем нули minutes = '0' + minutes; } if (hours.toString().length == 1) { hours = '0' + hours; } if (element[1]) { element.forEach(item => { if (hours != 0) { //Если в часах не 0, то отображаем с часами. item.innerHTML = `через  ${hours}:${minutes}`; } else { item.innerHTML = `через  ${minutes}:${seconds.toString().length == 1 ? '0' : ''}${seconds}`; } }); } else { if (hours != 0) { //Если в часах не 0, то отображаем с часами. element.innerHTML = `через  ${hours}:${minutes}`; } else { element.innerHTML = `через  ${minutes}:${seconds.toString().length == 1 ? '0' : ''}${seconds}`; } } sec--; }, 1000); } } let wheelGame; if (wheelSettings) { wheelGame = checkMobileDevice() ? new WheelGame(document.querySelector('.wheel__banner_mobile') || null, wheelSettings) : new WheelGame(document.querySelector('.wheel__banner') || null, wheelSettings); } [{ "type": 3, "amount": 2000, "color": "#034452", "prob": 5000 }, { "type": 6, "color": "#df7a1b", "prob": 50000 }, { "type": 3, "amount": 1500, "color": "#034452", "prob": 10000 }, { "type": 6, "color": "#df7a1b", "prob": 50000 }, { "type": 0, "color": "#002B31", "prob": 500 }, { "type": 1, "color": "#E3B586", "prob": 10000 }, { "type": 3, "amount": 1000, "color": "#0000FF", "prob": 150000 }, { "type": 6, "color": "#df7a1b", "prob": 50000 }, { "type": 3, "amount": 500, "color": "#0000FF", "prob": 614000 }, { "type": 6, "color": "#df7a1b", "prob": 50000 }, { "type": 0, "color": "#002B31", "prob": 500 }, { "type": 1, "color": "#E3B586", "prob": 10000 }] [{"type":0,"name":"лотобокс","prob":"20,000"},{"type":1,"name":"5%","prob":"62,150"},{"type":1,"name":"10%","prob":"10,000"},{"type":1,"name":"15%","prob":"1,000"},{"type":1,"name":"20%","prob":"0,500"},{"type":2,"name":"крути еще!","prob":"5,350"},{"type":3,"name":"удача впереди","prob":"1,000"}]