iT邦幫忙

2022 iThome 鐵人賽

DAY 15
0
Modern Web

Have fun! 新手也能打造的Javascript微型專案系列 第 15

Have fun! 新手也能打造的Javascript微型專案! Day15: 不知道該怎麼做決定? 那就交給Magic 8 Ball吧!

  • 分享至 

  • xImage
  •  
tags: ItIron2022 Javascript

前言

接連幾天都是稍微有點篇幅的專案,今天我們就放輕鬆來個簡單一點的東西吧!Magic 8 Ball又稱神奇8號球是一種美國常見的兒童玩具,他大概長得像這樣。

magic 8 ball

玩法也相當簡單,你詢問它一個問題後將它用力的甩一甩,在它的背面就會出現其中一種答案

其中會包含10種肯定的回答、5種模稜兩可的回答以及5種否定的回答,在許多美劇或卡通中都能見到它的身影,今天就一起來做個簡易版的吧,本次的小專案是參照我之前看到的一篇影片教學,我會附在文末,有興趣的可以去看看影片版!

預期成果

我們要的成果很簡單,對著它問個問題後我們點下搖動按鈕,接著就可以看到問題的結果,比方說我今天問說"鐵人賽我是否能完賽呢?" 結果會是這樣的。

Getting started

Step1: 專案結構

老樣子,一樣請你把那三元素的檔案建立起來,js檔案同樣先留空,請你先在html & css檔案補上以下的內容。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Magic 8 Ball</title>
    <script src="./script.js" defer></script>
    <link rel="stylesheet" href="./style.css" />
  </head>
  <body>
    <h1>Ask me anything!</h1>
    <div class="container">
      <img src="./magic-8-ball.png" class="ball-image" alt="magic-eight-ball" />
      <div class="result-box">
        <button id="shake">Shake it!</button>
        <div class="result">Your fortune will be displayed here</div>
      </div>
    </div>
  </body>
</html>

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  color: #fff;
}

body {
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  background: #222;
}

.container {
  padding: 24px 48px;
  display: flex;
  width: 1000px;
  align-items: center;
  justify-content: space-around;
}

.result-box {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 16px;
  flex-basis: 40%;
}

.result,
button {
  padding: 8px 16px;
  border-radius: 8px;
  font-size: 20px;
}

button {
  background: #fff;
  color: #222;
  border: none;
  cursor: pointer;
  transition: transform 0.3s ease-in;
}

button:active {
  transform: scale(0.85);
}

button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.shake {
  animation: shake 1s;
}

@keyframes shake {
  0% {
    transform: translate(4px, 4px) rotate(0deg);
  }
  10% {
    transform: translate(-4px, -4px) rotate(-10deg);
  }
  20% {
    transform: translate(4px, 4px) rotate(0deg);
  }
  30% {
    transform: translate(-4px, -4px) rotate(-10deg);
  }
  40% {
    transform: translate(4px, 4px) rotate(0deg);
  }
  50% {
    transform: translate(-4px, -4px) rotate(-10deg);
  }
  60% {
    transform: translate(4px, 4px) rotate(0deg);
  }
  70% {
    transform: translate(-4px, -4px) rotate(-10deg);
  }
  80% {
    transform: translate(4px, 4px) rotate(0deg);
  }
  90% {
    transform: translate(-4px, -4px) rotate(-10deg);
  }
  100% {
    transform: translate(4px, 4px) rotate(0deg);
  }
}

Step2: 產出並呈現隨機的答案

產出隨機答案這點跟之前的打字遊戲一樣,我們建立一個含有所有答案的陣列並利用函數從中隨機取出一個即可,相信這已經難不倒你了! 我們只要先建立答案陣列、選好元素並加上監聽器,這個步驟真的一下就結束了,請你在js檔案先補上以下的內容

const shakeBtn = document.getElementById("shake");
const result = document.querySelector(".result");

