first commit 2
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
/* pns_visual_borad module style */
|
||||
|
||||
/* 💡 [수정] 슬라이더 크기를 부모 요소에 정확히 맞춤 */
|
||||
.pns-visual-slider {
|
||||
width: 100%;
|
||||
height: 850px; /* 고정 높이 */
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: #000; /* 빈 공간 배경색 */
|
||||
}
|
||||
|
||||
/* 💡 [수정] 이미지를 꽉 채우되(cover), 컨테이너가 이미지 비율과 같으므로 잘리지 않음 */
|
||||
.visual-bg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
/* 💡 [핵심 수정] 이미지 비율 무시하고 가로세로 100% 꽉 채움 */
|
||||
background-size: 100% 100% !important;
|
||||
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
/*transition: transform 7s;*/
|
||||
|
||||
image-rendering: -webkit-optimize-contrast;
|
||||
image-rendering: crisp-edges;
|
||||
-ms-interpolation-mode: bicubic;
|
||||
}
|
||||
|
||||
/* .swiper-slide-active .visual-bg { transform: scale(1.1); } */ /* 줌 효과 제거 (이미지 전체 보기에 방해될 수 있음) */
|
||||
|
||||
/* 오버레이 제거 (투명) */
|
||||
.visual-bg::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0,0,0,0);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.visual-content { position: relative; z-index: 10; height: 100%; display: flex; flex-direction: column; justify-content: center; color: #fff; padding: 0 10%; }
|
||||
.visual-title { font-size: 3.5rem; font-weight: 800; line-height: 1.2; margin-bottom: 20px; word-break: keep-all; text-shadow: 2px 2px 10px rgba(0,0,0,0.5); }
|
||||
.visual-desc { font-size: 1.3rem; line-height: 1.6; margin-bottom: 40px; font-weight: 300; opacity: 0.9; text-shadow: 1px 1px 5px rgba(0,0,0,0.5); }
|
||||
.visual-btn { display: inline-block; padding: 15px 45px; border: 2px solid #fff; color: #fff; text-decoration: none; font-size: 1rem; transition: 0.3s; width: fit-content; cursor: pointer; }
|
||||
.visual-btn:hover { background: #fff; color: #000; }
|
||||
|
||||
/* 라이트박스 스타일 */
|
||||
.image-lightbox {
|
||||
display: none;
|
||||
position: fixed;
|
||||
z-index: 9999;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.85);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
animation: fadeIn 0.3s;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.lightbox-content {
|
||||
max-width: 90%;
|
||||
max-height: 80%;
|
||||
object-fit: contain;
|
||||
animation: zoomIn 0.3s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.lightbox-close {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 40px;
|
||||
color: #fff;
|
||||
font-size: 40px;
|
||||
font-weight: bold;
|
||||
transition: 0.3s;
|
||||
cursor: pointer;
|
||||
z-index: 10001;
|
||||
}
|
||||
|
||||
.lightbox-close:hover {
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
/* 라이트박스 내 바로가기 버튼 스타일 */
|
||||
.lightbox-link-btn {
|
||||
display: none;
|
||||
margin-top: 20px;
|
||||
padding: 12px 30px;
|
||||
background-color: #009fe3;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
border-radius: 5px;
|
||||
transition: background-color 0.3s;
|
||||
z-index: 10001;
|
||||
}
|
||||
|
||||
.lightbox-link-btn:hover {
|
||||
background-color: #007bb5;
|
||||
}
|
||||
|
||||
/* Swiper 네비게이션 버튼 스타일 */
|
||||
.swiper-button-next, .swiper-button-prev {
|
||||
color: #fff !important;
|
||||
text-shadow: 0 0 5px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.swiper-pagination-bullet {
|
||||
background: #fff !important;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.swiper-pagination-bullet-active {
|
||||
opacity: 1;
|
||||
background: #009fe3 !important;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
@keyframes zoomIn {
|
||||
from { transform: scale(0.8); }
|
||||
to { transform: scale(1); }
|
||||
}
|
||||
|
||||
/* 💡 [수정] 모바일 반응형 처리 (비율 유지) */
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* rb.custom :: pns_visual_borad_laser/module.js
|
||||
* 메인 비주얼 슬라이더 스크립트 (Swiper 사용)
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
"use strict";
|
||||
|
||||
// 이미 함수가 정의되어 있다면 중복 정의 방지
|
||||
if (typeof window.initPnsVisualSlider === 'function') {
|
||||
// return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 슬라이더 초기화 함수
|
||||
* @param {string} moduleId - 슬라이더 컨테이너의 ID
|
||||
*/
|
||||
window.initPnsVisualSlider = function(moduleId) {
|
||||
const $module = $('#' + moduleId);
|
||||
if (!$module.length) return;
|
||||
|
||||
const $swiperContainer = $module;
|
||||
|
||||
// 데이터 속성에서 설정값 가져오기 (없으면 기본값 사용)
|
||||
const spaceBetween = parseInt($swiperContainer.data('space-between'), 10) || 0; // 슬라이드 간 간격
|
||||
// 💡 [수정] autoplay 시간 설정값 가져오기 (기본값 5000ms)
|
||||
const autoplayDelay = parseInt($swiperContainer.data('autoplay-time'), 10) || 5000;
|
||||
const totalSlides = $swiperContainer.find('.swiper-slide').length; // 전체 슬라이드 개수
|
||||
|
||||
// Swiper 옵션 설정
|
||||
const swiperOptions = {
|
||||
// 💡 [핵심] 한 번에 보여줄 슬라이드 개수 (1로 설정하여 꽉 차게 표시)
|
||||
slidesPerView: 1,
|
||||
spaceBetween: spaceBetween,
|
||||
|
||||
// 슬라이드가 1개보다 많을 때만 무한 루프 활성화
|
||||
loop: totalSlides > 1,
|
||||
|
||||
// DOM 변화 감지 및 자동 업데이트 (이미지 로딩 문제 방지)
|
||||
observer: true,
|
||||
observeParents: true,
|
||||
watchOverflow: true,
|
||||
|
||||
// 자동 재생 설정
|
||||
autoplay: {
|
||||
delay: autoplayDelay, // 💡 [수정] 설정된 시간 적용
|
||||
disableOnInteraction: false, // 사용자 상호작용 후에도 자동 재생 유지
|
||||
},
|
||||
|
||||
// 네비게이션 버튼 (이전/다음)
|
||||
navigation: {
|
||||
nextEl: $module.find('.swiper-button-next')[0],
|
||||
prevEl: $module.find('.swiper-button-prev')[0],
|
||||
},
|
||||
|
||||
// 페이지네이션 (하단 점)
|
||||
pagination: {
|
||||
el: $module.find('.swiper-pagination')[0],
|
||||
clickable: true, // 클릭하여 이동 가능
|
||||
},
|
||||
|
||||
// 반응형 설정 (화면 크기에 따른 설정 변경)
|
||||
// 현재는 모든 해상도에서 1개씩 보여주도록 고정됨
|
||||
breakpoints: {
|
||||
640: {
|
||||
slidesPerView: 1 // 태블릿 등에서도 1개
|
||||
},
|
||||
1024: {
|
||||
slidesPerView: 1 // PC에서도 1개
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 슬라이드가 1개 이하일 경우 네비게이션/페이지네이션 숨기고 롤링 비활성화
|
||||
if (totalSlides <= 1) {
|
||||
$module.find('.swiper-button-next, .swiper-button-prev, .swiper-pagination').hide();
|
||||
swiperOptions.loop = false;
|
||||
swiperOptions.autoplay = false;
|
||||
}
|
||||
|
||||
// Swiper 인스턴스 생성 및 초기화
|
||||
new Swiper($swiperContainer[0], swiperOptions);
|
||||
};
|
||||
|
||||
// 문서 로드 완료 후 실행
|
||||
$(function() {
|
||||
// .pns-visual-slider 클래스를 가진 모든 요소를 찾아 초기화
|
||||
$('.pns-visual-slider').each(function() {
|
||||
if ($(this).attr('id')) {
|
||||
window.initPnsVisualSlider($(this).attr('id'));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* rb.custom :: pns_visual_borad_laser/module.js
|
||||
* 메인 비주얼 슬라이더 스크립트 (Swiper 사용)
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
"use strict";
|
||||
|
||||
// 이미 함수가 정의되어 있다면 중복 정의 방지
|
||||
if (typeof window.initPnsVisualSlider === 'function') {
|
||||
// return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 슬라이더 초기화 함수
|
||||
* @param {string} moduleId - 슬라이더 컨테이너의 ID
|
||||
*/
|
||||
window.initPnsVisualSlider = function(moduleId) {
|
||||
const $module = $('#' + moduleId);
|
||||
if (!$module.length) return;
|
||||
|
||||
const $swiperContainer = $module;
|
||||
|
||||
// 데이터 속성에서 설정값 가져오기 (없으면 기본값 사용)
|
||||
const spaceBetween = parseInt($swiperContainer.data('space-between'), 10) || 0; // 슬라이드 간 간격
|
||||
const totalSlides = $swiperContainer.find('.swiper-slide').length; // 전체 슬라이드 개수
|
||||
|
||||
// Swiper 옵션 설정
|
||||
const swiperOptions = {
|
||||
// 💡 [핵심] 한 번에 보여줄 슬라이드 개수 (1로 설정하여 꽉 차게 표시)
|
||||
slidesPerView: 1,
|
||||
spaceBetween: spaceBetween,
|
||||
|
||||
// 슬라이드가 1개보다 많을 때만 무한 루프 활성화
|
||||
loop: totalSlides > 1,
|
||||
|
||||
// DOM 변화 감지 및 자동 업데이트 (이미지 로딩 문제 방지)
|
||||
observer: true,
|
||||
observeParents: true,
|
||||
watchOverflow: true,
|
||||
|
||||
// 자동 재생 설정
|
||||
autoplay: {
|
||||
delay: 5000, // 3초마다 전환
|
||||
disableOnInteraction: false, // 사용자 상호작용 후에도 자동 재생 유지
|
||||
},
|
||||
|
||||
// 네비게이션 버튼 (이전/다음)
|
||||
navigation: {
|
||||
nextEl: $module.find('.swiper-button-next')[0],
|
||||
prevEl: $module.find('.swiper-button-prev')[0],
|
||||
},
|
||||
|
||||
// 페이지네이션 (하단 점)
|
||||
pagination: {
|
||||
el: $module.find('.swiper-pagination')[0],
|
||||
clickable: true, // 클릭하여 이동 가능
|
||||
},
|
||||
|
||||
// 반응형 설정 (화면 크기에 따른 설정 변경)
|
||||
// 현재는 모든 해상도에서 1개씩 보여주도록 고정됨
|
||||
breakpoints: {
|
||||
640: {
|
||||
slidesPerView: 1 // 태블릿 등에서도 1개
|
||||
},
|
||||
1024: {
|
||||
slidesPerView: 1 // PC에서도 1개
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 슬라이드가 1개 이하일 경우 네비게이션/페이지네이션 숨기고 롤링 비활성화
|
||||
if (totalSlides <= 1) {
|
||||
$module.find('.swiper-button-next, .swiper-button-prev, .swiper-pagination').hide();
|
||||
swiperOptions.loop = false;
|
||||
swiperOptions.autoplay = false;
|
||||
}
|
||||
|
||||
// Swiper 인스턴스 생성 및 초기화
|
||||
new Swiper($swiperContainer[0], swiperOptions);
|
||||
};
|
||||
|
||||
// 문서 로드 완료 후 실행
|
||||
$(function() {
|
||||
// .pns-visual-slider 클래스를 가진 모든 요소를 찾아 초기화
|
||||
$('.pns-visual-slider').each(function() {
|
||||
if ($(this).attr('id')) {
|
||||
window.initPnsVisualSlider($(this).attr('id'));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,238 @@
|
||||
<?php
|
||||
if (!defined('_GNUBOARD_')) exit;
|
||||
|
||||
/**
|
||||
* rb.custom :: pns_visual_borad_laser/module.php
|
||||
* PNS 스타일 메인 비주얼 슬라이더 (게시판 연동)
|
||||
*/
|
||||
|
||||
if (!isset($md_id) || !$md_id) return;
|
||||
|
||||
$md_id_safe = sql_real_escape_string($md_id);
|
||||
$module_config = sql_fetch(" SELECT * FROM `rb_module` WHERE md_id = '{$md_id_safe}' ");
|
||||
if (!$module_config) $module_config = sql_fetch(" SELECT * FROM `rb_module_shop` WHERE md_id = '{$md_id_safe}' ");
|
||||
if (!$module_config) return;
|
||||
|
||||
$config_path = __DIR__ . '/config.php';
|
||||
if (file_exists($config_path)) include_once($config_path);
|
||||
|
||||
|
||||
// --- 설정 변수 ---
|
||||
$bo_table = 'main_visual'; // 실제 생성하신 게시판 테이블명으로 수정하세요
|
||||
$limit_count = 10; // 불러올 슬라이드 개수 (변수 처리)
|
||||
$write_table = $g5['write_prefix'] . $bo_table;
|
||||
|
||||
// 💡 [설정] 애니메이션(Parallax) 사용 여부 (true: 사용, false: 사용안함 - 이미지 고정)
|
||||
$use_parallax = true;
|
||||
|
||||
// 💡 [추가] 팝업 내 링크 이동 방식 설정 (button, image, both)
|
||||
$link_type = 'image'; // 기본값: 이미지 클릭 시 이동
|
||||
|
||||
// 💡 [수정] 노출 조건 추가 (숨김, 예약 노출)
|
||||
$today = G5_TIME_YMD; // 오늘 날짜 (YYYY-MM-DD)
|
||||
|
||||
$sql_where = " wr_is_comment = 0 "; // 기본 조건: 댓글 제외
|
||||
|
||||
// 1. 숨김 설정 (wr_10) 체크: 값이 없거나 0인 경우만 노출
|
||||
$sql_where .= " AND (wr_10 = '' OR wr_10 IS NULL OR wr_10 = '0') ";
|
||||
|
||||
// 2. 노출 방식 (wr_9) 체크: 즉시 노출이거나, 예약 기간 내인 경우
|
||||
$sql_where .= " AND (
|
||||
wr_9 != 'RESERVED'
|
||||
OR (wr_9 = 'RESERVED' AND wr_2 <= '{$today}' AND wr_3 >= '{$today}')
|
||||
) ";
|
||||
|
||||
// 데이터베이스에서 데이터 가져오기 (wr_id 역순)
|
||||
$sql = " SELECT * FROM {$write_table}
|
||||
WHERE {$sql_where}
|
||||
ORDER BY wr_num, wr_reply LIMIT 0, {$limit_count} ";
|
||||
$result = sql_query($sql);
|
||||
|
||||
$module_id = 'pns_visual_' . uniqid();
|
||||
$module_css_path = G5_THEME_PATH.'/rb.custom/pns_visual_borad_laser/module.css';
|
||||
$module_js_path = G5_THEME_PATH.'/rb.custom/pns_visual_borad_laser/module.js';
|
||||
$module_css_ver = file_exists($module_css_path) ? filemtime($module_css_path) : G5_CSS_VER;
|
||||
$module_js_ver = file_exists($module_js_path) ? filemtime($module_js_path) : G5_JS_VER;
|
||||
$swiper_time = isset($module_config['md_auto_time']) && $module_config['md_auto_time'] ? $module_config['md_auto_time'] : '5000';
|
||||
?>
|
||||
|
||||
<div id="<?php echo $module_id; ?>" class="pns-visual-slider swiper-container" data-autoplay-time="<?php echo $swiper_time; ?>">
|
||||
<div class="swiper-wrapper">
|
||||
<?php
|
||||
for ($i=0; $row=sql_fetch_array($result); $i++) {
|
||||
// 💡 [수정] 이미지 가져오기 로직 개선 (원본 파일 우선 -> 썸네일 -> 기본 이미지)
|
||||
$img_url = '';
|
||||
|
||||
// 1. 원본 파일 확인
|
||||
$sql_file = " select bf_file from {$g5['board_file_table']} where bo_table = '$bo_table' and wr_id = '{$row['wr_id']}' order by bf_no limit 1 ";
|
||||
$row_file = sql_fetch($sql_file);
|
||||
|
||||
if ($row_file['bf_file']) {
|
||||
$img_url = G5_DATA_URL.'/file/'.$bo_table.'/'.$row_file['bf_file'];
|
||||
}
|
||||
|
||||
// 2. 원본 파일이 없으면 썸네일 확인
|
||||
if (!$img_url) {
|
||||
// 💡 [수정] 썸네일 생성 (부모 영역에 맞게 고화질 유지, 크롭핑 안함)
|
||||
// 1240x750 고정 비율 대신 원본 비율 유지하거나 충분히 큰 사이즈 사용
|
||||
// crop을 false로 설정하여 원본 비율 유지
|
||||
$thumb = get_list_thumbnail($bo_table, $row['wr_id'], 796, 850, true, true);
|
||||
|
||||
if ($thumb['src']) {
|
||||
$img_url = $thumb['src'];
|
||||
}
|
||||
}
|
||||
// $img_url = get_list_thumbnail($bo_table, $row['wr_id'], 760, 760, true, true);
|
||||
// 3. 둘 다 없으면 기본 이미지
|
||||
if (!$img_url) {
|
||||
$img_url = G5_THEME_URL.'/rb.img/no_image.png';
|
||||
}
|
||||
|
||||
// 원본 이미지 경로 (팝업용)
|
||||
$ori_url = $img_url;
|
||||
|
||||
// 제목과 요약 내용 (wr_subject, wr_1)
|
||||
$subject = cut_str(get_text($row['wr_subject']), 100);
|
||||
$summary = get_text($row['wr_1']); // wr_1에 저장된 요약 내용
|
||||
|
||||
// 링크 URL (wr_link1 사용)
|
||||
$link_url = $row['wr_link1'];
|
||||
|
||||
// 💡 [수정] 링크가 있으면 바로 이동, 없으면 팝업
|
||||
$click_action = '';
|
||||
$cursor_style = '';
|
||||
if ($link_url) {
|
||||
$click_action = "onclick=\"window.open('{$link_url}', '_blank');\"";
|
||||
$cursor_style = 'cursor: pointer;';
|
||||
} else {
|
||||
$click_action = "onclick=\"openLightbox('{$ori_url}', '{$link_url}');\""; // 팝업 함수 호출
|
||||
$cursor_style = 'cursor: zoom-in;';
|
||||
}
|
||||
?>
|
||||
<div class="swiper-slide">
|
||||
<div class="visual-bg"
|
||||
style="background-image: url('<?php echo $img_url; ?>'); "<?php echo $cursor_style; ?>"
|
||||
<?php echo $click_action; ?>
|
||||
<?php if($use_parallax) echo 'data-swiper-parallax="100%"'; ?>>
|
||||
</div>
|
||||
<!-- <div class="visual-content">-->
|
||||
<!-- <h2 class="visual-title" --><?php //if($use_parallax) echo 'data-swiper-parallax="-300"'; ?><!-->--><?php //echo $subject; ?><!--</h2>-->
|
||||
<!-- --><?php //if ($summary): ?>
|
||||
<!-- <p class="visual-desc" --><?php //if($use_parallax) echo 'data-swiper-parallax="-200"'; ?><!-->--><?php //echo $summary; ?><!--</p>-->
|
||||
<!-- --><?php //endif; ?>
|
||||
<!-- <div --><?php //if($use_parallax) echo 'data-swiper-parallax="-100"'; ?><!-->-->
|
||||
<a <?php echo $click_action; ?>></a>
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<?php if($i == 0) echo '<div class="swiper-slide"><div class="visual-content">등록된 광고 데이터가 없습니다.</div></div>'; ?>
|
||||
</div>
|
||||
|
||||
<div class="swiper-pagination"></div>
|
||||
<div class="swiper-button-next"></div>
|
||||
<div class="swiper-button-prev"></div>
|
||||
</div>
|
||||
|
||||
<!-- 💡 [추가] 이미지 라이트박스 컨테이너 -->
|
||||
<div id="image-lightbox" class="image-lightbox">
|
||||
<span class="lightbox-close">×</span>
|
||||
<img class="lightbox-content" id="lightbox-img">
|
||||
<!-- 💡 [추가] 바로가기 버튼 -->
|
||||
<a href="#" target="_blank" class="lightbox-link-btn" id="lightbox-link">바로가기</a>
|
||||
</div>
|
||||
|
||||
<!-- CSS 파일 로드 (경로 수정됨: pns_visual_borad_laser) -->
|
||||
<link rel="stylesheet" href="<?php echo G5_THEME_URL; ?>/rb.custom/pns_visual_borad_laser/module.css?ver=<?php echo $module_css_ver; ?>">
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
const currentModuleId = '<?php echo $module_id; ?>';
|
||||
// 💡 [수정] 함수 이름 변경 (initPremiumAdSection -> initPnsVisualSlider)
|
||||
const initFunctionName = 'initPnsVisualSlider';
|
||||
const scriptId = 'pns-visual-slider-script';
|
||||
|
||||
if (document.getElementById(scriptId)) {
|
||||
if (typeof window[initFunctionName] === 'function') {
|
||||
window[initFunctionName](currentModuleId);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const script = document.createElement('script');
|
||||
script.id = scriptId;
|
||||
script.src = '<?php echo G5_THEME_URL; ?>/rb.custom/pns_visual_borad_laser/module.js?ver=<?php echo $module_js_ver; ?>';
|
||||
script.async = true;
|
||||
|
||||
script.onload = () => {
|
||||
if (typeof window[initFunctionName] === 'function') {
|
||||
window[initFunctionName](currentModuleId);
|
||||
}
|
||||
};
|
||||
document.head.appendChild(script);
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<!-- 통합 동적 로더 (Swiper) -->
|
||||
<script>
|
||||
// 전역 함수로 선언하여 HTML onclick에서 호출 가능하게 함
|
||||
function openLightbox(imgSrc, linkUrl) {
|
||||
var lightbox = document.getElementById('image-lightbox');
|
||||
var lightboxImg = document.getElementById('lightbox-img');
|
||||
var lightboxLink = document.getElementById('lightbox-link');
|
||||
|
||||
if (imgSrc) {
|
||||
lightboxImg.src = imgSrc;
|
||||
|
||||
if (linkUrl && linkUrl !== "") {
|
||||
lightboxLink.href = linkUrl;
|
||||
lightboxLink.style.display = 'inline-block';
|
||||
|
||||
lightboxImg.onclick = function() {
|
||||
window.open(linkUrl, '_blank');
|
||||
};
|
||||
lightboxImg.style.cursor = 'pointer';
|
||||
} else {
|
||||
lightboxLink.style.display = 'none';
|
||||
lightboxImg.onclick = null;
|
||||
lightboxImg.style.cursor = 'default';
|
||||
}
|
||||
|
||||
lightbox.style.display = 'flex';
|
||||
}
|
||||
}
|
||||
|
||||
(function() {
|
||||
// Swiper 로드 로직은 module.js에서 처리하거나, 여기서 로드 후 module.js 실행
|
||||
// 현재 구조상 module.js가 Swiper 초기화를 담당하므로 여기서는 Swiper 라이브러리 로드만 확인하면 됨
|
||||
|
||||
function loadScript(src, id, callback) {
|
||||
if (document.getElementById(id)) {
|
||||
if (callback) callback();
|
||||
return;
|
||||
}
|
||||
var script = document.createElement('script');
|
||||
script.id = id;
|
||||
script.src = src;
|
||||
script.async = false;
|
||||
if (callback) {
|
||||
script.onload = callback;
|
||||
}
|
||||
document.head.appendChild(script);
|
||||
}
|
||||
|
||||
if (typeof Swiper === 'undefined') {
|
||||
var link = document.createElement('link');
|
||||
link.rel = 'stylesheet';
|
||||
link.href = 'https://unpkg.com/swiper/swiper-bundle.min.css';
|
||||
document.head.appendChild(link);
|
||||
|
||||
loadScript('https://unpkg.com/swiper/swiper-bundle.min.js', 'swiper-bundle-js', function() {
|
||||
// Swiper 로드 완료 후 module.js의 초기화 함수가 있다면 실행될 것임
|
||||
// (module.js 내부에서 $(function(){...}) 으로 자동 실행되거나, 위쪽 스크립트에서 호출됨)
|
||||
});
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
@@ -0,0 +1,236 @@
|
||||
<?php
|
||||
if (!defined('_GNUBOARD_')) exit;
|
||||
|
||||
/**
|
||||
* rb.custom :: pns_visual_borad_laser/module.php
|
||||
* PNS 스타일 메인 비주얼 슬라이더 (게시판 연동)
|
||||
*/
|
||||
|
||||
if (!isset($md_id) || !$md_id) return;
|
||||
|
||||
$md_id_safe = sql_real_escape_string($md_id);
|
||||
$module_config = sql_fetch(" SELECT * FROM `rb_module` WHERE md_id = '{$md_id_safe}' ");
|
||||
if (!$module_config) $module_config = sql_fetch(" SELECT * FROM `rb_module_shop` WHERE md_id = '{$md_id_safe}' ");
|
||||
if (!$module_config) return;
|
||||
|
||||
$config_path = __DIR__ . '/config.php';
|
||||
if (file_exists($config_path)) include_once($config_path);
|
||||
|
||||
// --- 설정 변수 ---
|
||||
$bo_table = 'main_visual'; // 실제 생성하신 게시판 테이블명으로 수정하세요
|
||||
$limit_count = 10; // 불러올 슬라이드 개수 (변수 처리)
|
||||
$write_table = $g5['write_prefix'] . $bo_table;
|
||||
|
||||
// 💡 [설정] 애니메이션(Parallax) 사용 여부 (true: 사용, false: 사용안함 - 이미지 고정)
|
||||
$use_parallax = true;
|
||||
|
||||
// 💡 [추가] 팝업 내 링크 이동 방식 설정 (button, image, both)
|
||||
$link_type = 'image'; // 기본값: 이미지 클릭 시 이동
|
||||
|
||||
// 💡 [수정] 노출 조건 추가 (숨김, 예약 노출)
|
||||
$today = G5_TIME_YMD; // 오늘 날짜 (YYYY-MM-DD)
|
||||
|
||||
$sql_where = " wr_is_comment = 0 "; // 기본 조건: 댓글 제외
|
||||
|
||||
// 1. 숨김 설정 (wr_10) 체크: 값이 없거나 0인 경우만 노출
|
||||
$sql_where .= " AND (wr_10 = '' OR wr_10 IS NULL OR wr_10 = '0') ";
|
||||
|
||||
// 2. 노출 방식 (wr_9) 체크: 즉시 노출이거나, 예약 기간 내인 경우
|
||||
$sql_where .= " AND (
|
||||
wr_9 != 'RESERVED'
|
||||
OR (wr_9 = 'RESERVED' AND wr_2 <= '{$today}' AND wr_3 >= '{$today}')
|
||||
) ";
|
||||
|
||||
// 데이터베이스에서 데이터 가져오기 (wr_id 역순)
|
||||
$sql = " SELECT * FROM {$write_table}
|
||||
WHERE {$sql_where}
|
||||
ORDER BY wr_num, wr_reply LIMIT 0, {$limit_count} ";
|
||||
$result = sql_query($sql);
|
||||
|
||||
$module_id = 'pns_visual_' . uniqid();
|
||||
$module_css_path = G5_THEME_PATH.'/rb.custom/pns_visual_borad_laser/module.css';
|
||||
$module_js_path = G5_THEME_PATH.'/rb.custom/pns_visual_borad_laser/module.js';
|
||||
$module_css_ver = file_exists($module_css_path) ? filemtime($module_css_path) : G5_CSS_VER;
|
||||
$module_js_ver = file_exists($module_js_path) ? filemtime($module_js_path) : G5_JS_VER;
|
||||
?>
|
||||
|
||||
<div id="<?php echo $module_id; ?>" class="pns-visual-slider swiper-container">
|
||||
<div class="swiper-wrapper">
|
||||
<?php
|
||||
for ($i=0; $row=sql_fetch_array($result); $i++) {
|
||||
// 💡 [수정] 이미지 가져오기 로직 개선 (원본 파일 우선 -> 썸네일 -> 기본 이미지)
|
||||
$img_url = '';
|
||||
|
||||
// 1. 원본 파일 확인
|
||||
$sql_file = " select bf_file from {$g5['board_file_table']} where bo_table = '$bo_table' and wr_id = '{$row['wr_id']}' order by bf_no limit 1 ";
|
||||
$row_file = sql_fetch($sql_file);
|
||||
|
||||
if ($row_file['bf_file']) {
|
||||
$img_url = G5_DATA_URL.'/file/'.$bo_table.'/'.$row_file['bf_file'];
|
||||
}
|
||||
|
||||
// 2. 원본 파일이 없으면 썸네일 확인
|
||||
if (!$img_url) {
|
||||
// 💡 [수정] 썸네일 생성 (부모 영역에 맞게 고화질 유지, 크롭핑 안함)
|
||||
// 1240x750 고정 비율 대신 원본 비율 유지하거나 충분히 큰 사이즈 사용
|
||||
// crop을 false로 설정하여 원본 비율 유지
|
||||
$thumb = get_list_thumbnail($bo_table, $row['wr_id'], 796, 850, true, true);
|
||||
|
||||
if ($thumb['src']) {
|
||||
$img_url = $thumb['src'];
|
||||
}
|
||||
}
|
||||
// $img_url = get_list_thumbnail($bo_table, $row['wr_id'], 760, 760, true, true);
|
||||
// 3. 둘 다 없으면 기본 이미지
|
||||
if (!$img_url) {
|
||||
$img_url = G5_THEME_URL.'/rb.img/no_image.png';
|
||||
}
|
||||
|
||||
// 원본 이미지 경로 (팝업용)
|
||||
$ori_url = $img_url;
|
||||
|
||||
// 제목과 요약 내용 (wr_subject, wr_1)
|
||||
$subject = cut_str(get_text($row['wr_subject']), 100);
|
||||
$summary = get_text($row['wr_1']); // wr_1에 저장된 요약 내용
|
||||
|
||||
// 링크 URL (wr_link1 사용)
|
||||
$link_url = $row['wr_link1'];
|
||||
|
||||
// 💡 [수정] 링크가 있으면 바로 이동, 없으면 팝업
|
||||
$click_action = '';
|
||||
$cursor_style = '';
|
||||
if ($link_url) {
|
||||
$click_action = "onclick=\"window.open('{$link_url}', '_blank');\"";
|
||||
$cursor_style = 'cursor: pointer;';
|
||||
} else {
|
||||
$click_action = "onclick=\"openLightbox('{$ori_url}', '{$link_url}');\""; // 팝업 함수 호출
|
||||
$cursor_style = 'cursor: zoom-in;';
|
||||
}
|
||||
?>
|
||||
<div class="swiper-slide">
|
||||
<div class="visual-bg"
|
||||
style="background-image: url('<?php echo $img_url; ?>'); "<?php echo $cursor_style; ?>"
|
||||
<?php echo $click_action; ?>
|
||||
<?php if($use_parallax) echo 'data-swiper-parallax="100%"'; ?>>
|
||||
</div>
|
||||
<!-- <div class="visual-content">-->
|
||||
<!-- <h2 class="visual-title" --><?php //if($use_parallax) echo 'data-swiper-parallax="-300"'; ?><!-->--><?php //echo $subject; ?><!--</h2>-->
|
||||
<!-- --><?php //if ($summary): ?>
|
||||
<!-- <p class="visual-desc" --><?php //if($use_parallax) echo 'data-swiper-parallax="-200"'; ?><!-->--><?php //echo $summary; ?><!--</p>-->
|
||||
<!-- --><?php //endif; ?>
|
||||
<!-- <div --><?php //if($use_parallax) echo 'data-swiper-parallax="-100"'; ?><!-->-->
|
||||
<a <?php echo $click_action; ?>></a>
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<?php if($i == 0) echo '<div class="swiper-slide"><div class="visual-content">등록된 광고 데이터가 없습니다.</div></div>'; ?>
|
||||
</div>
|
||||
|
||||
<div class="swiper-pagination"></div>
|
||||
<div class="swiper-button-next"></div>
|
||||
<div class="swiper-button-prev"></div>
|
||||
</div>
|
||||
|
||||
<!-- 💡 [추가] 이미지 라이트박스 컨테이너 -->
|
||||
<div id="image-lightbox" class="image-lightbox">
|
||||
<span class="lightbox-close">×</span>
|
||||
<img class="lightbox-content" id="lightbox-img">
|
||||
<!-- 💡 [추가] 바로가기 버튼 -->
|
||||
<a href="#" target="_blank" class="lightbox-link-btn" id="lightbox-link">바로가기</a>
|
||||
</div>
|
||||
|
||||
<!-- CSS 파일 로드 (경로 수정됨: pns_visual_borad_laser) -->
|
||||
<link rel="stylesheet" href="<?php echo G5_THEME_URL; ?>/rb.custom/pns_visual_borad_laser/module.css?ver=<?php echo $module_css_ver; ?>">
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
const currentModuleId = '<?php echo $module_id; ?>';
|
||||
// 💡 [수정] 함수 이름 변경 (initPremiumAdSection -> initPnsVisualSlider)
|
||||
const initFunctionName = 'initPnsVisualSlider';
|
||||
const scriptId = 'pns-visual-slider-script';
|
||||
|
||||
if (document.getElementById(scriptId)) {
|
||||
if (typeof window[initFunctionName] === 'function') {
|
||||
window[initFunctionName](currentModuleId);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const script = document.createElement('script');
|
||||
script.id = scriptId;
|
||||
script.src = '<?php echo G5_THEME_URL; ?>/rb.custom/pns_visual_borad_laser/module.js?ver=<?php echo $module_js_ver; ?>';
|
||||
script.async = true;
|
||||
|
||||
script.onload = () => {
|
||||
if (typeof window[initFunctionName] === 'function') {
|
||||
window[initFunctionName](currentModuleId);
|
||||
}
|
||||
};
|
||||
document.head.appendChild(script);
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<!-- 통합 동적 로더 (Swiper) -->
|
||||
<script>
|
||||
// 전역 함수로 선언하여 HTML onclick에서 호출 가능하게 함
|
||||
function openLightbox(imgSrc, linkUrl) {
|
||||
var lightbox = document.getElementById('image-lightbox');
|
||||
var lightboxImg = document.getElementById('lightbox-img');
|
||||
var lightboxLink = document.getElementById('lightbox-link');
|
||||
|
||||
if (imgSrc) {
|
||||
lightboxImg.src = imgSrc;
|
||||
|
||||
if (linkUrl && linkUrl !== "") {
|
||||
lightboxLink.href = linkUrl;
|
||||
lightboxLink.style.display = 'inline-block';
|
||||
|
||||
lightboxImg.onclick = function() {
|
||||
window.open(linkUrl, '_blank');
|
||||
};
|
||||
lightboxImg.style.cursor = 'pointer';
|
||||
} else {
|
||||
lightboxLink.style.display = 'none';
|
||||
lightboxImg.onclick = null;
|
||||
lightboxImg.style.cursor = 'default';
|
||||
}
|
||||
|
||||
lightbox.style.display = 'flex';
|
||||
}
|
||||
}
|
||||
|
||||
(function() {
|
||||
// Swiper 로드 로직은 module.js에서 처리하거나, 여기서 로드 후 module.js 실행
|
||||
// 현재 구조상 module.js가 Swiper 초기화를 담당하므로 여기서는 Swiper 라이브러리 로드만 확인하면 됨
|
||||
|
||||
function loadScript(src, id, callback) {
|
||||
if (document.getElementById(id)) {
|
||||
if (callback) callback();
|
||||
return;
|
||||
}
|
||||
var script = document.createElement('script');
|
||||
script.id = id;
|
||||
script.src = src;
|
||||
script.async = false;
|
||||
if (callback) {
|
||||
script.onload = callback;
|
||||
}
|
||||
document.head.appendChild(script);
|
||||
}
|
||||
|
||||
if (typeof Swiper === 'undefined') {
|
||||
var link = document.createElement('link');
|
||||
link.rel = 'stylesheet';
|
||||
link.href = 'https://unpkg.com/swiper/swiper-bundle.min.css';
|
||||
document.head.appendChild(link);
|
||||
|
||||
loadScript('https://unpkg.com/swiper/swiper-bundle.min.js', 'swiper-bundle-js', function() {
|
||||
// Swiper 로드 완료 후 module.js의 초기화 함수가 있다면 실행될 것임
|
||||
// (module.js 내부에서 $(function(){...}) 으로 자동 실행되거나, 위쪽 스크립트에서 호출됨)
|
||||
});
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
Reference in New Issue
Block a user