타일 이미지 구현하기

Project Diary/Vue (Roblox WebSite)

data구조와 css를 이용한 타일 이미지 구현 방법 기록


1. HTML 구조 설정

먼저, 타일 이미지를 담을 HTML 구조를 설정합니다.

 

<template>
  <section>
    <div class="row">
      <h2 :class="{ dark: changeDarkMode }">
        {{ $t("[4].tileview.h2-1") }}
        <br />
        {{ $t("[4].tileview.h2-2") }}
      </h2>
      <div class="tileBox" :class="{ dark: changeDarkMode }">
        <div
          class="imgContainer"
          v-for="(item, idx) in colContainer"
          :key="idx"
        >
          <div class="imgBox1" v-for="(val, idx) in item.col" :key="idx">
            <div class="imgBox2">
              <img :src="val.image1" :alt="val.alt" />
            </div>
          </div>
        </div>
      </div>
    </div>
  </section>
</template>

 v-for 디렉티브를 사용하여 colContainer 배열의 데이터를 순회하며 타일 이미지를 생성합니다. imgContainer는 열을 나타내며, 각 열 안에 여러 개의 imgBox1이 포함됩니다. imgBox2 안에는 실제 이미지가 포함됩니다.

 

2. 데이터 설정

data 속성에 타일 이미지를 담은 데이터를 설정합니다.

 

<script>
export default {
  name: "TileView",
  data() {
    return {
      colContainer: [
        {
          col: [
            {
              image1: "./assets/images/tile-1/header_1_Thumbnail.jpg",
              alt: "타일 이미지1",
            },
            {
              image1: "./assets/images/tile-1/header_2_Thumbnail.jpg",
              alt: "타일 이미지2",
            },
            {
              image1: "./assets/images/tile-1/experience_2_Thumbnail.jpg",
              alt: "타일 이미지3",
            },
          ],
        },
        // 데이터 생략
      ],
    };
  },
  computed: {
    changeDarkMode() {
      return this.$store.getters.fnGetDark;
    },
  },
};
</script>

data 속성에는 여러 개의 열(col)을 포함하는 colContainer 배열이 있습니다. 각 열은 여러 개의 타일 이미지 객체를 포함하며, 각 객체는 image1 속성으로 이미지 경로를, alt 속성으로 대체 텍스트를 가집니다.

 

colContainer는 여러 개의 열을 담고 있는 배열입니다. 각 열(col)은 타일 이미지를 담고 있는 객체들의 배열입니다. 각 객체는 image1 속성과 alt 속성을 가지고 있으며, image1은 이미지 경로를, alt는 대체 텍스트를 나타냅니다. 이러한 구조를 통해 데이터를 유연하게 관리하고, 쉽게 접근할 수 있습니다.

 

3. CSS 스타일링

<style lang="scss" scoped>
.row {
  h2 {
    color: #dee2e6; 
    text-align: center; 
    font-size: 4rem; 
    margin: 5.5rem 0; 
  }
  .tileBox {
    display: flex; 
    position: relative; /* 자식 요소의 위치를 상대적으로 설정 */
    height: 720px; 
    align-items: center; 
    overflow: hidden; /* 내용이 넘칠 때 숨김 */
    &::before {
      position: absolute; 
      content: ""; 
      height: 15%; 
      left: 0;
      right: 0;
      z-index: 10; 
      top: -2px; 
      background: linear-gradient(
        180deg,
        #121110 0%,
        #121110 5%,
        rgba(18, 17, 16, 0) 100%
      ); 
    }
    &::after {
      position: absolute; 
      content: ""; /* 내용 없음 */
      height: 15%; /* 높이 15% */
      left: 0;
      right: 0;
      z-index: 10; 
      bottom: -2px; 
      background: linear-gradient(
        0deg,
        #121110 0%,
        #121110 5%,
        rgba(18, 17, 16, 0) 100%
      ); 
    }
    .imgContainer {
      display: flex; 
      flex-direction: column; 
      transform: rotate(15deg); /* 15도 회전 */
      animation: fadeInUp 3s; 
      .imgBox1 {
        margin: 0 7px;
        .imgBox2 {
          margin: 7px 0; 
          img {
            border-radius: 10px; 
            transition: all 0.3s;/
          }
          img:hover {
            transform: scale(1.05); /* 마우스 오버 시 확대 각각의 타일이미지 확대 */
          }
        }
      }
    }
  }
/* 반응형 스타일 */
  @media screen and (max-width: 390px) {
    h2 {
      font-size: 1.8rem; 
      margin-bottom: 2rem; 
      padding: 0 1rem; 
      margin: 1.5rem 0 4rem 0; 
    }
    .tileBox {
      height: 150px; 
      .imgContainer {
        .imgBox1 {
          margin: 0 4px; 
          .imgBox2 {
            margin: 4px 0; 
          }
        }
      }
    }
  }
}

@keyframes fadeInUp {
  0% {
    transform: translateY(175%) rotate(15deg); /* 처음에 아래에서 위로 이동 */
  }
  to {
    transform: translateY(0%) rotate(15deg); /* 끝에 정상 위치 */
  }
}
</style>

 

 

타일 이미지 완성!