Browse Source

feat: 首页轮播图调整 增加文案

main
betaqi 2 months ago
parent
commit
94c544aa14
  1. 57
      components/SwiperFlip.vue
  2. 24
      components/pageLayout/abuot.vue
  3. 5
      components/pageLayout/device.vue
  4. 35
      components/pageLayout/electricPower.vue
  5. 2
      components/pageLayout/midele.vue
  6. 2
      components/pageLayout/serce.vue
  7. 18
      layouts/default.vue
  8. 6
      pages/aboutUs.vue
  9. 109
      pages/index.vue
  10. 14
      pages/products/BK-1000.vue
  11. 14
      pages/products/BK-2000.vue
  12. 116
      pages/test.vue
  13. 85
      pages/text.vue
  14. 28
      pnpm-lock.yaml
  15. BIN
      public/images/electricPower/c1.png
  16. BIN
      public/images/electricPower/c2.png
  17. BIN
      public/images/electricPower/c3.png
  18. BIN
      public/images/electricPower/c4.png
  19. BIN
      public/images/electricPower/c5.png

57
components/SwiperFlip.vue

@ -0,0 +1,57 @@
<template>
<ClientOnly>
<div class="swiper-card-container">
<swiper-container ref="containerRef" :init="false" :effect="'coverflow'">
<slot></slot>
</swiper-container>
<div class="swiper-cards-prev"></div>
<div class="swiper-cards-next"></div>
</div>
</ClientOnly>
</template>
<script setup>
const containerRef = ref(null)
useSwiper(containerRef, {
effect: 'cards',
grabCursor: true,
centeredSlides: true,
loop: true,
slidesPerView: 'auto',
cardsEffect: {
slideShadows: true,
perSlideOffset: 8,
},
pagination: {
el: '.swiper-pagination',
clickable: true,
},
navigation: {
nextEl: '.swiper-cards-next',
prevEl: '.swiper-cards-prev',
},
})
</script>
<style scoped>
.swiper-card-container {
width: 100%;
position: relative;
overflow: hidden;
height: 100%;
}
/* .swiper-cards-prev,
.swiper-cards-next {
@apply absolute top-0 bottom-0 w-32 z-10;
}
.swiper-cards-prev {
left: 0px;
}
.swiper-cards-next {
right: 0px;
} */
</style>

24
components/pageLayout/abuot.vue

