เรียน​ CSS Animation | Day 6 - Card Game

Published on

เขียนวันที่ : Jan 11, 2023

learn-css-animations/day6-card-game
Discord

สวัสดีครับ วันที่ 6 เป็นการทำ animation คล้ายๆ การ์ดเกม (อาจจะไม่เหมือนเท่าไหร่) ซึ่ง ก็จะมี 2 states คือ ตอนที่เอาเมาท์ไปชี้ ก็จะคล้ายๆ เราเลือกการ์ดใบนั้น และก็ตอนคลิ๊กที่การ์ด เพื่อดูรายลละเอียด (เป็นแค่ flow นะครับ)

Day 6 - Card Game

โค๊ดบน Codepen

See the Pen on https://codepen.io/phonbopit/pen/oNMBNOL/

สามารถดูแบบ Video ได้จาก Link Youtube ครับ

Step 1 - สร้าง Markup

เริ่มแรกผมทำการสร้าง HTML ขึ้นมาก่อนแบบง่ายๆ มีแค่ .cards และ .card

// emmet
.wrapper>h2.title{Card Game Example}+.cards>.card*7
<div class="wrapper">
  <h2 class="title">Card Game Example</h2>
  <div class="cards">
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
  </div>
</div>

Step 2 - CSS

ส่วนของ CSS ผมปรับให้ card ไปอยู่ด้านล่างของจอ (ใช้ position: absolute หรือ flex)

.wrapper {
  display: flex;
  flex-direction: column;
  position: relative;
  justify-content: space-around;
  align-items: center;
  width: 100%;
  height: 100vh;
}

.cards {
  /*   position: absolute; */
  /*   bottom: 4em; */
  display: flex;
  justify-content: center;
  gap: 8px;
}

.card {
  display: block;
  width: 75px;
  height: 100px;
  border: 1px solid #df93b8;
  cursor: pointer;
  transition: all 0.25s ease-in;
  background-color: #000;
  border-radius: 4px;
  color: #fff;
}

ตอนที่ hover ที่การ์ด ก็แค่ขยับ translateY นิดหน่อย

.card:hover {
  transform: translateY(-8px);
}

Step 3 - Keyframes

ส่วนนี้เป็นการทำ keyframes ผมสร้างไว้ชื่อ displayCard เพื่อให้มัน scale และ rotate จำลองคล้ายๆ เปิดการ์ด (ทำแบบง่ายๆ ไม่ได้เหมือนนะครับ)

โดย anmiation-fill-mode ผมใช้ forwards เพื่อให้มันค้าง state อยู่ ไม่กลับไปเริ่มต้น

.card.show {
  animation-name: displayCard;
  animation-duration: 0.6s;
  animation-iteration-count: 1;
  animation-timing-function: linear;
  animation-fill-mode: forwards;
}

@keyframes displayCard {
  0% {
    transform: translateY(0) scale(1) rotate(0);
  }

  100% {
    transform: translate(-50%, calc(-50vh)) scale(2) rotate(-180deg);
  }
}

Step 4 - JavaScript

ผมใช้ JavaScript เข้ามาช่วย เพื่อจะเพิ่ม handle ตอน click นั่นเอง โดยเพิ่มคลาส .show เวลาที่คลิ๊ก หรือถ้า show อยู่แล้วก็ลบ และเพิ่ม dismiss (ส่วนนี้ผมเอาไว้ให้มันยกเลิก animation แต่คิดว่าน่าจะมีิวิธีที่ง่ายกว่านี้รึเปล่า?)

const elements = document.querySelectorAll(".card");

elements.forEach((element) => {
  element.addEventListener("click", () => {
    if (element.classList.contains("dismiss")) {
      element.classList.remove("dismiss");
    }

    if (element.classList.contains("show")) {
      element.classList.remove("show");
      element.classList.add("dismiss");
    } else {
      element.classList.add("show");
    }
  });
});

่ส่วน css เพิ่ม dismiss เข้าไป

.card.dismiss {
  animation: 0.6s dismissCard 1;
}

สุดท้าย จัด style ให้การ์ดที่เหลือใน deck กรณีที่มีการ์ดถูก hover ที่เหลือก็จะถูก grayscale และ blur

.cards:has(.card:hover) .card:not(:hover) {
  filter: grayscale(50%) blur(1px);
  opacity: 0.8;
}

เป็นอันเรียบร้อย ได้การ์ดเท่ๆ เหลือแค่ตอน animation มันยังไม่สวยเท่าไหร่

ไว้เจอกันใหม่บล็อกหน้าครับ สวัสดีครับ

Happy Coding ❤️

Buy Me A Coffee
Discord