/** * Cpslmkn.js * * 캡슐 메이킹 게임 기능을 관리하는 모듈 * 사용자가 제품을 선택하고 게임을 진행할 수 있는 인터페이스 제공 */ $(function() { // 초기 컨텐츠 숨김 - 인트로 모달이 먼저 표시되어야 함 $('.content-wrap').hide(); // 인트로 모달 초기화 및 표시 - 게임 시작 전 소개 화면 initIntroModal(); // 제품 선택 이벤트 바인딩 - 사용자가 게임을 진행할 제품 선택 bindProductSelection(); // 시작하기 버튼 이벤트 바인딩 - 제품 선택 후 게임 시작 bindStartButton(); /** * 제품 선택 시 시각적 피드백 및 상태 업데이트 * 사용자가 게임 제품을 클릭하면 해당 항목 강조 표시 및 선택 처리 */ $('.gameProduct').on('click', function() { // 모든 gameProduct에서 selected 클래스 제거 - 기존 선택 초기화 $('.gameProduct').removeClass('selected'); // 클릭된 gameProduct에 selected 클래스 추가 - 현재 선택 항목 강조 $(this).addClass('selected'); // 해당 radio 버튼 선택 - UI와 실제 form 값 동기화 $(this).find('input[type="radio"]').prop('checked', true); // 시작 버튼 활성화 - 제품 선택 완료 시 다음 단계 진행 가능 $('.bottomBtnControls .btn').prop('disabled', false); }); }); /** * 인트로 모달 초기화 및 표시 함수 * 게임 시작 전 소개 슬라이드를 표시하고 관련 이벤트 설정 */ function initIntroModal() { // 슬라이드 및 페이징 요소 참조 const $slides = $('.gameIntroWrap'); // 각 소개 슬라이드 const $paging = $('.gamePaging'); // 페이징 도트 컨테이너 let currentSlide = 0; // 현재 표시 중인 슬라이드 인덱스 // 터치 이벤트 관련 변수 let touchStartX = 0; let touchStartY = 0; let touchEndX = 0; let touchEndY = 0; let isSwipe = false; // 페이징 도트 동적 생성 - 슬라이드 개수만큼 도트 추가 $slides.each(function() { $paging.append(''); }); // 초기 슬라이드 표시 - 첫 번째 슬라이드(인덱스 0) 표시 showSlide(0); // 터치 시작 이벤트 $('.gameIntroPaging').on('touchstart', function(e) { touchStartX = e.originalEvent.touches[0].clientX; touchStartY = e.originalEvent.touches[0].clientY; isSwipe = false; }); // 터치 이동 이벤트 $('.gameIntroPaging').on('touchmove', function(e) { e.preventDefault(); // 스크롤 방지 touchEndX = e.originalEvent.touches[0].clientX; touchEndY = e.originalEvent.touches[0].clientY; // 움직임이 있으면 스와이프로 판단 const deltaX = Math.abs(touchEndX - touchStartX); const deltaY = Math.abs(touchEndY - touchStartY); if (deltaX > 10 || deltaY > 10) { isSwipe = true; } }); // 터치 종료 이벤트 $('.gameIntroPaging').on('touchend', function(e) { if (!isSwipe) return; // 스와이프가 아니면 무시 const deltaX = touchEndX - touchStartX; const deltaY = touchEndY - touchStartY; const minSwipeDistance = 50; // 최소 스와이프 거리 // 좌우 스와이프만 처리 (상하 스와이프는 무시) if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > minSwipeDistance) { if (deltaX > 0) { // 오른쪽 스와이프 - 이전 슬라이드 const prevIndex = currentSlide === 0 ? $slides.length - 1 : currentSlide - 1; showSlide(prevIndex); } else { // 왼쪽 스와이프 - 다음 슬라이드 const nextIndex = (currentSlide + 1) % $slides.length; showSlide(nextIndex); } } }); // 기존 클릭 이벤트 (터치와 충돌하지 않도록 수정) $('.gameIntroPaging').on('click', function(e) { // 스와이프가 발생했으면 클릭 이벤트 무시 if (isSwipe) { isSwipe = false; return; } // 다음 슬라이드로 순환 이동 (마지막 슬라이드에서는 처음으로) showSlide((currentSlide + 1) % $slides.length); }); // 페이징 도트 클릭 시 해당 슬라이드로 직접 이동 $paging.on('click', 'span', function() { showSlide($(this).index()); }); /** * 특정 슬라이드 표시 함수 * 지정된 인덱스의 슬라이드를 표시하고 페이징 상태 업데이트 * @param {number} index - 표시할 슬라이드 인덱스 */ function showSlide(index) { // 모든 슬라이드 숨김 후 해당 인덱스의 슬라이드만 표시 $slides.hide().eq(index).show(); // 페이징 도트 상태 업데이트 - 현재 슬라이드에 해당하는 도트만 활성화 $paging.find('span').removeClass('active').eq(index).addClass('active'); // 현재 슬라이드 인덱스 업데이트 currentSlide = index; } // 시작하기 버튼 클릭 이벤트 - 인트로 종료 및 메인 컨텐츠 표시 $('#goCapsuleMaking').on('click', function() { // 인트로 모달 닫기 MicroModal.close('intro-modal'); // 메인 컨텐츠 표시 $('.content-wrap').show(); }); // 인트로 모달 표시 - 페이지 로드 시 자동 표시 MicroModal.show('intro-modal', { disableScroll: true, // 모달 표시 시 배경 스크롤 방지 awaitCloseAnimation: true // 닫기 애니메이션 완료 대기 }); } /** * 제품 선택 이벤트 설정함수 * 라디오 버튼으로 제품 선택 시 시작 버튼 활성화 */ function bindProductSelection() { // 제품 라디오 버튼 변경 시 시작 버튼 활성화 $('input[name="gameproduct"]').on('change', function() { $('.bottomBtnControls .btn').prop('disabled', false); }); } /** * 시작하기 버튼 이벤트 설정 함수 * 제품 선택 후 게임 시작 버튼 클릭 시 확인 모달 표시 및 게임 생성 요청 */ function bindStartButton() { // 초기에 시작 버튼 비활성화 상태로 설정하고 클릭 이벤트 바인딩 $('.bottomBtnControls .btn').prop('disabled', true).on('click', function() { // 선택된 제품 라디오 버튼 확인 const selectedProduct = $('input[name="gameproduct"]:checked'); // 제품이 선택된 경우에만 처리 if (selectedProduct.length > 0) { // 선택된 제품명을 확인 모달에 표시 const productName = selectedProduct.closest('.gameProduct').find('.gpTit .tit').text(); $('#selectedProductName').text(productName); // 확인 모달 표시 - 사용자에게 최종 확인 요청 MicroModal.show('modal-1', { disableScroll: true, awaitCloseAnimation: true }); // 모달의 '예' 버튼 클릭 이벤트 - 게임 생성 요청 처리 $('.microModal__btn-primary').off('click').on('click', function() { // 선택된 제품의 혜택 고유번호 가져오기 const bnfInnb = selectedProduct.val(); // AJAX 대신 폼 제출 방식으로 서버에 게임 생성 요청 const form = $('
', { 'method': 'post', 'action': '/sopmal/bnft/createGame' }).append($('', { 'type': 'hidden', 'name': 'bnfInnb', 'value': bnfInnb })); const sopmalCd = $('#sopmalCd').val(); form.append($('', { 'type': 'hidden', 'name': 'sopmalCd', 'value': sopmalCd })); // 동적으로 생성한 폼을 body에 추가하고 제출 $('body').append(form); form.submit(); }); } }); }