@ -7,7 +7,7 @@
alt="公司地图背景" alt="公司地图背景"
/> />
<div <div
class="w-[1172px] h-[300px] px-[95px] md:w-[780px] md:h-[180px] sm:w-[360px] sm:h-[80px] md:px-[20px] sm:px-[10px] bg-white absolute bottom-5 md:bottom-2 sm:bottom-1 left-1/2 -translate-x-1/2 flex items-center" class="w-[1172px] h-[300px] px-[95px] md:w-[780px] md:h-[180px] sm:w-[374px] sm:h-[80px] md:px-[20px] sm:px-[8px] bg-white absolute bottom-5 md:bottom-2 sm:bottom-1 left-1/2 -translate-x-1/2 flex items-center"
> >
<div> <div>
<div class="flex flex-col"> <div class="flex flex-col">
@ -34,23 +34,22 @@
class="size-10 md:size-8 sm:size-4 mr-5 sm:mr-2" class="size-10 md:size-8 sm:size-4 mr-5 sm:mr-2"
alt="位置图标" alt="位置图标"
/> />
<span class="block sm:hidden">来访地址</span> 辉煌国际 北京市海淀区上地十街1号院 <span class="block sm:hidden">来访地址</span>
北京市海淀区西二旗辉光国际大厦西六号楼317
</div> </div>
<div class="py-7 md:py-3 sm:py-1 border-t-[1px] border-[#979797] flex items-center"> <div class="py-7 md:py-3 sm:py-1 border-t-[1px] border-[#E5E5E5] flex items-center">
<img <img
src="/images/about/phone.png" src="/images/about/phone.png"
class="size-10 md:size-8 sm:size-4 mr-5 sm:mr-2" class="size-10 md:size-8 sm:size-4 mr-5 sm:mr-2"
alt="电话图标" alt="电话图标"
/> />
<span class="block sm:hidden">服务邮箱</span> XXXXX@jsldjf.com <span class="block sm:hidden">联系电话</span> 4000996200
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div <div class="mx-auto h-[824px] md:h-auto sm:h-auto bg-cover bg-no-repeat overflow-hidden relative">
class="mx-auto h-[824px] md:h-[358px] sm:h-[198px] bg-cover bg-no-repeat overflow-hidden relative"
>
<picture class="absolute inset-0 z-0"> <picture class="absolute inset-0 z-0">
<source media="(max-width: 1024px)" srcset="/images/about/bg_sm.png" /> <source media="(max-width: 1024px)" srcset="/images/about/bg_sm.png" />
<source media="(max-width: 1025px)" srcset="/images/about/bg_lg.png" /> <source media="(max-width: 1025px)" srcset="/images/about/bg_lg.png" />
@ -63,14 +62,11 @@
<span class="text-4xl md:text-4xl sm:text-base relative -top-8">关于我们</span> <span class="text-4xl md:text-4xl sm:text-base relative -top-8">关于我们</span>
</div> </div>
<div <div
class="text-white font-bold text-center mt-17 md:mt-5 sm:mt-3 text-[28px] md:text-2xl sm:text-xs max-w-[1440px] mx-auto relative z-20 break-all px-48 md:px-20 sm:px-10" class="text-white font-bold text-center mt-17 md:mt-5 sm:mt-3 text-[28px] md:text-2xl sm:text-xs max-w-[1440px] mx-auto relative z-20 break-all px-48 pb-48 md:pb-20 sm:pb-10 md:px-20 sm:px-10"
> >
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 北京比特电科技术有限公司简称比特电科专注于为电力储能提供设备软硬件服务
</div> 公司拥有多项发明专利及软著通过了ISO9001质量体系
<div 公司以储能EMS产品为基础提供从设计到运维从边端到云端的的全链条专业服务实现用户侧能源管理的全场景覆盖为客户打造专业高效经济省心开放赋能的数智化能源管理解决方案从而助力客户构筑自有产品的差异化竞争壁垒共创生态多赢新格局
class="font-bold text-center mt-13 md:mt-5 sm:mt-3 text-3xl md:text-base sm:text-xs text-[#15A351]"
>
了解更多>>
</div> </div>
</div> </div>
</template> </template>

5
components/pageLayout/device.vue

@ -15,9 +15,10 @@
<TabsContent value="BK-1000" class="size-full"> <TabsContent value="BK-1000" class="size-full">
<ClientOnly> <ClientOnly>
<!-- background-position-x: -20px; -->
<div <div
style="background-image: url('/images/deviceInterface/head_bg.png')" style="background-image: url('/images/deviceInterface/head_bg.png')"
class="tabs-content-head" class="tabs-content-head [background-position-x:-20px] sm:[background-position-x:-10px]"
> >
<span class="text-white text-xl md:text-xl sm:text-[10px] font-bold" <span class="text-white text-xl md:text-xl sm:text-[10px] font-bold"
>BK-1000 参数表</span >BK-1000 参数表</span
@ -41,7 +42,7 @@
<ClientOnly> <ClientOnly>
<div <div
style="background-image: url('/images/deviceInterface/head_bg.png')" style="background-image: url('/images/deviceInterface/head_bg.png')"
class="tabs-content-head" class="tabs-content-head [background-position-x:-20px] sm:[background-position-x:-10px]"
> >
<span class="text-white text-xl md:text-xl sm:text-[10px] font-bold" <span class="text-white text-xl md:text-xl sm:text-[10px] font-bold"
>BK-2000 参数表</span >BK-2000 参数表</span

35
components/pageLayout/electricPower.vue

