chore: synchronize project dependencies and update vendor directory files
This commit is contained in:
@@ -0,0 +1,392 @@
|
||||
<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> để có 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(/"/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>
|
||||
Reference in New Issue
Block a user