123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400 |
- <script setup lang="ts">
- import { computed, reactive, ref } from 'vue'
- import { useEventListener, useParallax, useThrottleFn } from '@vueuse/core'
- import { useLang } from '../../composables/lang'
- import homeLocale from '../../../i18n/pages/home.json'
- import HomeSponsors from '../home/home-sponsors.vue'
- import HomeCards from '../home/home-cards.vue'
- import HomeFooter from './vp-footer.vue'
- import type { CSSProperties } from 'vue'
- const target = ref<HTMLElement | null>(null)
- const parallax = reactive(useParallax(target))
- const jumbotronRedOffset = ref(0)
- const jumbotronRef = ref<HTMLElement | null>(null)
- const lang = useLang()
- const homeLang = computed(() => homeLocale[lang.value])
- function jumpTo(path: string) {
- // vitepress has not router
- location.href = `/${lang.value}/${path}`
- }
- const containerStyle: CSSProperties = {
- display: 'flex',
- flexDirection: 'column',
- justifyContent: 'center',
- alignItems: 'center',
- transition: '.3s ease-out all',
- position: 'relative',
- perspective: '300px',
- }
- const cardStyle = computed(() => ({
- height: '30rem',
- width: '100%',
- transition: '.3s ease-out all',
- transform: `rotateX(${parallax.roll}deg) rotateY(${parallax.tilt}deg)`,
- }))
- const layerBase: CSSProperties = {
- position: 'absolute',
- width: '100%',
- height: '100%',
- transition: '.3s ease-out all',
- }
- const screenLayer = computed(() => ({
- ...layerBase,
- width: '80%',
- height: '80%',
- transform: `translateX(${parallax.tilt * 10 + 80}px) translateY(${
- parallax.roll * 10 + 50
- }px)`,
- }))
- const peopleLayer = computed(() => ({
- ...layerBase,
- width: '30%',
- height: '30%',
- right: 0,
- bottom: 0,
- transform: `translateX(${parallax.tilt * 25 + 25}px) translateY(${
- parallax.roll * 25
- }px) scale(1)`,
- }))
- // center layer
- const leftLayer = computed(() => ({
- ...layerBase,
- width: '20%',
- height: '20%',
- transform: `translateX(${parallax.tilt * 12 + 205}px) translateY(${
- parallax.roll * 12 + 210
- }px)`,
- }))
- const leftBottomLayer = computed(() => ({
- ...layerBase,
- width: '30%',
- height: '30%',
- left: 0,
- bottom: 0,
- transform: `translateX(${parallax.tilt * 30 - 10}px) translateY(${
- parallax.roll * 30
- }px)`,
- }))
- const rightLayer = computed(() => ({
- ...layerBase,
- width: '33%',
- height: '33%',
- top: 0,
- right: 0,
- transform: `translateX(${parallax.tilt * 25 + 5}px) translateY(${
- parallax.roll * 25
- }px)`,
- }))
- const handleScroll = useThrottleFn(() => {
- const ele = jumbotronRef.value
- if (ele) {
- const rect = ele.getBoundingClientRect()
- const eleHeight = ele.clientHeight
- let calHeight = (180 - rect.top) * 2
- if (calHeight < 0) calHeight = 0
- if (calHeight > eleHeight) calHeight = eleHeight
- jumbotronRedOffset.value = calHeight
- }
- }, 10)
- useEventListener(window, 'scroll', handleScroll)
- </script>
- <template>
- <div ref="target" class="home-page">
- <div class="banner" text="center">
- <div class="banner-desc" m="t-4">
- <h1>{{ homeLang['title'] }}</h1>
- <p m="t-2">{{ homeLang['title_sub'] }}</p>
- </div>
- </div>
- <div ref="jumbotronRef" class="jumbotron">
- <div class="parallax-container" :style="containerStyle">
- <div :style="cardStyle">
- <screen-svg :style="screenLayer" alt="banner" />
- <people-svg
- :style="peopleLayer"
- alt="banner"
- class="cursor-pointer"
- @click="jumpTo('guide/quickstart.html')"
- />
- <left-layer-svg :style="leftLayer" alt="banner" />
- <left-bottom-layer-svg :style="leftBottomLayer" alt="banner" />
- <right-layer-svg :style="rightLayer" alt="banner" />
- </div>
- </div>
- </div>
- <img
- src="/images/theme-index-blue.png"
- alt="banner"
- class="mobile-banner"
- />
- <HomeSponsors />
- <HomeCards />
- </div>
- <HomeFooter :is-home="true" />
- </template>
- <style lang="scss">
- @use '../../styles/mixins' as *;
- .home-page {
- .mobile-banner {
- display: none;
- }
- .banner-dot h1 span {
- position: relative;
- &::after {
- content: '';
- position: absolute;
- right: -12px;
- bottom: 8px;
- background: var(--el-color-primary);
- height: 8px;
- width: 8px;
- border-radius: 100%;
- }
- }
- .banner-desc {
- h1 {
- font-size: 34px;
- margin: 0;
- line-height: 48px;
- color: var(--text-color);
- }
- p {
- font-size: 18px;
- color: var(--text-color-light);
- }
- }
- .count-down {
- .cd-main {
- background: #f1f6fe;
- border-radius: 10px;
- width: 50%;
- margin: 60px auto 120px;
- padding: 30px 0;
- font-size: 24px;
- color: #666;
- text-align: center;
- font-weight: 600;
- }
- .cd-date {
- font-size: 28px;
- }
- .cd-time {
- display: flex;
- justify-content: space-between;
- width: 80%;
- margin: 10px auto 0;
- }
- .cd-num {
- color: var(--el-color-primary);
- font-size: 78px;
- font-weight: bold;
- }
- .cd-num span {
- width: 50%;
- display: inline-block;
- }
- .cd-str {
- font-size: 22px;
- margin-top: -5px;
- }
- }
- .jumbotron {
- width: 800px;
- margin: 20px auto;
- position: relative;
- img {
- width: 100%;
- }
- .parallax-container {
- width: 800px;
- }
- }
- @media screen and (max-width: 959px) {
- .jumbotron {
- display: none !important;
- }
- .mobile-banner {
- display: inline-block;
- }
- }
- @media (max-width: 768px) {
- .jumbotron {
- width: 50%;
- display: flex;
- margin: auto;
- justify-content: center;
- align-items: center;
- .parallax-container {
- width: 100%;
- }
- }
- }
- @media (max-width: 768px) {
- .banner-desc {
- padding-top: 0px;
- }
- .cards {
- li {
- width: 80%;
- margin: 0 auto 20px;
- float: none;
- }
- .card {
- height: auto;
- padding-bottom: 54px;
- }
- }
- .banner-stars {
- display: none;
- }
- .banner-desc {
- h1 {
- font-size: 22px;
- }
- #line2 {
- display: none;
- }
- h2 {
- font-size: 32px;
- }
- p {
- width: auto;
- }
- }
- .banner-dot h1 span {
- &::after {
- right: -8px;
- bottom: 2px;
- height: 6px;
- width: 6px;
- }
- }
- .count-down {
- .cd-main {
- width: 90%;
- margin: 40px auto 40px;
- padding: 20px 0;
- }
- .cd-date {
- font-size: 22px;
- }
- .cd-num {
- font-size: 38px;
- }
- .cd-str {
- font-size: 12px;
- margin-top: 0px;
- }
- }
- .sponsors-list {
- display: flex;
- flex-direction: column;
- align-content: center;
- .sponsor {
- justify-content: left;
- }
- }
- }
- .theme-intro-b {
- position: fixed;
- left: 0;
- right: 0;
- top: 0;
- bottom: 0;
- z-index: 200;
- .intro-banner {
- position: absolute;
- }
- img {
- width: 300px;
- }
- .title {
- position: absolute;
- top: 0;
- bottom: 0;
- left: 0;
- right: 0;
- color: #fff;
- text-align: center;
- font-weight: bold;
- font-size: 20px;
- display: flex;
- justify-content: center;
- align-items: center;
- p {
- padding: 0;
- margin: 10px 0;
- }
- }
- }
- .theme-intro-a {
- position: fixed;
- left: 0;
- right: 0;
- top: 0;
- bottom: 0;
- z-index: 200;
- .mask {
- position: fixed;
- left: 0;
- right: 0;
- top: 0;
- bottom: 0;
- background: #000;
- opacity: 0.5;
- }
- .intro-banner {
- top: 50%;
- left: 50%;
- position: fixed;
- transform: translate(-50%, -50%);
- box-sizing: border-box;
- text-align: center;
- z-index: 100;
- img {
- width: 100%;
- }
- .intro-text {
- position: absolute;
- top: 50%;
- left: 0;
- right: 0;
- p {
- padding: 0;
- margin: 0;
- font-size: 48px;
- font-weight: bold;
- color: #fff;
- }
- }
- }
- }
- }
- </style>
|