Files
quayso.sisvietnam.vn/resources/views/frontend/game/luckywheel.blade.php
T

392 lines
17 KiB
PHP

<link rel="stylesheet" href="{{asset('/public/frontend/css/game.css?version=2.4')}}" />
<div class="row chart_containter">
<div class="col-lg-6 col-md-6 ribbon">
<div class="wrap">
<span class="ribbon6" id="game_rule" data-toggle="modal" data-target="#ruleModal">Thể lệ tham dự</span>
</div>
@if(Session::has('success'))
<div class="alert alert-success">
{{ Session::get('success') }}
@php
Session::forget('success');
@endphp
</div>
@endif
@if(Session::has('error'))
<div class="alert alert-danger">
{{ Session::get('error') }}
@php
Session::forget('error');
@endphp
</div>
@endif
@if(Session::has('errors'))
<div class="alert alert-danger">
{{ 'Có lỗi xảy ra (' . implode(', ', $errors->all(':message')) . ')'}}
@php
Session::forget('errors');
@endphp
</div>
@endif
<div id="luckywheel_container">
<div class="luckywheel_inner" style="margin-top: 1rem;">
<div class="luckywheel_inner" style="background-color: #950000;
box-shadow: inset 6px -6px 20px #000;">
<div class="wheel-section">
<div class="wheel-container">
<div class="wheel-border-lights">
<canvas id="wheelCanvas" width="600" height="600"></canvas>
</div>
</div>
</div>
<div class="cylinder_container">
<div class="cylinder2"></div>
<div class="cylinder"></div>
</div>
<button id="spinButton" style="display: block;"
data-check="{{ Auth::check() && $spined == 0 ? 'true' : 'false' }}"
data-auth="{{ Auth::check() ? 'true' : 'false' }}"
data-spined="{{ $spined ?? 0 }}">BẮT ĐẦU
QUAY
</button>
<!-- Debug: Auth={{ Auth::check() ? 'YES' : 'NO' }} Spined={{ $spined ?? 0 }} -->
</div>
</div>
</div>
</div>
<div class="col-lg-6 col-md-6 slogan">
<div class="custom_title text-center" style="{{ !Auth::check() || $spined == 1 ? 'position: absolute;' : '' }};">
<span>VÒNG QUAY MAY MẮN</span>
</div>
<div class="logo-container">
<img class="logo" src="{{asset('/public/frontend/imgs/LogoSIS.png')}}" alt="Your Company Logo">
</div>
<div class="demonstration_img">
@if (isset($parameter_data['banner_image']) && $parameter_data['banner_image'] != '')
<img src="{{asset('/public/images/' . $parameter_data['banner_image'])}}" alt="Demonstration img">
@else
<img src="{{asset('/public/frontend/imgs/luckywheel_winner.avif')}}" alt="Demonstration img">
@endif
</div>
</div>
@if (!$is_login || $spined == 1)
<section class="alert_wheel_spin">
<div class="alert fade alert-simple alert-danger alert-dismissible text-left font__family-montserrat font__size-16 font__weight-light brk-library-rendered rendered show"
role="alert" data-brk-library="component__alert">
<button type="button" class="close font__size-18" data-dismiss="alert">
<span aria-hidden="true">
<i class="fa fa-times danger "></i>
</span>
<span class="sr-only">Close</span>
</button>
<i class="start-icon far fa-times-circle faa-pulse animated"></i>
<strong class="font__weight-semibold">Thông báo: </strong>
@if (!$is_login)
<div class="alert alert-danger text-center" style="width: 100%; margin: auto;">
Vui lòng <a class="btn btn-danger custom_btn" href="{{ route('login') }}">Nhập thông tin</a> để thể
quay số
trúng giải
</div>
@endif
@if ($spined == 1)
<div class="alert alert-danger text-center prize_alert">
Bạn chỉ được phép quay 1 lần,
giải thưởng gần nhất <b>
<h2>{{ $lasted_prize_name ?? '' }}</h2>
</b>
</div>
@endif
</div>
</section>
@endif
<div id="result"></div>
</div>
@include('frontend.game.customprize_popup')
@include('frontend.game.rule')
<script>
$('#game_rule').on('click', function () {
$('#gamerule').html('');
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
var url = "{{route('game/rule')}}";
$.ajax({
// dataType: 'json',
url: url,
type: 'GET',
contentType: false,
processData: false,
success: function (result) {
$('#gamerule').html(result);
}
});
});
const canvas = document.getElementById("wheelCanvas");
const ctx = canvas.getContext("2d");
const spinButton = document.getElementById("spinButton");
const segmentsInput = document.getElementById("segments");
const resultDiv = document.getElementById("result");
let game_data = "{{json_encode($game_data)}}";
var data = JSON.parse(game_data.replace(/&quot;/g, '"'));
let segments = [];
let prize_ids = [];
const images = [];
data.forEach(item => {
segments.push(item.detail);
prize_ids.push(item.id);
const img = new Image();
img.src = item.image; // Đảm bảo 'item' chứa URL của ảnh
images.push(img);
});
// Tableau de couleurs avec leurs configurations
const colorSchemes = [{
bg: "#e30a00",
text: "#fff"
}, // Bleu foncé
{
bg: "#fff",
text: "#e30a00"
}, {
bg: "#e30a00",
text: "#fff"
}, // Bleu foncé
{
bg: "#fff",
text: "#e30a00"
}, {
bg: "#e30a00",
text: "#fff"
}, // Bleu foncé
{
bg: "#fff",
text: "#e30a00"
}, {
bg: "#e30a00",
text: "#fff"
}, // Bleu foncé
{
bg: "#fff",
text: "#e30a00"
}, {
bg: "#e30a00",
text: "#fff"
}, // Bleu foncé
{
bg: "#fff",
text: "#e30a00"
}
];
// Dimensions du canvas
const width = 600; // Tăng chiều rộng
const height = 600;
canvas.width = width; // Cập nhật kích thước canvas
canvas.height = height;
// Variables pour l'animation
let currentAngle = 0; // angle de départ
let spinVelocity = 0; // vitesse de rotation
let isSpinning = false; // indicateur d'animation en cours
// Fonction pour dessiner la roue
function drawWheel(segmentsArray) {
ctx.clearRect(0, 0, width, height);
const numSegments = segmentsArray.length;
const anglePerSegment = (2 * Math.PI) / numSegments;
const centerX = width / 2;
const centerY = height / 2;
const radius = Math.min(width, height) / 2;
for (let i = 0; i < numSegments; i++) {
const startAngle = currentAngle + i * anglePerSegment - Math.PI / 2;
const endAngle = startAngle + anglePerSegment;
const colorScheme = colorSchemes[i % colorSchemes.length];
// Vẽ nền của phân đoạn
ctx.beginPath();
ctx.moveTo(centerX, centerY);
ctx.arc(centerX, centerY, radius, startAngle, endAngle);
ctx.fillStyle = colorScheme.bg;
ctx.fill();
ctx.closePath();
// BẮT ĐẦU: Vẽ ảnh TRƯỚC chữ để chữ nằm trên ảnh
if (images[i] && images[i].complete && images[i].naturalWidth > 0 && images[i].naturalHeight > 0) { // Kiểm tra ảnh đã tải xong và không bị lỗi
ctx.save(); // Lưu trạng thái hiện tại của canvas
const imageSize = 100; // Kích thước ảnh
const distanceFromCenter = radius * 0.65; // Khoảng cách từ tâm vòng quay ra vị trí ảnh
// Tính toán góc chính giữa của phân đoạn hiện tại
const angleOfSegmentCenter = startAngle + anglePerSegment / 2;
// Tính toán vị trí tâm của ảnh trên vòng quay (nếu không xoay)
const imageCenterX = centerX + Math.cos(angleOfSegmentCenter) * distanceFromCenter;
const imageCenterY = centerY + Math.sin(angleOfSegmentCenter) * distanceFromCenter;
// Di chuyển gốc tọa độ về tâm của ảnh
ctx.translate(imageCenterX, imageCenterY);
// Xoay ngữ cảnh vẽ để "chân" ảnh hướng về tâm vòng tròn.
ctx.rotate(angleOfSegmentCenter + Math.PI / 2);
// Vẽ ảnh. Vì gốc tọa độ đã ở tâm ảnh, ta vẽ ảnh tại (-imageSize / 2, -imageSize / 2)
// để căn giữa ảnh.
ctx.drawImage(images[i], -imageSize / 2, -imageSize / 2, imageSize, imageSize);
ctx.restore(); // Khôi phục trạng thái canvas về ban đầu
} else if (images[i] && !images[i].complete) {
// Nếu ảnh chưa tải xong, gán sự kiện onload để vẽ lại khi ảnh đã sẵn sàng
images[i].onload = () => {
drawWheel(segments);
};
}
// KẾT THÚC: Vẽ ảnh
// BẮT ĐẦU: Vẽ chữ SAU ảnh để chữ nằm trên ảnh
ctx.save();
ctx.fillStyle = colorScheme.text;
ctx.font = "bold 24px Arial"; // Đã TĂNG kích thước chữ lên 24px
ctx.translate(
centerX + Math.cos(startAngle + anglePerSegment / 2) * (radius * 0.85),
centerY + Math.sin(startAngle + anglePerSegment / 2) * (radius * 0.85)
);
ctx.rotate(startAngle + anglePerSegment / 2 + Math.PI / 2);
const text = segmentsArray[i];
ctx.fillText(text, -ctx.measureText(text).width / 2, 0);
ctx.restore();
// KẾT THÚC: Vẽ chữ
}
// Vẽ mũi tên chỉ thị
const oscillationAmount = 8; // Tăng độ lớn dao động để mũi tên "rung" mạnh hơn
const oscillationSpeed = 0.05; // Giảm tốc độ dao động để nó mượt mà hơn
const time = Date.now() * 0.005; // Sử dụng thời gian để tạo dao động độc lập với vòng quay
const offsetX_oscillation = Math.sin(time * oscillationSpeed) * oscillationAmount;
const offsetY_oscillation = Math.cos(time * oscillationSpeed) * oscillationAmount;
// Dời mũi tên sang phải 15px cố định
const fixedOffsetX = 0;
ctx.beginPath();
// Điều chỉnh vị trí mũi tên để nó nằm gần viền ngoài của canvas và dời sang phải
// Thêm fixedOffsetX vào các tọa độ X để dịch chuyển sang phải
ctx.moveTo(centerX + 100, centerY);
ctx.lineTo(centerX, centerY - 60);
ctx.lineTo(centerX, centerY + 60);
ctx.closePath(); // Đóng đường dẫn để đảm bảo hình tam giác được vẽ đúng
// Định dạng màu sắc và đổ bóng cho mũi tên
ctx.fillStyle = "#db0202"; // Màu cam nổi bật (Material Design Orange A700)
ctx.shadowColor = "rgb(0, 0, 0)"; // Màu đổ bóng
ctx.shadowBlur = 30; // Độ mờ đổ bóng
ctx.shadowOffsetX = 5; // Độ lệch đổ bóng theo X
ctx.shadowOffsetY = 5; // Độ lệch đổ bóng theo Y
ctx.fill();
// Đảm bảo reset shadow sau khi vẽ mũi tên để không ảnh hưởng các phần tử khác
ctx.shadowColor = "transparent";
ctx.shadowBlur = 0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
// --- Bắt đầu phần vẽ HÌNH TRÒN tại TÂM ---
ctx.beginPath();
const centerCircleRadius = radius * 0.18; // Kích thước hình tròn tại tâm, 18% bán kính vòng quay
ctx.arc(centerX, centerY, centerCircleRadius, 0, Math.PI * 2, false);
ctx.fillStyle = "#fff"; // Màu vàng gold cho hình tròn tâm
ctx.shadowColor = "rgba(0, 0, 0, 0.4)"; // Đổ bóng nhẹ cho hình tròn tâm
ctx.shadowBlur = 10;
ctx.shadowOffsetX = 3;
ctx.shadowOffsetY = 3;
ctx.fill();
ctx.strokeStyle = "#db0202"; // Viền màu đồng cho hình tròn tâm
ctx.lineWidth = 10;
ctx.stroke();
// Đảm bảo reset shadow sau khi vẽ hình tròn để không ảnh hưởng mũi tên
ctx.shadowColor = "transparent";
ctx.shadowBlur = 0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
// Vẽ chữ lên hình tròn tại tâm
ctx.save(); // Lưu trạng thái canvas để không ảnh hưởng các phần tử khác
ctx.fillStyle = "#db0202"; // Màu chữ
ctx.font = `bold ${Math.min(centerCircleRadius * 0.6, 32)}px Arial`; // Kích thước chữ responsive, tối đa 28px
ctx.textAlign = 'center';
ctx.textBaseline = 'middle'; // Căn giữa chữ theo chiều dọc
const centerText = "S.I.S"; // Văn bản muốn hiển thị
ctx.fillText(centerText, centerX, centerY); // Vẽ chữ tại tâm
ctx.restore(); // Khôi phục trạng thái canvas
// --- Kết thúc phần vẽ HÌNH TRÒN tại TÂM ---
}
// Animation de la roue
function spinWheel() {
if (!isSpinning) return;
// Mise à jour de l'angle et réduction de la vitesse
currentAngle += spinVelocity;
spinVelocity *= 0.995; // friction
// Condition d'arrêt
if (spinVelocity < 0.01) {
spinVelocity = 0;
isSpinning = false;
findWinner();
}
// Redessiner la roue à chaque frame
drawWheel(segments);
requestAnimationFrame(spinWheel);
}
// Déterminer le segment gagnant en fonction de l'angle final
function findWinner() {
const numSegments = segments.length;
const anglePerSegment = (2 * Math.PI) / numSegments;
let normalizedAngle = currentAngle % (2 * Math.PI);
if (normalizedAngle < 0) normalizedAngle += 2 * Math.PI;
normalizedAngle = (normalizedAngle - Math.PI / 2 + 2 * Math.PI) % (2 * Math.PI);
const winningIndex = (numSegments - Math.floor(normalizedAngle / anglePerSegment) - 1) % numSegments;
const winner = segments[winningIndex];
const resultDiv = document.getElementById('result');
resultDiv.classList.remove('show');
// Utiliser le schéma de couleur du segment gagnant
const colorScheme = colorSchemes[winningIndex % colorSchemes.length];
setTimeout(() => {
// cong bo giai thuong
let prize_id = prize_ids[winningIndex];
var csrfToken = $('meta[name="csrf-token"]').attr('content');
$.ajax({
url: "{{ route('updateprizeuser') }}",
type: 'POST',
data: {
prize_id: prize_id,
_token: csrfToken // Bao gồm CSRF token
},
success: function (response) {
resultDiv.innerHTML = response;
},
error: function (xhr, status, error) {
alert('Có lỗi xảy ra');
}
});
resultDiv.classList.add('show');
}, 300);
}
// Bouton "Tourner la roue"
spinButton.addEventListener("click", (event) => {
if ($(event.currentTarget).data('check') == false) {
alert('Chưa đăng nhập hoặc đã quay số rồi');
return;
}
if (!isSpinning) {
// Réinitialiser l'affichage du résultat
const resultDiv = document.getElementById('result');
resultDiv.classList.remove('show');
// Donner une vitesse initiale aléatoire
spinVelocity = Math.random() * 0.5 + 0.4;
isSpinning = true;
spinWheel();
}
});
drawWheel(segments);
</script>
<script src="{{asset('/public/frontend/js/game.js')}}"></script>