Files
dinner.tootaio.com/20251116/photowall/index.html
xiaomai e15d9a881c feat(ui): add founders list scrolling banner
This commit introduces a 'breaking news' style scrolling banner at the bottom of the page. The banner displays the list of the first
founders from 2005. It includes the necessary HTML structure and CSS for styling, animation, and responsiveness.
2025-11-01 21:16:30 +08:00

374 lines
11 KiB
HTML
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.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<title>动态翻页轮播图</title>
<style>
.carousel-container {
perspective: 1000px;
}
.carousel-item {
transition: transform 0.6s ease-in-out, opacity 0.6s ease-in-out;
transform-style: preserve-3d;
}
/* 响应式调整 */
@media (max-width: 768px) {
.carousel-container {
width: 100% !important;
height: 60vh !important;
}
.carousel-image {
width: 90% !important;
height: auto !important;
}
}
/* Breaking News 样式 */
.breaking-news-container {
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.3);
}
.breaking-news-label {
box-shadow: 2px 0 5px rgba(0, 0, 0, 0.2);
}
.breaking-news-content {
display: inline-block;
white-space: nowrap;
/* padding-left: 120px; 为标签留出空间 */
animation: scrollText 120s linear infinite;
}
.breaking-news-content span {
margin: 0 15px;
font-weight: bold;
}
@keyframes scrollText {
0% {
transform: translateX(100%);
}
100% {
transform: translateX(-100%);
}
}
/* 响应式调整 */
@media (max-width: 768px) {
.breaking-news-content {
font-size: 14px;
padding-left: 100px;
}
.breaking-news-label {
padding: 10px 15px;
font-size: 14px;
}
}
</style>
</head>
<body class="bg-red-500 min-h-screen flex items-center justify-center">
<div id="app">
<!-- 背景视频(在最底层)打开页面自动播放 -->
<video
src="assets/麦卉 - 前人种树后人凉《潮州劲歌金曲》.mp4"
class="absolute w-full h-full object-cover blur-2xl"
autoplay
loop
controls
></video>
<div
class="carousel-container w-screen h-screen flex items-center justify-center overflow-hidden"
>
<div class="relative w-full h-full flex items-center justify-center">
<!-- 轮播图片容器 -->
<div class="relative w-full h-full flex items-center justify-center">
<!-- 第一张图片 (prev) -->
<div
class="absolute carousel-item carousel-image h-172 w-7xl object-cover rounded-2xl shadow-2xl z-10"
:class="getImageClass(0)"
>
<img
:src="getImage(displayImages[0])"
:alt="`图片 ${displayImages[0] + 1}`"
class="w-full h-full object-cover rounded-2xl"
/>
</div>
<!-- 第二张图片 (current) -->
<div
class="absolute carousel-item carousel-image h-172 w-7xl object-cover rounded-2xl shadow-2xl z-20"
:class="getImageClass(1)"
>
<img
:src="getImage(displayImages[1])"
:alt="`图片 ${displayImages[1] + 1}`"
class="w-full h-full object-cover rounded-2xl"
/>
</div>
<!-- 第三张图片 (next) -->
<div
class="absolute carousel-item carousel-image h-172 w-7xl object-cover rounded-2xl shadow-2xl z-10"
:class="getImageClass(2)"
>
<img
:src="getImage(displayImages[2])"
:alt="`图片 ${displayImages[2] + 1}`"
class="w-full h-full object-cover rounded-2xl"
/>
</div>
<!-- 第四张图片 (helper) -->
<div
class="absolute carousel-item carousel-image h-172 w-7xl object-cover rounded-2xl shadow-2xl z-0"
:class="getImageClass(3)"
>
<img
:src="getImage(displayImages[3])"
:alt="`图片 ${displayImages[3] + 1}`"
class="w-full h-full object-cover rounded-2xl"
/>
</div>
</div>
<!-- 控制按钮 -->
<button
@click="prevSlide"
class="absolute left-4 z-30 bg-white/20 hover:bg-white/30 text-white p-3 rounded-full transition-all"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M15 19l-7-7 7-7"
/>
</svg>
</button>
<button
@click="nextSlide"
class="absolute right-4 z-30 bg-white/20 hover:bg-white/30 text-white p-3 rounded-full transition-all"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 5l7 7-7 7"
/>
</svg>
</button>
<!-- 指示器 -->
<!-- <div class="absolute bottom-4 z-30 flex space-x-2">
<button
v-for="i in images.length"
:key="i"
@click="goToSlide(i-1)"
class="w-3 h-3 rounded-full transition-all"
:class="currentIndex === i-1 ? 'bg-white' : 'bg-white/50'"
></button>
</div> -->
</div>
</div>
<!-- Breaking News 滚动条 -->
<div
class="fixed bottom-0 left-0 w-full bg-red-700 text-yellow-400 text-2xl py-3 overflow-hidden z-50 breaking-news-container"
>
<div
class="absolute left-0 top-0 bg-red-900 text-yellow-100 px-4 py-3 font-bold z-10 breaking-news-label"
>
2005年第一届创办人名表
</div>
<div class="breaking-news-content">
<span>楊吉陽(已故)</span>
<span>唐華(已故)</span>
<span>許仁菘(已故)</span>
<span>許汶信(已故)</span>
<span>劉炎松(已故)</span>
<span>楊淑清(已故)</span>
<span>黃芝芳(已故)</span>
<span>|</span>
<span>劉吉棟</span>
<span>許任隆</span>
<span>楊順發</span>
<span>吳祥森</span>
<span>林庭芝</span>
<span>林炳華</span>
<span>林庭珠</span>
<span>李玉媚</span>
<span>林應財</span>
<span>許斯杰</span>
<span>許敏捷</span>
<span>許智興</span>
<span>劉德祥</span>
<span>李豫梅</span>
<span>黄潮明</span>
<span>楊信陞</span>
<span>蔡立義</span>
<span>林炳龍</span>
<span>劉振昌</span>
<span>劉迪發</span>
<span>楊美雄</span>
<span>彭三媚</span>
<span>楊光豐</span>
<span>楊秀娥</span>
<span>莊秀清</span>
<span>李玉嬌</span>
<span>趙惜嬌</span>
<span>陳秀珠</span>
<span>張彩雁</span>
<span>劉暐康</span>
<span>王貴興</span>
<span>劉林順</span>
<span>劉益華</span>
<span>紀有平</span>
</div>
</div>
</div>
<script>
const { createApp, ref, computed, onMounted, onUnmounted } = Vue;
createApp({
setup() {
// 图片数组
const images = Array.from(
{ length: 25 },
(_, i) => `assets/image (${i + 1}).png`
);
// 当前索引
const currentIndex = ref(0);
// 显示图片的索引数组
const displayImages = ref([]);
// 初始化显示图片
const initializeDisplayImages = () => {
const len = images.length;
displayImages.value = [
(currentIndex.value - 1 + len) % len,
currentIndex.value,
(currentIndex.value + 1) % len,
(currentIndex.value + 2) % len,
];
};
// 获取图片URL
const getImage = (index) => images[index];
// 获取图片类名
const getImageClass = (position) => {
switch (position) {
case 0: // 上一张
return "scale-90 -translate-x-3/4 opacity-80";
case 1: // 当前
return "scale-100 translate-x-0 opacity-100";
case 2: // 下一张
return "scale-90 translate-x-3/4 opacity-80";
case 3: // 隐藏的搬运工
return "scale-90 translate-x-full opacity-0";
default:
return "";
}
};
// 轮播控制
const nextSlide = () => {
// 将第一个元素移到末尾
displayImages.value.push(displayImages.value.shift());
// 更新当前索引
currentIndex.value = (currentIndex.value + 1) % images.length;
// 更新最后一个元素(搬运工角色)
displayImages.value[3] = (currentIndex.value + 2) % images.length;
};
const prevSlide = () => {
// 将最后一个元素移到开头
displayImages.value.unshift(displayImages.value.pop());
// 更新当前索引
currentIndex.value =
(currentIndex.value - 1 + images.length) % images.length;
// 更新第一个元素(搬运工角色)
displayImages.value[0] =
(currentIndex.value - 1 + images.length) % images.length;
};
const goToSlide = (index) => {
const diff = index - currentIndex.value;
if (diff > 0) {
for (let i = 0; i < diff; i++) {
nextSlide();
}
} else if (diff < 0) {
for (let i = 0; i < Math.abs(diff); i++) {
prevSlide();
}
}
};
// 自动轮播
let autoPlayInterval = null;
const startAutoPlay = () => {
autoPlayInterval = setInterval(nextSlide, 3000);
};
const stopAutoPlay = () => {
if (autoPlayInterval) {
clearInterval(autoPlayInterval);
autoPlayInterval = null;
}
};
// 生命周期
onMounted(() => {
initializeDisplayImages();
startAutoPlay();
});
onUnmounted(() => {
stopAutoPlay();
});
return {
images,
currentIndex,
displayImages,
getImage,
getImageClass,
nextSlide,
prevSlide,
goToSlide,
startAutoPlay,
stopAutoPlay,
};
},
}).mount("#app");
</script>
</body>
</html>