Files
thebet365/apps/player/src/components/AnnouncementMarquee.vue

122 lines
2.5 KiB
Vue

<script setup lang="ts">
import { computed } from 'vue';
import { useRouter } from 'vue-router';
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
const router = useRouter();
const props = withDefaults(
defineProps<{ items: string[]; targetId?: string; embedded?: boolean }>(),
{ embedded: false },
);
const detailTo = computed(() =>
props.targetId ? `/announcements/${props.targetId}` : '/announcements',
);
const text = computed(() => {
const list = props.items.filter(Boolean);
if (!list.length) return '';
return list.join('  ◆  ');
});
function goDetail() {
void router.push(detailTo.value);
}
</script>
<template>
<button
v-if="text"
type="button"
class="marquee-bar"
:class="{ embedded }"
@click="goDetail"
>
<span class="marquee-badge">{{ t('home.announcement_badge') }}</span>
<div class="marquee-viewport">
<div class="marquee-track">
<span class="marquee-text">{{ text }}</span>
<span class="marquee-text" aria-hidden="true">{{ text }}</span>
</div>
</div>
</button>
</template>
<style scoped>
.marquee-bar {
width: 100%;
display: flex;
align-items: center;
gap: 10px;
margin: -4px -2px 14px;
padding: 10px 12px;
background: #141414;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
overflow: hidden;
text-decoration: none;
color: inherit;
cursor: pointer;
touch-action: manipulation;
-webkit-tap-highlight-color: transparent;
}
.marquee-bar.embedded {
margin: 0;
border: none;
border-radius: 0;
background: transparent; /* inherit parent strip's gold gradient */
}
.marquee-bar.embedded .marquee-badge {
padding: 3px 8px;
font-size: 10px;
}
.marquee-bar.embedded .marquee-text {
font-size: 12px;
}
.marquee-badge {
flex-shrink: 0;
padding: 4px 10px;
font-size: 11px;
font-weight: 800;
letter-spacing: 0.12em;
color: #1A1000;
background: var(--gradient-gold);
border: 1px solid var(--border-gold-soft);
border-radius: 4px;
}
.marquee-viewport {
flex: 1;
overflow: hidden;
min-width: 0;
mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.marquee-track {
display: flex;
width: max-content;
animation: marquee-scroll 18s linear infinite;
pointer-events: none;
}
.marquee-text {
flex-shrink: 0;
padding-right: 80px;
font-size: 13px;
font-weight: 600;
color: var(--primary-light);
white-space: nowrap;
}
@keyframes marquee-scroll {
0% { transform: translateX(0); }
100% { transform: translateX(-50%); }
}
</style>