xyyh-hhj/src/components/Index.vue
2025-02-25 18:00:42 +08:00

443 lines
9.4 KiB
Vue
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.

<template>
<div class="IndexPage">
<div class="index-title">
<div class="title-flower"></div>
</div>
<div class="location">
<div class="building index-location-bj"></div>
<div class="building index-location-xa"></div>
<div class="building index-location-sh"></div>
<div class="building index-location-wh"></div>
<div class="building index-location-gz"></div>
</div>
<div class="location-name">
<div class="place-name bj"></div>
<div class="place-name xa"></div>
<div class="place-name sh"></div>
<div class="place-name wh"></div>
<div class="place-name gz"></div>
</div>
<div class="index-line"></div>
<div class="location-mark">
<div class="mark mark-bj"></div>
<div class="mark mark-xa"></div>
<div class="mark mark-sh"></div>
<div class="mark mark-wh" @click="playFn(1)"></div>
<div class="mark mark-gz" @click="playFn(0)"></div>
</div>
<div class="top-bird-1"></div>
<div class="top-bird-2"></div>
<div class="crane-1"></div>
<div class="crane-2"></div>
<div class="boat-1"></div>
<div class="boat-2"></div>
<div class="boat-3"></div>
<div class="bottom-bird-1"></div>
<div class="bottom-cloud"></div>
<div class="xfl-icon">
<div id="frameBox"></div>
</div>
</div>
<div class="video-popup" @touchmove.prevent @click="hideVideo">
<div class="video-box">
<video ref="playerRef" class="plyr" id="player" controls>
<source src="https://cdn.plyr.io/static/our-video.mp4" type="video/mp4">
<!-- 你可以根据需要添加多个source标签支持不同的视频格式 -->
</video>
</div>
</div>
</template>
<script setup>
import gsap from 'gsap'
import Plyr from 'plyr';
import 'plyr/dist/plyr.css'; // 导入 Plyr 样式
import ImageFramePlayer from 'image-frame-player';
const playerRef = ref(null)
const frame = ref(null)
const imageFramePlayer = ref(null)
const locationId = ref(1)
// 视频库
const videoList = [
new URL(`../assets/video/gz.mp4`, import.meta.url).href,
new URL(`../assets/video/video.mp4`, import.meta.url).href,
]
// 帧图
const frameList = Array.from({ length: 35 }, (_, index) => {
return new URL(`../assets/images/xlz/xfl_${index + 1}.png`, import.meta.url).href
});
onMounted(() => {
animationFn();
palyFrame()
playerRef.value = new Plyr('#player', {
controls: ['play', 'progress', 'current-time', 'fullscreen'],
fullscreen: {
enabled: true, // 启用全屏功能
fallback: true, // 启用全屏回退
iosNative: true, // 在 iOS 上启用原生全屏
},
autoplay: true, // 自动播放
mute: false, // 初始不静音
loop: { // 循环播放
active: true
},
})
})
// 帧图初始化
const palyFrame = () => {
imageFramePlayer.value = new ImageFramePlayer({
dom: document.getElementById("frameBox"),
imgArr: frameList,
fps: 35,
useCanvas: true,
loop: -1,
yoyo: true
});
imageFramePlayer.value.play();
};
// 播放事件
const playFn = (index) => {
gsap.to(".video-popup", {
autoAlpha: 1,
duration: 0.5
});
playerRef.value.source = {
type: 'video',
sources: [
{
src: videoList[index],
type: 'video/mp4'
}
]
};
}
// 关闭弹窗
const hideVideo = () => {
gsap.to(".video-popup", {
autoAlpha: 0,
duration: 0.5
});
playerRef.value.pause();
}
// 入场动画
const animationFn = () => {
const tl = gsap.timeline({});
tl.from(".IndexPage", {
autoAlpha: 0,
scale: 1.2,
duration: 0.75,
ease: "power2.out",
onComplete: () => {
gsap.to(".title-flower", {
rotation: 360,
duration: 4,
repeat: -1,
ease: "linear",
});
gsap.to(".title-flower", {
scale: 1.5,
duration: 4,
repeat: -1,
ease: "linear",
yoyo: true,
});
gsap.to(".index-title", {
y: "-=20",
duration: 2,
repeat: -1,
ease: "linear",
yoyo: true,
});
gsap.to(".place-name", {
scale: "1.05",
y: "-=5",
duration: 2,
repeat: -1,
yoyo: true,
// ease: "back.inOut(1.7)",
})
gsap.to(".boat-1,.boat-2", {
scale: "1.05",
x: "-=30",
duration: 4,
repeat: -1,
yoyo: true,
ease: "back.inOut(1.1)",
})
gsap.to(".boat-3", {
scale: "1.05",
x: "+=30",
duration: 3,
repeat: -1,
yoyo: true,
ease: "back.inOut(2.9)",
})
gsap.to(".crane-1", {
scale: "1.1",
y: "-=10",
duration: 3,
repeat: -1,
yoyo: true,
})
gsap.to(".crane-2", {
scale: "1.1",
y: "-=10",
x: "-=20",
duration: 3,
repeat: -1,
yoyo: true,
})
}
})
.from(".index-title", {
autoAlpha: 0,
y: 20,
duration: 1,
ease: "power1.out",
})
.from(".bj,.index-location-bj", {
autoAlpha: 0,
y: -20,
duration: 1,
ease: "back.inOut(.3)",
}, 0.3)
.from(".xa,.index-location-xa", {
autoAlpha: 0,
y: -20,
duration: 1,
ease: "back.inOut(3)",
}, 0.5)
.from(".sh,.index-location-sh", {
autoAlpha: 0,
y: -20,
duration: 1,
ease: "back.inOut(3)",
}, 0.7)
.from(".wh,.index-location-wh", {
autoAlpha: 0,
y: -20,
duration: 1,
ease: "back.inOut(3)",
}, 1)
.from(".gz,.index-location-gz", {
autoAlpha: 0,
y: -20,
duration: 1,
ease: "back.inOut(3)",
}, 1.2)
}
</script>
<style lang="scss" scoped>
.IndexPage {
@include bgSrc("index/bg.jpg");
@include box(750px, 1929px);
overflow: auto;
position: relative;
.index-title {
@include bgSrc("index/title.png");
@include pos(502px, 299px, 114px, 44px);
position: relative;
pointer-events: none;
overflow: hidden;
.title-flower {
@include bgSrc("index/title-flower.png");
@include pos(58px, 56px, 246px, 79px);
}
}
.index-line {
@include bgSrc("index/line.png");
@include pos(348px, 1048px, 170px, 568px);
pointer-events: none;
}
.location {
.index-location-bj {
@include bgSrc("index/location-bj.png");
@include pos(644px, 217px, 105px, 384px);
}
.index-location-xa {
@include bgSrc("index/location-xa.png");
@include pos(303px, 319px, 36px, 647px);
}
.index-location-sh {
@include bgSrc("index/location-sh.png");
@include pos(378px, 413px, 372px, 760px);
}
.index-location-wh {
@include bgSrc("index/location-wh.png");
@include pos(192px, 229px, 94px, 1067px);
}
.index-location-gz {
@include bgSrc("index/location-gz.png");
@include pos(750px, 507px, 0px, 1402px);
}
}
.location-name {
.bj {
@include bgSrc("index/name-bj.png");
@include pos(98px, 65px, 161px, 404px);
}
.xa {
@include bgSrc("index/name-xa.png");
@include pos(98px, 65px, 190px, 658px);
}
.sh {
@include bgSrc("index/name-sh.png");
@include pos(98px, 65px, 610px, 797px);
}
.wh {
@include bgSrc("index/name-wh.png");
@include pos(98px, 66px, 266px, 1061px);
}
.gz {
@include bgSrc("index/name-gz.png");
@include pos(98px, 66px, 499px, 1389px);
}
}
.location-mark {
.mark {
@include bgSrc("index/sign-icon.png");
}
.mark-bj {
@include pos(73px, 75px, 466px, 540px);
}
.mark-xa {
@include pos(73px, 75px, 291px, 731px);
}
.mark-sh {
@include pos(73px, 75px, 393px, 976px);
}
.mark-wh {
@include pos(73px, 75px, 152px, 1348px);
}
.mark-gz {
@include pos(73px, 75px, 150px, 1558px);
}
}
.top-bird-1 {
@include bgSrc("index/top-bird-1.png");
@include pos(112px, 46px, 559px, 117px);
pointer-events: none;
}
.top-bird-2 {
@include bgSrc("index/top-bird-2.png");
@include pos(102px, 42px, 553px, 408px);
pointer-events: none;
}
.crane-1 {
@include bgSrc("index/crane-1.png");
@include pos(80px, 116px, 44px, 1147px);
pointer-events: none;
}
.crane-2 {
@include bgSrc("index/crane-2.png");
@include pos(117px, 112px, 197px, 1210px);
pointer-events: none;
}
.boat-1 {
@include bgSrc("index/boat.png");
@include pos(181px, 57px, 567px, 1156px);
pointer-events: none;
}
.boat-2 {
@include bgSrc("index/boat-2.png");
@include pos(186px, 62px, 125px, 1749px);
pointer-events: none;
}
.boat-3 {
@include bgSrc("index/boat.png");
@include pos(197px, 49px, 438px, 1834px);
pointer-events: none;
}
.bottom-bird-1 {
@include bgSrc("index/bottom-bird-1.png");
@include pos(89px, 42px, 324px, 1797px);
pointer-events: none;
}
.bottom-cloud {
@include bgSrc("index/cloud-bottom.png");
@include pos(749px, 371px, 0px, 1558px);
pointer-events: none;
}
.xfl-icon {
@include pos(163px, 153px, 245px, 679px);
#frameBox {
width: 100%;
height: 100%;
}
}
}
.video-popup {
@include fixed();
@include flexCen();
background-color: rgba($color: #000000, $alpha: .6);
visibility: hidden;
.video-box {
width: 700px;
// height: 393.75px;
border-radius: 12px;
border: 1px solid #fff;
// margin-top: -200px;
overflow: hidden;
.plyr {
// @include box(100%,100%);
}
}
}
</style>