Преглед изворни кода

+ Swiper 컴포넌트 타입 적용

송용우 пре 1 месец
родитељ
комит
be79a0221b

+ 221 - 3
app/assets/scss/admin.scss

@@ -148,6 +148,8 @@
       margin: 88px auto 0 auto;
       padding: 40px;
       border-radius: 20px;
+      left: 4%;
+      flex-basis: 44%;
       h2{
         margin: 0px;
         color: rgb(252, 252, 253);    
@@ -197,8 +199,76 @@
 //Swiper 배너 컴포넌트 (30% + 70% 레이아웃)
 .swiper--banner--wrapper {
   width: 100%;
-  padding: 40px 96px;  
-  background: #000;
+  padding: 40px 96px;    
+
+  &[data-type="vertical"]{
+    padding:0px;
+    .swiper--banner--container{
+      flex-direction: column-reverse;
+      height:auto;   
+ 
+      .swiper--controls--section{            
+        flex-direction: row-reverse;
+        @media(min-width:768px){
+          padding: 0px 96px;
+        }
+        @media(min-width:1024px){
+          padding: 0px 96px;
+        }
+        @media(min-width:1440px){
+          padding: 0px 96px;
+        }
+        @media(min-width:1920px){          
+          padding:24px 96px;
+        }
+
+        .text--content{
+          width:100%;
+
+          .main--title{
+            margin: 0px;
+            color: rgb(252, 252, 253);
+            font-family: AudiType, sans-serif;
+            letter-spacing: 0px;
+            font-weight: 400;
+            text-decoration: none;
+            font-size: 20px;
+            line-height: 32px;
+            font-stretch: 130%;
+
+            @media(min-width:1440px){              
+              font-size: 24px;
+              line-height: 36px;
+            }
+          }
+
+          .sub--title{
+            margin: 0px;
+            color: rgba(252, 252, 253, 0.7);            
+            letter-spacing: 0px;
+            font-weight: 400;
+            text-decoration: none;
+            font-size: 16px;
+            line-height: 24px;
+            font-stretch: 105%;
+          }
+        }
+      }
+
+      > div{
+        width:100%;
+        max-height:100vh;
+        .swiper--container {
+        
+          .swiper-slide {
+            .slide--image {
+              border-radius: 0px;
+            }
+          }
+        }
+      }
+    }
+  }
   
   .swiper--banner--container {
     max-width: 1920px;
@@ -206,6 +276,8 @@
     margin: 0 auto;
     display: flex;
     min-height: 600px;
+
+   
     
     // 30% 영역: 컨트롤 및 텍스트
     .swiper--controls--section {
@@ -236,7 +308,7 @@
             .swiper-pagination-bullet {
               width: 24px;
               height: 24px;
-              background: rgba(255, 255, 255, 0.1);              
+              // background: rgba(255, 255, 255, 0.1);              
               border-radius: 50%;
               color: rgba(255, 255, 255, 0.6);
               font-size: 14px;
@@ -360,6 +432,17 @@
           line-height: 24px;
           font-stretch: 105%;
         }
+
+        .desc--title{
+          margin-top:25px;
+          color: rgba(252, 252, 253, 0.7);          
+          letter-spacing: 0px;
+          font-weight: 400;
+          text-decoration: none;
+          font-size: 15px;
+          line-height: 24px;
+          font-stretch: 105%;
+        }
         
         .notice--text {
           margin-top: 40px;
@@ -464,6 +547,141 @@
   }
 }
 
+
+.title--visual {
+  position: relative;
+  width: 100%;  
+  overflow: hidden;
+  padding:40px 0px;
+
+  
+  // 테마별 스타일
+  &[data-theme="dark"] {    
+    color: rgb(252, 252, 253);
+    
+    .title--description {
+      color: rgba(252, 252, 253, 0.8);
+    }
+  }
+  
+  &[data-theme="light"] {
+    background: rgb(252, 252, 253);
+    color: #000;
+    
+    .title--description {
+      color: rgba(0, 0, 0, 0.7);
+    }
+  }
+  
+  .title--visual--wrapper {    
+    margin: 0 auto;
+    padding: 0 60px;
+    align-content: center;
+    box-sizing: content-box;
+    display: grid;
+    grid-template-columns: 100%;  
+    padding-bottom: 0px;
+    padding-top: 0px;
+
+    @media (min-width:1920px){
+      margin: 0 auto;
+      max-width:1248px;
+    }
+    
+    @media (max-width: 1024px) {
+      padding: 0 40px;
+    }
+    
+    @media (max-width: 768px) {
+      padding: 0 20px;
+    }
+  }
+  
+  .title--visual--content {    
+    margin: 0 auto;
+    
+    &[data-align="left"] {
+      margin-left: 0;
+      text-align: left;
+    }
+    
+    &[data-align="center"] {
+      text-align: center;
+    }
+    
+    &[data-align="right"] {
+      margin-right: 0;
+      margin-left: auto;
+      text-align: right;
+    }
+    
+    // 애니메이션 상태
+    &[data-animated="true"] {
+      opacity: 0;
+      transform: translateY(40px);
+      transition: all 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94);
+      
+      &.visible {
+        opacity: 1;
+        transform: translateY(0);
+      }
+    }
+  }
+  
+  .title--main {        
+
+    margin: 0 0 24px 0;
+    color: rgb(252, 252, 253);    
+    letter-spacing: 0px;
+    font-weight: 400;
+    text-decoration: none;
+    font-size: 36px;
+    line-height: 52px;
+    font-stretch: 130%;
+
+    overflow-wrap: break-word;
+    text-align: center;
+    
+    @media (max-width: 1920px) {
+      font-size: 72px;
+      line-height: 100px;
+    }
+
+    @media (max-width: 1440px) {
+      font-size: 60px;
+      line-height: 84px;
+    }
+
+    @media (max-width: 1024px) {
+      font-size: 52px;
+      line-height: 76px;
+    }
+    
+    @media (max-width: 768px) {
+      font-size: 44px;
+      line-height: 60px;      
+    }
+  }
+  
+  .title--description {
+    margin: 0;    
+    color: rgba(252, 252, 253, 0.7);    
+    letter-spacing: 0px;
+    font-weight: 400;
+    text-decoration: none;
+    font-size: 16px;
+    line-height: 24px;
+    font-stretch: 105%;        
+  }
+  
+  .title--additional {
+    margin-top: 40px;
+    
+    @media (max-width: 768px) {
+      margin-top: 32px;
+    }
+  }
+}
 /*=================================================
 |컴포넌트 별 css
 |END

+ 6 - 6
app/assets/scss/responsive.scss

@@ -13,7 +13,7 @@
     .prallax--banner{}
     .text--box--wrapper{
       .text--container{
-        margin:88px 0px 0px;
+        margin:120px 0px 0px;
         h2{
           font-size: 36px;
           line-height: 52px;
@@ -29,16 +29,12 @@
       font-size: 40px;
     }
   }
-}
-
-@media (min-width:1440px) {
   .prallax--banner--wrapper{
     height:1600px;
     .prallax--banner{}
     .text--box--wrapper{
       .text--container{
-        left: 4%;
-        flex-basis: 44%;
+       
         margin: 88px 0 0;
         h2{
           font-size: 32px;
@@ -49,6 +45,10 @@
   }
 }
 
+@media (min-width:1440px) {
+  
+}
+
 @media (min-width:1024px) and (max-width:1439px) { 
   .img--section--full {  
     img {

+ 15 - 1
app/components/block/SwiperBanner.vue

@@ -1,5 +1,5 @@
 <template>
-  <section class="swiper--banner--wrapper">
+  <section class="swiper--banner--wrapper" :data-type="type">
     <div class="swiper--banner--container">
       <!-- 30% 영역: 컨트롤 및 텍스트 -->
       <div class="swiper--controls--section">
@@ -47,6 +47,7 @@
             >
               <h2 v-if="title" class="main--title">{{ getSlideTitle(index) }}</h2>
               <h3 v-if="subtitle" class="sub--title">{{ getSlideSubtitle(index) }}</h3>
+              <h4 v-if="smalldesc" class="desc--title">{{ getSlideSmalldesc(index) }}</h4>
             </div>
           </div>
           <div v-if="notice" class="notice--text">
@@ -115,6 +116,10 @@
       type: String,
       default: "특별한 아우디 경험",
     },
+    smalldesc: {
+      type: String,
+      default: "",
+    },
     notice: {
       type: String,
       default: "* 모든 이미지는 참고용이며 실제와 다를 수 있습니다.",
@@ -127,6 +132,11 @@
       type: Boolean,
       default: true,
     },
+    type: {
+      type: String,
+      default: "horizental", // 'horz' , 'vert'
+      validator: (value) => ["horizental", "vertical"].includes(value),
+    },
   });
 
   // Refs
@@ -149,6 +159,10 @@
     return props.slides[index]?.subtitle || props.subtitle;
   };
 
+  const getSlideSmalldesc = (index) => {
+    return props.slides[index]?.smalldesc || props.smalldesc;
+  };
+
   onMounted(() => {
     // Swiper 인스턴스 초기화
     swiperInstance = new Swiper(swiperContainer.value, {

+ 93 - 0
app/components/block/TitleVisual.vue

@@ -0,0 +1,93 @@
+<template>
+  <section class="title--visual" :data-theme="theme">
+    <div class="title--visual--wrapper">
+      <div
+        class="title--visual--content"
+        :data-align="textAlign"
+        :data-animated="animation"
+        :class="{ visible: isVisible }"
+      >
+        <h2 class="title--main">{{ title }}</h2>
+        <span class="title--description">{{ description }}</span>
+        <div v-if="$slots.default" class="title--additional">
+          <slot></slot>
+        </div>
+      </div>
+    </div>
+  </section>
+</template>
+
+<script setup>
+  // Props 정의
+  const props = defineProps({
+    title: {
+      type: String,
+      required: true,
+      default: "특별함을 창조하다",
+    },
+    description: {
+      type: String,
+      required: true,
+      default:
+        "아우디 RS e-tron GT, 아우디 RS 6 Avant, 아우디 RS Q8의 예에서 여러 옵션을 결합하여 Audi exclusive order의 다양성과 개인 맞춤 구성 옵션을 경험해 보세요. 3D 버튼을 클릭하여 3D 보기를 활성화하면 인터랙티브 경험을 할 수 있습니다.",
+    },
+    textAlign: {
+      type: String,
+      default: "center", // 'left', 'center', 'right'
+      validator: (value) => ["left", "center", "right"].includes(value),
+    },
+    theme: {
+      type: String,
+      default: "light", // 'light', 'dark'
+      validator: (value) => ["light", "dark"].includes(value),
+    },
+    animation: {
+      type: Boolean,
+      default: true,
+    },
+    animationDelay: {
+      type: Number,
+      default: 300, // milliseconds
+    },
+  });
+
+  // 애니메이션 로직
+  import { onMounted, ref } from "vue";
+
+  const isVisible = ref(false);
+
+  onMounted(() => {
+    if (props.animation) {
+      // IntersectionObserver로 스크롤 애니메이션 구현
+      const observer = new IntersectionObserver(
+        (entries) => {
+          entries.forEach((entry) => {
+            if (entry.isIntersecting) {
+              setTimeout(() => {
+                isVisible.value = true;
+              }, props.animationDelay);
+              observer.unobserve(entry.target);
+            }
+          });
+        },
+        {
+          threshold: 0.3, // 30% 보일 때 애니메이션 시작
+        }
+      );
+
+      const element = document.querySelector(".title--visual");
+      if (element) {
+        observer.observe(element);
+      }
+
+      // cleanup
+      return () => {
+        if (element) {
+          observer.unobserve(element);
+        }
+      };
+    } else {
+      isVisible.value = true;
+    }
+  });
+</script>

+ 20 - 6
app/pages/exclusive/exclusive-order.vue

@@ -14,20 +14,30 @@
         linkText="아우디 딜러 네트워크 알아보기"
       />
 
-      <!-- Swiper 배너 (30% + 70% 레이아웃) -->
+      <!-- 
+        Swiper 배너 (30% + 70% 레이아웃)
+        type="vertical", 
+        type="horizental"
+      -->
       <SwiperBanner
         :slides="bannerSlides"
         title="Audi Exclusive Collection"
         subtitle="당신만을 위한 특별한 아우디"
-        notice="* 모든 이미지는 참고용이며 실제와 다를 수 있습니다."
+        smalldesc="유럽 인증 기준"
+        notice=""
         :autoplay="{ delay: 0 }"
         :loop="false"
       />
 
-      <!--
-        일반 텍스트 밑에서 올라오는 디자인
-        대타이틀, 소타이틀 형 정렬은 옵션으로 정의
-      -->
+      <!-- 타이틀 비주얼 컴포넌트 -->
+      <TitleVisual
+        title="특별함을 창조하다"
+        description="아우디 RS e-tron GT, 아우디 RS 6 Avant, 아우디 RS Q8의 예에서 여러 옵션을 결합하여 Audi exclusive order의 다양성과 개인 맞춤 구성 옵션을 경험해 보세요. 3D 버튼을 클릭하여 3D 보기를 활성화하면 인터랙티브 경험을 할 수 있습니다."
+        textAlign="center"
+        theme="dark"
+        :animation="true"
+        :animationDelay="300"
+      />
     </div>
   </main>
 </template>
@@ -37,6 +47,7 @@
   import FullSizeBannerText1 from "~/components/block/fullSizeBannerText1.vue";
   import ParallaxBanner from "~/components/block/parallaxBanner.vue";
   import SwiperBanner from "~/components/block/SwiperBanner.vue";
+  import TitleVisual from "~/components/block/TitleVisual.vue";
 
   const bannerImagePath = ref("/img/exclusive/1920X1080_exclusive_edited_v2.jpg");
 
@@ -60,6 +71,7 @@
       title: "당신만을 위해 반영된 특별함",
       subtitle:
         "색상부터 스티칭 요소까지, Audi exclusive order를 통해 오직 당신을 위한 아우디를 만나보세요.",
+      smalldesc: "유럽인증",
     },
     {
       image: "/img/exclusive/05_rsegt_ae_2021_2376-S-L.jpg",
@@ -67,6 +79,7 @@
       title: "원하는 컬러를 선택하다",
       subtitle:
         "노을의 골드, 와인의 레드, 에메랄드 반지의 그린 등 아우디 차체 색상으로 원하는 색상을 선택할 수 있습니다.",
+      smalldesc: "유럽인증",
     },
     {
       image: "/img/exclusive/04_r8_2021_3106_58054-S-L.jpg",
@@ -74,6 +87,7 @@
       title: "보고, 느끼고, 매료되다",
       subtitle:
         "Audi exclusive order 인테리어 트림을 사용하면 다양한 옵션을 선택할 수 있습니다. 가장 상위 카테고리로 고급 가죽을 선택할 수 있습니다.",
+      smalldesc: "유럽인증",
     },
   ]);
 </script>