fgu_a4_dark/modules/video_pro/_video_pro_widget8.html.erb

388 lines
9.6 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<div class="w-video_data video_data-widget-8" data-subpart-id="{{subpart-id}}">
<h3 class="widget-title"><span>{{widget-title}}</span></h3>
<div class="vw3-carousel">
<button class="vw3-prev" title="上一組" aria-label="上一組" type="button">
<i class="fa fa-angle-left" aria-hidden="true"></i>
</button>
<div class="vw3-track-wrap">
<ul class="video_data_wrap vw3-track" data-list="videos" data-level="0">
<li class="video_data vw3-slide" data-video-url="{{video_url}}" data-video-webm-url="{{video_webm_url}}" data-type="{{video_type}}">
<a href="{{video_show_url}}" title="{{video_title_escape}}">
<div class="video_linkwrapper3">
<div class="videohover">
<div class="view_info"><span>{{view_count}}</span></div>
<div class="Video__Player"><button class="Video__PlayerButton" type="button"></button></div>
</div>
<img class="video_snapshot" src="{{snapshot_url}}" alt="{{video_title_escape}}">
</div>
</a>
<div class="video_info">
<div class="video_title">
<a class="video_link" href="{{video_show_url}}" title="{{video_title_escape}}"><h4>{{video_title}}</h4></a>
</div>
<div class="video_desc">
<a class="video_link" href="{{video_show_url}}" title="{{video_title_escape}}">{{video_desc}}</a>
</div>
</div>
</li>
</ul>
</div>
<button class="vw3-next" title="下一組" aria-label="下一組" type="button">
<i class="fa fa-angle-right" aria-hidden="true"></i>
</button>
</div>
</div>
<style>
.video_data-widget-8 {
position: relative;
.widget-title { margin-bottom: 1rem; }
/* 外層輪播框 */
.vw3-carousel {
display: flex;
align-items: center;
gap: 0.5rem;
position: relative;
}
/* 可視區域 */
.vw3-track-wrap {
overflow: hidden;
flex: 1;
}
/* 滑動軌道 */
.vw3-track {
display: flex;
align-items: center;
gap: 1rem;
list-style: none;
margin: 0;
padding: 0;
transition: transform 0.4s ease;
}
/* 所有 slide 共用 */
.vw3-slide {
flex-shrink: 0;
box-sizing: border-box;
}
/* 第一張大卡:40% 相對容器 */
.vw3-slide:nth-child(1) {
width: 40%;
position: relative;
.video_linkwrapper3 { margin-bottom: 0; }
.video_info {
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 2rem 1rem 1rem;
background: linear-gradient(to top, rgba(0,0,0,0.7) 0%, transparent 100%);
border-radius: 0 0 14px 14px;
z-index: 10;
margin: 0;
}
.video_title h4 {
color: #fff;
font-size: 1.15rem;
font-weight: 500;
margin: 0 0 0.2rem;
}
.video_desc,
.video_desc a {
color: rgba(255,255,255,0.85);
font-size: 0.85rem;
}
}
/* 後續小卡:各約 20% */
.vw3-slide:nth-child(n+2) {
width: calc(20% - 0.75rem);
.video_info {
padding: 0.5rem 0 0;
margin: 0;
}
.video_title h4 {
font-size: 0.95rem;
font-weight: 500;
color: #1a1a1a;
margin: 0 0 0.2rem;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.video_desc,
.video_desc a {
font-size: 0.82rem;
color: #666;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
}
/* 圖片共用 */
.video_linkwrapper3 {
position: relative;
aspect-ratio: 16 / 9;
overflow: hidden;
border-radius: 14px;
box-shadow: 0 2px 12px rgba(0,0,0,0.1);
transition: transform 0.22s ease, box-shadow 0.22s ease;
&:hover {
transform: translateY(-4px);
box-shadow: 0 8px 24px rgba(0,0,0,0.18);
}
img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
}
/* 播放按鈕 */
.Video__Player {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 10;
}
.Video__PlayerButton {
width: 48px;
height: 48px;
border-radius: 50%;
background: rgba(255,255,255,0.85);
border: none;
cursor: pointer;
position: relative;
&::after {
content: '';
position: absolute;
top: 50%;
left: 54%;
transform: translate(-50%, -50%);
width: 0;
height: 0;
border-style: solid;
border-width: 8px 0 8px 16px;
border-color: transparent transparent transparent #1a1a1a;
}
&:hover { background: #fff; }
}
/* 左右箭頭 */
.vw3-prev,
.vw3-next {
flex-shrink: 0;
width: 36px;
height: 36px;
border-radius: 50%;
background: rgba(0,0,0,0.15);
color: #fff;
border: none;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.2rem;
transition: background 0.2s;
z-index: 10;
&:hover { background: rgba(0,0,0,0.4); }
&:focus { outline: 2px solid #2980b9; outline-offset: 2px; }
&:disabled { opacity: 0.3; cursor: default; }
}
/* view_info */
.view_info {
position: absolute;
top: 10px;
left: 10px;
background: rgba(0,0,0,0.75);
color: #fff;
font-size: 0.8rem;
padding: 2px 8px;
border-radius: 3px;
z-index: 10;
display: flex;
align-items: center;
gap: 4px;
}
/* RWD */
@media(max-width: 768px) {
.vw3-slide:nth-child(1) { width: 100%; }
.vw3-slide:nth-child(n+2) { width: calc(50% - 0.5rem); }
}
@media(max-width: 480px) {
.vw3-slide:nth-child(n+2) { width: 100%; }
}
}
</style>
<script>
$(document).ready(function() {
var $widget = $('[data-subpart-id="{{subpart-id}}"]');
var $trackWrap = $widget.find('.vw3-track-wrap');
var $track = $widget.find('.vw3-track');
var $prevBtn = $widget.find('.vw3-prev');
var $nextBtn = $widget.find('.vw3-next');
var originalSlides = $widget.find('.vw3-slide').toArray();
var total = originalSlides.length;
if (total === 0) return;
var currentIndex = 0; // 目前第一個顯示的 slide index(在 originalSlides 裡)
// 重建 track:把所有 slide 克隆三份(前後各補一輪),讓循環無縫
function buildTrack() {
$track.empty();
// 補後一輪(讓往右循環)
$(originalSlides).each(function() {
$track.append($(this).clone().addClass('vw3-clone'));
});
// 原始
$(originalSlides).each(function() {
$track.append($(this).clone());
});
// 補前一輪(讓往左循環)
$(originalSlides).each(function() {
$track.append($(this).clone().addClass('vw3-clone'));
});
}
function getVisibleCount() {
return $(window).width() < 1024 ? 1 : 4;
}
function isMobile() {
return $(window).width() < 1024;
}
// 更新每個 slide 的寬度
function updateWidths() {
var $allSlides = $track.find('.vw3-slide');
var wrapWidth = $trackWrap.width();
var gap = 16;
var visibleCount = getVisibleCount();
var mobile = isMobile();
// 先全部清除大卡樣式
$allSlides.find('.video_info').css({
'color' : '',
'position' : '',
'bottom' : '',
'width' : '',
'padding' : '',
'background-image' : '',
'border-radius' : ''
});
$allSlides.find('.video_title h4').css({
'color' : '',
'font-size' : ''
});
if (mobile) {
// 手機:一次一則,全寬,不套大卡樣式
$allSlides.css('width', wrapWidth + 'px');
} else {
// 桌機:第一張 40%,其餘平分
var bigWidth = wrapWidth * 0.4;
var smallTotal = wrapWidth - bigWidth - gap * (visibleCount - 1);
var smallWidth = smallTotal / (visibleCount - 1);
$allSlides.css('width', smallWidth + 'px');
var firstVisibleIdx = total + currentIndex;
var $firstSlide = $allSlides.eq(firstVisibleIdx);
$firstSlide.css('width', bigWidth + 'px');
$firstSlide.find('.video_info').css({
'color' : '#fff',
'position' : 'absolute',
'bottom' : '0',
'width' : '100%',
'padding' : '2em',
'background-image' : 'linear-gradient(180deg, transparent 0, #00000066 40%, #000000a3)',
'border-radius' : '0 0 14px 14px'
});
$firstSlide.find('.video_title h4').css({
'color' : '#fff',
'font-size' : '1.5em'
});
}
}
// 計算 track 的 translateX,讓第一個顯示的 slide 對齊左邊
function getOffset(targetIdx) {
var $allSlides = $track.find('.vw3-slide');
var offset = 0;
var gap = 16;
for (var i = 0; i < targetIdx; i++) {
offset += parseFloat($allSlides.eq(i).css('width')) + gap;
}
return offset;
}
function goTo(newIndex, animate) {
currentIndex = ((newIndex % total) + total) % total;
updateWidths();
var targetIdx = total + currentIndex; // 中間那組的 index
var offset = getOffset(targetIdx);
if (animate === false) {
$track.css('transition', 'none');
$track.css('transform', 'translateX(-' + offset + 'px)');
$track[0].offsetHeight; // force reflow
$track.css('transition', '');
} else {
$track.css('transform', 'translateX(-' + offset + 'px)');
}
}
// 初始化
buildTrack();
goTo(0, false);
$prevBtn.on('click', function() {
goTo(currentIndex - 1, true);
});
$nextBtn.on('click', function() {
goTo(currentIndex + 1, true);
});
$(window).on('resize', function() {
goTo(currentIndex, false);
});
});
</script>