const possibleAnswers = [
  "It is certain.",
  "It is decidedly so.",
  "Without a doubt.",
  "Yes definitely.",
  "You may rely on it.",
  "As I see it, yes.",
  "Most likely.",
  "Outlook good.",
  "Yes.",
  "Signs point to yes.",
  "Reply hazy, try again.",
  "Ask again later.",
  "Better not tell you now.",
  "Cannot predict now.",
  "Concentrate and ask again.",
  "Don't count on it.",
  "My reply is no.",
  "My sources say no.",
  "Outlook not so good.",
  "Very doubtful.",
];

function getRandomAnswer() {
  return possibleAnswers[Math.floor(Math.random() * possibleAnswers.length)];
}

function handleBtnClick() {
  result.textContent = getRandomAnswer();
}

shakeBtn.addEventListener("click", handleBtnClick);

Step3: 加入抖動動畫

目前雖然可以順利在點擊按鈕後產生結果,不過一點感覺都沒有! 答案直接顯示真的有夠無趣的,我們最終想要以下的流程

  • 點擊shake按鈕
  • 魔法球開始抖動1秒
  • 1秒後停止抖動並呈現答案

我們之前已經在css檔案內寫好shake的動畫了,那麼要做的事情很簡單,只要在點擊後將這個class加上去並在一秒後移除即可,請你修改我們剛寫好的handleBtnClick函數,並在上方加一個ballImage元素

const ballImage = document.querySelector(".ball-image");

function handleBtnClick() {
  ballImage.classList.add("shake");
  setTimeout(() => {
    ballImage.classList.remove("shake");
    result.textContent = getRandomAnswer();
  }, 1000);
}

這麼一來球就會抖的有那麼一回事了!

Step4: 額外優化

不過目前還存在一個比較明顯的問題,當你不斷的連續點擊時會出現答案快速被洗掉的情況,我們這種有耐心的人都希望一次點擊看一個答案就好,因此我們會希望加上一個點擊的限制,在結果出來前不允許再次點擊,這個其實也相當容易做到! 我們最後一次修改handleBtnClick函數吧!

function handleBtnClick() {
  ballImage.classList.add("shake");
  shakeBtn.disabled = true;
  setTimeout(() => {
    ballImage.classList.remove("shake");
    result.textContent = getRandomAnswer();
    shakeBtn.disabled = false;
  }, 1000);
}

總結

我們今天快速的完成一個magic 8 ball的小專案,js的邏輯相當簡單,主要重點反而其實在css上,這是個很好的animation初體驗! 明天我們將進入新的小專案,敬請期待囉!

文章中的範例程式碼可以在這邊取得,歡迎自行取用

轉職Q & A

Danny,我順利的開始跑面試流程了,但我發現他們最後常常會問說是否有問題想問,這時候我該問些什麼呢?

很好的問題!說實在我一直覺得面試是一種雙向交流的過程,受試者其實也有足夠的話語權去了解自己想了解的事情,不需要把地位放太低! 對我來說提問的時間非常重要,因為這是我獲取情報的好機會,許多細節在對方主導時會被忽略掉,只有自己提問時才有機會得到更真實的資訊,一般來說我會問以下的問題。

  • 整個面試過程大概會有多長,後續還有哪些關卡?
  • 你們目前工程師團隊的規模是?可以向我說明一下你們的開發流程嗎?
  • 若我順利的錄取,一開始我會負責的項目會是?
  • 這次招募/擴編的目的以及公司/產品未來的方向是?

我會建議至少對面試的公司做最基本的調查,可以的話對他們的歷史以及產品多做一些了解,這麼一來你針對公司或產品的提問也會較有水準一些,盡可能透過提問去了解你未來的工作情境,這會是你決定後續是否接受offer的考量之一。

參考連結

Code a Magic 8 Ball CSS Animation Website in 5min | CSS For Beginners | 5min Tech Project

本文章同步發布於個人部落格,有興趣的朋友也可以來逛逛~!


上一篇
Have fun! 新手也能打造的Javascript微型專案! Day14: 英打總是龜速? 寫個打字測驗遊戲來練習吧!(下)
下一篇
Have fun! 新手也能打造的Javascript微型專案! Day16: 用打字猜數字無聊? 那就用SpeechRecognition語音猜數字唄!(上)
系列文
Have fun! 新手也能打造的Javascript微型專案30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言