@ -11,25 +11,16 @@
<div <div
class="relative w-full h-[calc(100%-136px)] md:h-[calc(100%-100px)] sm:h-[calc(100%-60px)] z-20 text-white max-w-[1440px] mx-auto flex items-center justify-center gap-10" class="relative w-full h-[calc(100%-136px)] md:h-[calc(100%-100px)] sm:h-[calc(100%-60px)] z-20 text-white max-w-[1440px] mx-auto flex items-center justify-center gap-10"
> >
<div class="md:hidden sm:hidden"> <div
<div class="flex gap-8 justify-center items-center"> class="w-[494px] h-[672px] md:w-[286px] md:h-[378px] sm:w-[142px] sm:h-[188px] select-none"
<img src="/images/electricPower/c1.png" loading="eager" class="w-[419px] h-[582px]" /> >
<img src="/images/electricPower/c2.png" loading="eager" class="w-[419px] h-[582px]" /> <SwiperFlip>
</div> <swiper-slide v-for="(movie, index) in imgList" :key="index" class="size-[90%]">
</div> <div class="w-full h-full">
<div class="hidden md:block sm:block"> <img :src="movie" alt="" class="w-full h-full object-cover" />
<div class="flex gap-8 md:gap-4 sm:gap-2 justify-center items-center"> </div>
<img </swiper-slide>
src="/images/electricPower/c1.png" </SwiperFlip>
loading="eager"
class="md:w-[178px] md:h-[252px] sm:w-[89px] sm:h-[126px]"
/>
<img
src="/images/electricPower/c2.png"
loading="eager"
class="md:w-[178px] md:h-[252px] sm:w-[89px] sm:h-[126px]"
/>
</div>
</div> </div>
<div <div
@ -64,6 +55,12 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
const imgList = [
'/images/electricPower/c1.png',
'/images/electricPower/c5.png',
'/images/electricPower/c3.png',
'/images/electricPower/c4.png',
]
const electricPowerList = [ const electricPowerList = [
{ {
title: '电气安全', title: '电气安全',

2
components/pageLayout/midele.vue

@ -29,7 +29,7 @@
{{ item.title }} {{ item.title }}
</h3> </h3>
<div <div
class="text-[#A4B0B7] flex flex-col mt-21 md:mt-6 sm:mt-3 items-center text-3xl md:text-base sm:text-[8px] sm:leading-[14px] gap-9 md:gap-4 sm:gap-2" class="text-[#A4B0B7] flex flex-col mt-21 md:mt-6 sm:mt-3 items-center text-3xl md:text-base sm:text-[10px] sm:leading-[10px] gap-9 md:gap-4 sm:gap-2"
> >
<p v-for="(content, idx) in item.contentList" :key="idx" class="text-center"> <p v-for="(content, idx) in item.contentList" :key="idx" class="text-center">
{{ content }} {{ content }}

2
components/pageLayout/serce.vue

@ -27,7 +27,7 @@
</div> </div>
</div> </div>
<div class="hidden md:block sm:block"> <div class="hidden md:block sm:block">
<div class="flex flex-wrap gap-4 mx-auto justify-center size-full"> <div class="flex flex-wrap gap-4 mx-auto justify-center size-full sm:gap-2">
<div <div
v-for="(item, idx) in serveList" v-for="(item, idx) in serveList"
:key="idx" :key="idx"

18
layouts/default.vue

@ -6,12 +6,14 @@
<div <div
class="max-w-[1920px] mx-auto flex h-17 sm:h-13 w-full items-center justify-between px-28 sm:px-6 md:px-[88px] peer" class="max-w-[1920px] mx-auto flex h-17 sm:h-13 w-full items-center justify-between px-28 sm:px-6 md:px-[88px] peer"
> >
<h1 class="text-3xl md:text-2xl sm:text-base font-bold relative z-20"> <h1 class="font-bold relative z-20">
<NuxtLink to="/"> <LetterPullup <NuxtLink to="/">
<LetterPullup
words="BTDK" words="BTDK"
:delay="0.05" :delay="0.05"
class="text-[#52AC63]"" class="text-[#52AC63] text-3xl md:text-2xl sm:text-base"
/> </NuxtLink> />
</NuxtLink>
</h1> </h1>
<nav class="absolute inset-0"> <nav class="absolute inset-0">
<ul <ul
@ -133,7 +135,7 @@
</Menu> </Menu>
</div> </div>
<div <div
class="absolute h-17 top-0 w-full -z-10 peer-hover:backdrop-blur-2xl peer-hover:bg-[rgba(92,92,92,0.4)] peer-hover:bg-gradient-to-r peer-hover:from-black/50 peer-hover:to-black/50" class="absolute mx-auto flex sm:h-13 items-center justify-between px-28 sm:px-6 md:px-[88px] h-17 top-0 w-full -z-10 peer-hover:backdrop-blur-2xl peer-hover:bg-[rgba(92,92,92,0.4)] peer-hover:bg-gradient-to-r peer-hover:from-black/50 peer-hover:to-black/50"
:class="{ :class="{
'backdrop-blur-2xl': isScrolled || isNavbarOpen, 'backdrop-blur-2xl': isScrolled || isNavbarOpen,
'header-bg': isScrolled, 'header-bg': isScrolled,
@ -143,12 +145,12 @@
<slot /> <slot />
<footer> <footer>
<div <div
class="relative flex flex-row justify-between items-center text-sm font-regular bg-[#2D2D2F] md:flex-col p-4" class="relative flex flex-row justify-between sm:justify-center items-center text-sm font-regular bg-[#2D2D2F] md:flex-col p-4 sm:p-2 sm:text-xs"
> >
<div> <div>
<!-- <span class="text-[#18AA56] text-[90px] leading-[100px] font-bold">BTDK</span> --> <!-- <span class="text-[#18AA56] text-[90px] leading-[100px] font-bold">BTDK</span> -->
<div class="flex items-center text-sm text-white opacity-60 pl-2 gap-x-2"> <div class="flex items-center text-sm text-white opacity-60 pl-2 gap-x-2 sm:flex-col">
<p class="mr-2 lg:mr-0">©比特电科技有限公司</p> <p class="mr-2 lg:mr-0">©比特电科技有限公司</p>
<p class="mr-2 flex items-center"> <p class="mr-2 flex items-center">
<img <img
class="size-4 object-cover" class="size-4 object-cover"

6
pages/aboutUs.vue

@ -38,17 +38,17 @@ const aboutUs = [
title: '公司简介', title: '公司简介',
icon: '/images/aboutUs/company.png', icon: '/images/aboutUs/company.png',
content: content:
'比特电科是一家专注于提供EM系列储能边缘智能网关,为工业控制、能源管理提供高性能、高可靠性的解决方案。', ' 北京比特电科技术有限公司,简称(比特电科),专注于为电力储能提供设备软硬件服务,公司拥有多项发明专利及软著,通过了ISO9001质量体系。 公司以储能EMS产品为基础,提供从设计到运维,从边端到云端的的全链条专业服务。实现用户侧能源管理的全场景覆盖,为客户打造专业高效、经济省心、开放赋能的数智化能源管理解决方案,从而助力客户构筑自有产品的差异化竞争壁垒,共创生态多赢新格局。',
}, },
{ {
title: '企业地址', title: '企业地址',
icon: '/images/aboutUs/location.png', icon: '/images/aboutUs/location.png',
content: '北京市海淀区上地十街1号院', content: '北京市海淀区西二旗辉光国际大厦西六号楼317',
}, },
{ {
title: '企业联系人', title: '企业联系人',
icon: '/images/aboutUs/user.png', icon: '/images/aboutUs/user.png',
content: '8888-88888888', content: '4000996200',
}, },
] ]
</script> </script>

109
pages/index.vue

@ -3,7 +3,62 @@
<div <div
class="relative h-[428px] w-full bg-gradient-to-b from-[#0C0C16] to-[#080809] lg:h-[888px]" class="relative h-[428px] w-full bg-gradient-to-b from-[#0C0C16] to-[#080809] lg:h-[888px]"
> >
<ClientOnly> <div class="size-full mx-auto overflow-hidden relative" ref="emblaNode">
<div class="size-full flex">
<div v-for="(slide, idx) in slides" :key="idx" class="size-full flex-[0_0_100%]">
<div class="size-full relative flex overflow-hidden items-center sm:items-start">
<picture class="absolute w-full h-full left-0 top-0 -z-10">
<source media="(max-width: 480px)" :srcset="slide.bgSm" />
<source media="(max-width: 1280px)" :srcset="slide.bgLg" />
<img
:src="slide.bgLg"
class="size-full object-cover"
loading="lazy"
:fetchpriority="idx === 0 ? 'high' : 'low'"
/>
</picture>
<div class="w-[1440px] md:w-[870px] sm:w-[300px] sm:top-19 relative mx-auto">
<div class="swiper-banner-info">
<h6 class="text-2xl md:text-lg lg:text-xl sm:text-xs font-bold">
{{ slide.title }}
</h6>
<h2
class="text-4xl lg:text-3xl md:text-2xl sm:text-base overflow-hidden font-bold text-ellipsis whitespace-pre-line break-words"
>
{{ slide.subtitle }}
</h2>
<div v-if="slide.tags" class="flex text-lg lg:text-base md:text-base sm:text-sm">
<p
v-for="(tag, index) in slide.tags"
:key="index"
:class="tag.clx"
class="bg-cover bg-no-repeat bg-center bg-size-full flex items-center justify-center"
:style="{
backgroundImage: `url(${tag.bg})`,
}"
>
{{ tag.name }}
</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div
class="absolute bottom-[4%] left-1/2 -translate-x-1/2 flex gap-2 md:gap-[6px] sm:gap-1 z-10 bg-red"
>
<button
v-for="(_, index) in slides"
:key="index"
:class="{ 'active-slide': emblaState.selectedIndex == index }"
class="w-12 h-2 md:w-9 md:h-[6px] sm:w-6 sm:h-1 bg-[#818897] opacity-30"
@click="scrollTo(index)"
/>
</div>
</div>
<!-- <ClientOnly>
<swiper-container <swiper-container
ref="containerRef" ref="containerRef"
class="size-full mx-auto" class="size-full mx-auto"
@ -45,7 +100,7 @@
</div> </div>
</swiper-slide> </swiper-slide>
</swiper-container> </swiper-container>
</ClientOnly> </ClientOnly> -->
</div> </div>
<Serve /> <Serve />
<Device /> <Device />
@ -67,7 +122,9 @@ import ElectricPower from '@/components/pageLayout/electricPower.vue'
import CloudData from '@/components/pageLayout/cloudData.vue' import CloudData from '@/components/pageLayout/cloudData.vue'
import Operation from '@/components/pageLayout/operation.vue' import Operation from '@/components/pageLayout/operation.vue'
import About from '@/components/pageLayout/abuot.vue' import About from '@/components/pageLayout/abuot.vue'
import EmblaCarousel from 'embla-carousel'
const emblaNode = ref<any>(null)
const embla = ref<any>(null)
// SEO // SEO
useSeoMeta({ useSeoMeta({
title: '比特电科 - 智能边缘网关解决方案', title: '比特电科 - 智能边缘网关解决方案',
@ -125,6 +182,21 @@ const slides = [
], ],
}, },
] ]
const emblaState = reactive({
selectedIndex: 0,
})
const scrollTo = (index: number) => embla.value?.scrollTo(index)
function updateOnSelect() {
emblaState.selectedIndex = embla.value.selectedScrollSnap()
// state.canScrollPrev = embla.value.canScrollPrev()
// state.canScrollNext = embla.value.canScrollNext()
}
onMounted(() => {
embla.value = EmblaCarousel(emblaNode.value, { loop: true })
embla.value.on('select', updateOnSelect)
})
</script> </script>
<style> <style>
@ -135,7 +207,9 @@ const slides = [
.title-font { .title-font {
@apply text-5xl md:text-4xl sm:text-lg font-bold text-center text-white; @apply text-5xl md:text-4xl sm:text-lg font-bold text-center text-white;
} }
.active-slide {
opacity: 1;
}
/* Swiper分页器样式 */ /* Swiper分页器样式 */
:root { :root {
--swiper-pagination-color: #818897; --swiper-pagination-color: #818897;
@ -146,31 +220,4 @@ const slides = [
--swiper-pagination-bullet-inactive-opacity: 0.3; --swiper-pagination-bullet-inactive-opacity: 0.3;
--swiper-pagination-bullet-horizontal-gap: 8px; --swiper-pagination-bullet-horizontal-gap: 8px;
} }
/* 响应式分页器 - 移动端 */
@media (max-width: 479px) {
:root {
--swiper-pagination-bullet-width: 24px;
--swiper-pagination-bullet-height: 4px;
--swiper-pagination-bullet-horizontal-gap: 4px;
}
}
/* 响应式分页器 - 平板 */
@media (min-width: 480px) and (max-width: 1024px) {
:root {
--swiper-pagination-bullet-width: 36px;
--swiper-pagination-bullet-height: 6px;
--swiper-pagination-bullet-horizontal-gap: 6px;
}
}
/* 响应式分页器 - 大屏 */
@media (min-width: 1025px) {
:root {
--swiper-pagination-bullet-width: 48px;
--swiper-pagination-bullet-height: 8px;
--swiper-pagination-bullet-horizontal-gap: 8px;
}
}
</style> </style>

14
pages/products/BK-1000.vue

@ -76,7 +76,7 @@ const slide = {
{ label: '处理器', value: ['双核Cortex-A7,1.2GHz 工业级'] }, { label: '处理器', value: ['双核Cortex-A7,1.2GHz 工业级'] },
{ label: '内存', value: ['512M'] }, { label: '内存', value: ['512M'] },
{ label: '板载存储', value: ['4G'] }, { label: '板载存储', value: ['4G'] },
{ label: '操作系统', value: ['Linux-Buildroot '] }, { label: '操作系统', value: ['Linux-Buildroot'] },
], ],
}, },
], ],
@ -100,13 +100,13 @@ const slide = {
{ {
column: 1, column: 1,
items: [ items: [
{ label: 'RS485', value: ['6路'] }, { label: 'RS485', value: ['6路 隔离方案,抗干扰性强,电力四级'] },
{ label: 'CAN', value: ['2路'] }, { label: 'CAN', value: ['2路 隔离方案,抗干扰性强,电力四级'] },
{ label: 'DO', value: ['4路'] }, { label: 'DO', value: ['4路 隔离方案,3路常开,1路转换,电力四级'] },
{ label: 'DI', value: ['4路'] }, { label: 'DI', value: ['4路 隔离方案,抗干扰性强,电力四级'] },
{ label: '以太网', value: ['2路'] }, { label: '以太网', value: ['2路 工业级 防雷击浪涌'] },
{ label: '显示接口', value: ['无'] }, { label: '显示接口', value: ['无'] },
{ label: 'USB-A', value: ['2路'] }, { label: 'USB-A', value: ['2路 工业级'] },
{ label: '调试接口', value: ['1路,Type-C'] }, { label: '调试接口', value: ['1路,Type-C'] },
], ],
}, },

14
pages/products/BK-2000.vue

@ -100,13 +100,13 @@ const slide = {
{ {
column: 1, column: 1,
items: [ items: [
{ label: 'RS485', value: ['8路'] }, { label: 'RS485', value: ['8 隔离方案,抗干扰性强,电力四级'] },
{ label: 'CAN', value: ['2路'] }, { label: 'CAN', value: ['2路 隔离方案,抗干扰性强,电力四级'] },
{ label: 'DO', value: ['10路'] }, { label: 'DO', value: ['10路 隔离方案,6路常开,4路转换,电力四级'] },
{ label: 'DI', value: ['10路'] }, { label: 'DI', value: ['10路 隔离方案,抗干扰性强,电力四级'] },
{ label: '以太网', value: ['4路'] }, { label: '以太网', value: ['4路 工业级 防雷击浪涌'] },
{ label: '显示接口', value: ['DVI(lvds)'] }, { label: '显示接口', value: ['DVI(lvds) 工业级'] },
{ label: 'USB-A', value: ['4路'] }, { label: 'USB-A', value: ['4路 工业级 '] },
{ label: '调试接口', value: ['1路,Type-C'] }, { label: '调试接口', value: ['1路,Type-C'] },
], ],
}, },

116
pages/test.vue

@ -0,0 +1,116 @@
<template>
<div class="embla">
<div class="embla__viewport" ref="emblaNode">
<div class="embla__container">
<div class="embla__slide" v-for="(slide, index) in slides" :key="index">
<img :src="slide" alt="" />
</div>
</div>
</div>
<!-- 左右箭头 -->
<button class="embla__button prev" @click="scrollPrev" :disabled="!canScrollPrev"></button>
<button class="embla__button next" @click="scrollNext" :disabled="!canScrollNext"></button>
<!-- 圆点导航 -->
<div class="embla__dots">
<button
v-for="(_, index) in slides"
:key="index"
:class="{ 'is-selected': state.selectedIndex == index }"
@click="scrollTo(index)"
>
{{}}
</button>
</div>
</div>
</template>
<script setup>
import { onMounted, ref, reactive } from 'vue'
import EmblaCarousel from 'embla-carousel'
const emblaNode = ref(null)
const embla = ref(null)
const state = reactive({
selectedIndex: 0,
canScrollPrev: false,
canScrollNext: false,
})
const slides = ['/images/banner/bk1000.png', '/images/banner/bk2000.png']
const updateButtons = () => {
if (!embla.value) return
state.canScrollPrev = embla.value.canScrollPrev()
state.canScrollNext = embla.value.canScrollNext()
state.selectedIndex = embla.value.selectedScrollSnap()
}
const scrollPrev = () => embla.value?.scrollPrev()
const scrollNext = () => embla.value?.scrollNext()
const scrollTo = index => embla.value?.scrollTo(index)
onMounted(() => {
embla.value = EmblaCarousel(emblaNode.value, { loop: true })
const updateOnSelect = () => {
state.selectedIndex = embla.value.selectedScrollSnap()
state.canScrollPrev = embla.value.canScrollPrev()
state.canScrollNext = embla.value.canScrollNext()
}
embla.value.on('select', updateOnSelect)
})
</script>
<style scoped>
.embla {
position: relative;
}
.embla__viewport {
overflow: hidden;
}
.embla__container {
display: flex;
}
.embla__slide {
flex: 0 0 100%;
padding: 10px;
}
.embla__button {
position: absolute;
top: 50%;
transform: translateY(-50%);
background: #00000088;
color: white;
border: none;
padding: 10px;
cursor: pointer;
z-index: 1;
}
.embla__button.prev {
left: 10px;
}
.embla__button.next {
right: 10px;
}
.embla__dots {
display: flex;
justify-content: center;
gap: 8px;
margin-top: 10px;
}
.embla__dots button {
width: 10px;
height: 10px;
border-radius: 50%;
border: none;
background: #ccc;
cursor: pointer;
}
.embla__dots .is-selected {
background: #333;
}
</style>

85
pages/text.vue

@ -1,85 +0,0 @@
<template>
<ul
class="grid grid-cols-1 grid-rows-none gap-4 overflow-auto xl:max-h-[56rem] xl:grid-rows-2 lg:gap-4 md:grid-cols-12 md:grid-rows-3"
>
<li
v-for="item in gridItems"
:key="item.title"
:class="cn('min-h-[14rem] list-none', item.area)"
>
<div class="rounded-2.5xl relative h-full border p-2 md:rounded-3xl md:p-3">
<GlowingEffect
:spread="40"
:glow="true"
:disabled="false"
:proximity="64"
:inactive-zone="0.01"
/>
<div
class="border-0.75 relative flex h-full flex-col justify-between gap-6 overflow-hidden rounded-xl p-6 md:p-6 dark:shadow-[0px_0px_27px_0px_#2D2D2D]"
>
<div class="relative flex flex-1 flex-col justify-between gap-3">
<div class="w-fit rounded-lg border border-gray-600 p-2">
<Icon class="size-4 text-black dark:text-neutral-500" :name="item.icon"></Icon>
</div>
<div class="space-y-3">
<h3
class="-tracking-4 text-balance pt-0.5 font-sans text-xl/[1.375rem] font-semibold text-black md:text-2xl/[1.875rem] dark:text-white"
>
{{ item.title }}
</h3>
<h2
class="font-sans text-sm/[1.125rem] text-black md:text-base/[1.375rem] dark:text-neutral-400 [&_b]:md:font-semibold [&_strong]:md:font-semibold"
>
{{ item.description }}
</h2>
</div>
</div>
</div>
</div>
</li>
</ul>
</template>
<script lang="ts" setup>
import GlowingEffect from '@/components/ui/glowing-effect/GlowingEffect.vue'
import { cn } from '@/lib/utils'
const gridItems = [
{
area: 'md:[grid-area:1/1/2/7] xl:[grid-area:1/1/2/5]',
icon: 'lucide:box',
title: 'Unbox Endless Possibilities',
description:
'Open up Inspira UI to discover so many features, you’ll wonder if you’ve wandered into a magical subscription for infinite goodies.',
},
{
area: 'md:[grid-area:1/7/2/13] xl:[grid-area:2/1/3/5]',
icon: 'lucide:settings',
title: 'Crank the Dials to Eleven',
description:
'We packed Inspira UI with enough customizable settings to keep you tweaking forever. If it’s broken, you probably forgot to flip one more switch!',
},
{
area: 'md:[grid-area:2/1/3/7] lg:[grid-area:1/5/3/8]',
icon: 'lucide:music',
title: 'Dance Your Way to Better UI',
description:
'Forget dull interfaces—Inspira UI brings your Vue and Nuxt apps to life with animations so smooth, you’ll wonder!',
},
{
area: 'md:[grid-area:2/7/3/13] xl:[grid-area:1/8/2/13]',
icon: 'lucide:sparkles',
title: 'Spark a Little Magic',
description:
'Make your interface shine brighter than your future. Inspira UI turns that dull design into an enchanting experience—fairy dust included!',
},
{
area: 'md:[grid-area:3/1/4/13] xl:[grid-area:2/8/3/13]',
icon: 'lucide:search',
title: 'Seek and You Shall Find',
description:
'Our search is so advanced it might unearth your lost socks. Just don’t blame us when you realize they don’t match!',
},
]
</script>

28
pnpm-lock.yaml

@ -17,6 +17,9 @@ importers:
class-variance-authority: class-variance-authority:
specifier: ^0.7.1 specifier: ^0.7.1
version: 0.7.1 version: 0.7.1
embla-carousel-vue:
specifier: ^8.6.0
version: 8.6.0(vue@3.5.13(typescript@5.6.3))
lucide-vue-next: lucide-vue-next:
specifier: ^0.486.0 specifier: ^0.486.0
version: 0.486.0(vue@3.5.13(typescript@5.6.3)) version: 0.486.0(vue@3.5.13(typescript@5.6.3))
@ -1591,6 +1594,19 @@ packages:
electron-to-chromium@1.5.137: electron-to-chromium@1.5.137:
resolution: {integrity: sha512-/QSJaU2JyIuTbbABAo/crOs+SuAZLS+fVVS10PVrIT9hrRkmZl8Hb0xPSkKRUUWHQtYzXHpQUW3Dy5hwMzGZkA==} resolution: {integrity: sha512-/QSJaU2JyIuTbbABAo/crOs+SuAZLS+fVVS10PVrIT9hrRkmZl8Hb0xPSkKRUUWHQtYzXHpQUW3Dy5hwMzGZkA==}
embla-carousel-reactive-utils@8.6.0:
resolution: {integrity: sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==}
peerDependencies:
embla-carousel: 8.6.0
embla-carousel-vue@8.6.0:
resolution: {integrity: sha512-v8UO5UsyLocZnu/LbfQA7Dn2QHuZKurJY93VUmZYP//QRWoCWOsionmvLLAlibkET3pGPs7++03VhJKbWD7vhQ==}
peerDependencies:
vue: ^3.2.37
embla-carousel@8.6.0:
resolution: {integrity: sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==}
emoji-regex@8.0.0: emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
@ -5215,6 +5231,18 @@ snapshots:
electron-to-chromium@1.5.137: {} electron-to-chromium@1.5.137: {}
embla-carousel-reactive-utils@8.6.0(embla-carousel@8.6.0):
dependencies:
embla-carousel: 8.6.0
embla-carousel-vue@8.6.0(vue@3.5.13(typescript@5.6.3)):
dependencies:
embla-carousel: 8.6.0
embla-carousel-reactive-utils: 8.6.0(embla-carousel@8.6.0)
vue: 3.5.13(typescript@5.6.3)
embla-carousel@8.6.0: {}
emoji-regex@8.0.0: {} emoji-regex@8.0.0: {}
emoji-regex@9.2.2: {} emoji-regex@9.2.2: {}

BIN
public/images/electricPower/c1.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 428 KiB

After

Width:  |  Height:  |  Size: 400 KiB

BIN
public/images/electricPower/c2.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 428 KiB

BIN
public/images/electricPower/c3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

BIN
public/images/electricPower/c4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 685 KiB

BIN
public/images/electricPower/c5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 KiB

Loading…
Cancel
Save