Flex Panel Gallery


flex-box를 이용한 레이아웃 및 효과를 공부하는 시간

기본 코드

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Flex Panels 💪</title>
  <link href='https://fonts.googleapis.com/css?family=Amatic+SC' rel='stylesheet' type='text/css'>
</head>
<body>
  <style>
    html {
      box-sizing: border-box;
      background:#ffc600;
      font-family:'helvetica neue';
      font-size: 20px;
      font-weight: 200;
    }
    body {
      margin: 0;
    }
    *, *:before, *:after {
      box-sizing: inherit;
    }

    .panels {
      min-height:100vh;
      overflow: hidden;
    }

    .panel {
      background:#6B0F9C;
      box-shadow:inset 0 0 0 5px rgba(255,255,255,0.1);
      color:white;
      text-align: center;
      align-items:center;
      /* Safari transitionend event.propertyName === flex */
      /* Chrome + FF transitionend event.propertyName === flex-grow */
      transition:
        font-size 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11),
        flex 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11),
        background 0.2s;
      font-size: 20px;
      background-size:cover;
      background-position:center;
    }


    .panel1 { background-image:url(https://source.unsplash.com/gYl-UtwNg_I/1500x1500); }
    .panel2 { background-image:url(https://source.unsplash.com/1CD3fd8kHnE/1500x1500); }
    .panel3 { background-image:url(https://images.unsplash.com/photo-1465188162913-8fb5709d6d57?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&w=1500&h=1500&fit=crop&s=967e8a713a4e395260793fc8c802901d); }
    .panel4 { background-image:url(https://source.unsplash.com/ITjiVXcwVng/1500x1500); }
    .panel5 { background-image:url(https://source.unsplash.com/3MNzGlQM7qs/1500x1500); }

    .panel > * {
      margin:0;
      width: 100%;
      transition:transform 0.5s;
    }

    .panel p {
      text-transform: uppercase;
      font-family: 'Amatic SC', cursive;
      text-shadow:0 0 4px rgba(0, 0, 0, 0.72), 0 0 14px rgba(0, 0, 0, 0.45);
      font-size: 2em;
    }
    .panel p:nth-child(2) {
      font-size: 4em;
    }

    .panel.open {
      font-size:40px;
    }

  </style>


  <div class="panels">
    <div class="panel panel1">
      <p>Hey</p>
      <p>Let's</p>
      <p>Dance</p>
    </div>
    <div class="panel panel2">
      <p>Give</p>
      <p>Take</p>
      <p>Receive</p>
    </div>
    <div class="panel panel3">
      <p>Experience</p>
      <p>It</p>
      <p>Today</p>
    </div>
    <div class="panel panel4">
      <p>Give</p>
      <p>All</p>
      <p>You can</p>
    </div>
    <div class="panel panel5">
      <p>Life</p>
      <p>In</p>
      <p>Motion</p>
    </div>
  </div>

  <script>

  </script>
</body>
</html>

목표

CSS 속성인 display: flex를 사용해 레이아웃을 구성해보고 자바스크립트 효과를 익힘

과정

  1. display: flex 적용
  2. 각 패널의 크기, 내용의 위치 조정
  3. 패널 안의 구성요소 정렬
  4. 패널의 효과 적용
  5. 자바스크립트 효과 적용

코드 분석

  1. display: flex 적용

     .panels {
         display: flex;
     } 

     

    위 코드를 적용 시키면 각 패널의 레이아웃이 다음과 같이 바뀐다

  2. 각 패널의 크기, 내용의 위치 조정

    .panel {
     display: flex;
     flex: 1;
     justify-content: center;
     align-items: center;
     flex-direction: column;
    }
    

    display속성을 flex로 설정을 해주고,
    flex: 1을 적용하면서 브라우저 크기에 맞춰 모든 패널의 크기가 동일하게 설정이 됨
    justify-content: center로 수평정렬,
    align-items: center로 수직정렬
    flex-direction: column으로 정렬 축을 세로로 바꿔줌 기본값은 row
    ```

  3. 패널 안의 구성요소 정렬

     .panel > * {
         flex: 1 0 auto;
         display:flex;
         justify-content: center;
         align-items: center;
     }
    

    패널 안의 요소들을 2번과같은 설명으로 정렬하면 각 컨텐츠의 위치가 고르게 잡힌다.

  4. 패널의 효과 적용

     .panel > *:first-child { transform: translateY(-100%);}
     .panel.open-active > *:first-child { transform: translateY(0);}
     .panel > *:last-child { transform: translateY(100%);}
     .panel.open-active > *:last-child { transform: translateY(0);}
    

    패널의 첫번째 요소의 수직 위치를 위로 옮겨 숨기고, 마지막 요소를 아래로 옮겨 숨기게 설정한 뒤,
    open-active속성이 생기면 제자리로 돌아오도록 코드를 작성

  5. 자바스크립트 효과 적용

     <sctipt>
         const panels = document.querySelectorAll('.panel');
    
         function toggleOpen() {
             this.classList.toggle('open');
         }
    
         function toggleActive(e) {
             if(e.propertyName.includes('flex')) {
                 this.classList.toggle('open-active');
             }
         }
    
         panels.forEach(panel => panel.addEventListener('click', toggleOpen));
         panels.forEach(panel => panel.addEventListener('transitionend', toggleActive));
    

    panels에 모든 panel 클래스 인자를 담고,
    이벤트 발생 시open 클래스가 토글되는 toggleOpen() 함수와,
    flex라는 속성이 있으면 open-active 클래스가 토글되는 toggleActive() 함수를 생성 후
    각 panel에 대해서 click(클릭)할때 toggleOpen, transitionend(변화가 끝날때) toggleAcrive()함수를 실행하도록 코드를 작성해준다.

찾아본 내용, 알게된 내용들

flex: 1 - 위의 경우에서는 panel이 모두 1씩 flex값을 가지고 있으므로 너비가 동일하게 표현되는것,
클릭했을때 flex:5가 적용되면서 차지하는 비율이 5로 증가
:first-child - 요소 선택자의 종류로 첫 번째 자식 요소에 대해 속성을 적용하는 것
transform: translateY() - Y축의 값을 현재 위치(0을기준)에서 얼만큼 움직이겠다는 뜻


끝!


'개발 > JavaScript30' 카테고리의 다른 글

7. Array Cardio Day 2  (0) 2017.04.07
6. Type Ahead  (0) 2017.04.06
5. Flex Panel Gallery  (0) 2017.04.05
4. Array Cardio Day 1  (0) 2017.04.04
3. CSS Variables  (0) 2017.04.03
2. CSS + JS Clock  (0) 2017.04.03

Array Cardio Day 1


제목처럼 자바스크립트 배열과 배열제어에 대해서 공부하는 시간


기본코드

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Array Cardio 💪</title>
</head>
<body>
  <p><em>Psst: have a look at the JavaScript Console</em> 💁</p>
  <script>
    // Get your shorts on - this is an array workout!
    // ## Array Cardio Day 1

    // Some data we can work with

    const inventors = [
      { first: 'Albert', last: 'Einstein', year: 1879, passed: 1955 },
      { first: 'Isaac', last: 'Newton', year: 1643, passed: 1727 },
      { first: 'Galileo', last: 'Galilei', year: 1564, passed: 1642 },
      { first: 'Marie', last: 'Curie', year: 1867, passed: 1934 },
      { first: 'Johannes', last: 'Kepler', year: 1571, passed: 1630 },
      { first: 'Nicolaus', last: 'Copernicus', year: 1473, passed: 1543 },
      { first: 'Max', last: 'Planck', year: 1858, passed: 1947 },
      { first: 'Katherine', last: 'Blodgett', year: 1898, passed: 1979 },
      { first: 'Ada', last: 'Lovelace', year: 1815, passed: 1852 },
      { first: 'Sarah E.', last: 'Goode', year: 1855, passed: 1905 },
      { first: 'Lise', last: 'Meitner', year: 1878, passed: 1968 },
      { first: 'Hanna', last: 'Hammarström', year: 1829, passed: 1909 }
    ];

    const people = ['Beck, Glenn', 'Becker, Carl', 'Beckett, Samuel', 'Beddoes, Mick', 'Beecher, Henry', 'Beethoven, Ludwig', 'Begin, Menachem', 'Belloc, Hilaire', 'Bellow, Saul', 'Benchley, Robert', 'Benenson, Peter', 'Ben-Gurion, David', 'Benjamin, Walter', 'Benn, Tony', 'Bennington, Chester', 'Benson, Leana', 'Bent, Silas', 'Bentsen, Lloyd', 'Berger, Ric', 'Bergman, Ingmar', 'Berio, Luciano', 'Berle, Milton', 'Berlin, Irving', 'Berne, Eric', 'Bernhard, Sandra', 'Berra, Yogi', 'Berry, Halle', 'Berry, Wendell', 'Bethea, Erin', 'Bevan, Aneurin', 'Bevel, Ken', 'Biden, Joseph', 'Bierce, Ambrose', 'Biko, Steve', 'Billings, Josh', 'Biondo, Frank', 'Birrell, Augustine', 'Black, Elk', 'Blair, Robert', 'Blair, Tony', 'Blake, William'];

    // Array.prototype.filter()
    // 1. Filter the list of inventors for those who were born in the 1500's

    // Array.prototype.map()
    // 2. Give us an array of the inventors' first and last names

    // Array.prototype.sort()
    // 3. Sort the inventors by birthdate, oldest to youngest

    // Array.prototype.reduce()
    // 4. How many years did all the inventors live?

    // 5. Sort the inventors by years lived

    // 6. create a list of Boulevards in Paris that contain 'de' anywhere in the name
    // https://en.wikipedia.org/wiki/Category:Boulevards_in_Paris


    // 7. sort Exercise
    // Sort the people alphabetically by last name

    // 8. Reduce Exercise
    // Sum up the instances of each of these
    const data = ['car', 'car', 'truck', 'truck', 'bike', 'walk', 'car', 'van', 'bike', 'walk', 'car', 'van', 'car', 'truck' ];

  </script>
</body>
</html>

목표

자바스크립트의 배열제어 방법을 코드로 구현해보며 익힘

과정

  1. filter()
  2. map()
  3. sort()
  4. reduce()

코드 분석

  1. filter

     // Array.prototype.filter()
     // 1. Filter the list of inventors for those who were born in the 1500's
     const fifteen = inventors.filter(inventor => (inventor.year >= 1500 && inventor.year < 1600));
    
     console.table(fifteen);
    

    filter() 메소드로 inventors 배열 중 1500년대에 태어난 사람을 정렬
    inventors 배열 내의 모든 요소 각각 값들 중 year이 1500이상이면서 1600이하인 것들을 추출하고,
    새로운 배열 fifteen안에 담아 console.table(fifteen)을 통해 콘솔로 출력

  2. map()

     // Array.prototype.map()
     // 2. Give us an array of the inventor first and last names
     const fullNames = inventors.map(inventor => `${inventor.first} ${inventor.last}`);
    
     console.log(fullNames);
    

    map() 메소드로 inventors 배열 각각 값들의 first, last만 꺼내 새로운 배열을 만듦
    inventors 배열 내의 모든 요소 각각 값들 중 firstlast를 공백으로 구분지어 연결하고,
    새로운 배열 fullNames에 담아 conloe.log(fullNames)로 콘솔에 출력

  3. sort()

     // Array.prototype.sort()
     // 3. Sort the inventors by birthdate, oldest to youngest
     // const ordered = inventors.sort(function(a, b) {
     //   if(a.year > b.year) {
     //     return 1;
     //   } else {
     //     return -1;
     //   }
     // });
    
     const ordered = inventors.sort((a, b) => a.year > b.year ? 1 : -1);
     console.table(ordered);
    

    sort() 메소드로 inventors 배열의 값들을 생일순으로 정렬(나이많은순서대로)
    주석으로 되어있는 코드를 짧게 줄인것이 아래의 코드이니 비교해보면 된다.
    Arrow function( => )에 익숙해지는것이 좋음
    inventors안의 두 값을 year 속성으로 비교 후 참이면 1, 거짓이면 -1을 반환하고,
    ordered라는 새로운 배열에 담아서 console.table(ordered)로 콘솔에 출력

  4. reduce()

     // Array.prototype.reduce()
     // 4. How many years did all the inventors live?
     const totalYears = inventors.reduce((total, inventor) => {
         return total + (inventor.passed - inventor.year);
     }, 0);
    
     console.log(totalYears);
    

    reduce() 메소드로 inventors 배열 값들의 총 수명을 구함
    total 인자에 inventors 배열의 수명을 누적으로 더해주고(뒤의 0은 초기값),
    totalYears에 담아 콘솔에 출력

찾아본 내용, 알게된 내용들

.prototype - Vue에서 공부했던 인스턴스와 같은 개념(객체지향적 개발을 할 수 있게 해주는 메소드)
filter() - 말그대로 필터, 범위를 설정해 만족하는 값을 반환
map() - 배열 내의 모든 요소 각각에 대해 callback 호출 후, 결과를 모아 새로운 배열을 반환
sort() - 정렬, 알고리즘 공부가 추가적으로 필요함/ 정렬의 종류
reduce() - 누산기 > 누적계산기


'개발 > JavaScript30' 카테고리의 다른 글

6. Type Ahead  (0) 2017.04.06
5. Flex Panel Gallery  (0) 2017.04.05
4. Array Cardio Day 1  (0) 2017.04.04
3. CSS Variables  (0) 2017.04.03
2. CSS + JS Clock  (0) 2017.04.03
1. JavaScript Drum Kit  (0) 2017.03.30

블로그 운영시 참고 사이트, 프로그램


마크다운

하루패드
한국어도 지원되며 마크다운 작성시 아주 편하고 디자인도 예쁨


Jekyll 블로그

Github에서 개발한 사이트 개발 툴
블로그로 사용하기 아주 깔끔함
공식 홈페이지
만드는 방법


+꾸준히 추가 예정


'좋은글 > 개발' 카테고리의 다른 글

개발 좋은 글 모음  (3) 2017.07.02
자료구조 소트 쉽게 이해하기  (0) 2017.04.07
블로그 운영시 참고 사이트, 프로그램  (0) 2017.04.03
스타트업 관련 정보 사이트  (2) 2017.03.29

3. CSS Variables

이번 강의를 보면서 CSS에도 변수가 있다는걸 처음알았다
고수의 길은 정말 멀고도 멀다를 다시한번 느꼈음(ㅠㅠ)
각설하고 강의 내용을 분석해보자


기본코드

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Scoped CSS Variables and JS</title>
</head>
<body>
  <h2>Update CSS Variables with <span class='hl'>JS</span></h2>

  <div class="controls">
    <label for="spacing">Spacing:</label>
    <input id="spacing" type="range" name="spacing" min="10" max="200" value="10" data-sizing="px">

    <label for="blur">Blur:</label>
    <input id="blur" type="range" name="blur" min="0" max="25" value="10" data-sizing="px">

    <label for="base">Base Color</label>
    <input id="base" type="color" name="base" value="#ffc600">
  </div>

  <img src="https://source.unsplash.com/7bwQXzbF6KE/800x500">

  <style>

    /*
      misc styles, nothing to do with CSS variables
    */

    body {
      text-align: center;
    }

    body {
      background: #193549;
      color: white;
      font-family: 'helvetica neue', sans-serif;
      font-weight: 100;
      font-size: 50px;
    }

    .controls {
      margin-bottom: 50px;
    }

    input {
      width:100px;
    }
  </style>

  <script>
  </script>

</body>
</html>

#목표

사진에서 두가지의 레인지 조절 기능과 colorpicker 기능을 넣으려 한다

#과정

  1. CSS 변수를 만든다(base색상, 기본 여백(spacing), 기본 흐림정도(blur))
  2. CSS변수를 통한 이미지, 텍스트 효과 지정
  3. 자바스크립트로 CSS 변수가 작동하도록 코드 작성

1. CSS 변수를 만든다(base색상, 기본 여백(spacing), 기본 흐림정도(blur))

:root {
    --base: #ffc600;
    --spacing: 10px;
    --blur: 10px
}

:root - HTML 요소중 가장 상위 요소에 적용한다는 뜻
--base - base라는 CSS 변수를 생성
위와같이 :root에 변수를 선언하는 것은 전역변수를 생성한다는 뜻


2. CSS변수를 통한 이미지, 텍스트 효과 지정

img {
    padding: var(--spacing);
    background: var(--base);
    filter: blur(var(--blur));
}

.h1 {
    color: var(--base);
}

변수를 불러올 때 var(--spacing)과 같이 불러옴


3. 자바스크립트로 CSS 변수가 작동하도록 코드 작성

const inputs = document.querySelectorAll('.controls input');

function handleUpdate() {
    const suffix = this.dataset.sizing || '';
    document.documentElement.style.setProperty(`--${this.name}`, this.value + suffix);
}

inputs.forEach(input => input.addEventListener('change', handleUpdate));
inputs.forEach(input => input.addEventListener('mousemove', handleUpdate));

inputs 라는 변수에 controls 클래스 하위의 input 태그들을 담고
handleUpdate()라는 함수에서 suffixinputdata-sizing 또는 공백을 담는다 위의 HTML코드를 보면 range-bar로 이루어진 두개의 input태그는 data-sizing="px"이고 colorpicker input태그는 data-sizing속성이 존재하지 않기 때문에 둘을 or연산자로 엮어서 suffix에 담은 것 

document.documentElement.style.setProperty(`--${this.name}`, this.value +suffix); document의 최상위 태그 html에 style 요소를 부여하고 그 내용을 name: value로 채움

(글로 적으려니 정리가 안돼서 어려워 보이지만 직접 코드를 보는게 이해가 빠름!)

마지막 코드는 inputs 변수의 각각 내용(두개의 range-bar, colorpicker)에서 change 이벤트와 mousemove 이벤트가 일어날때 handleUpdate()를 실행하는 addEventListener메소드를 넣음.
이때 mousemove를 넣지 않으면 range-bar를 드래그 하면서 동시에 결과를 볼수 없고 마우스를 떼야만 결과가 출력되어 두가지를 같이 써주는게 보기가 훨씬 편함

찾아본 내용, 알게된 내용들

filter: blur(~~) - 번짐효과 설정

.dataset - data-~~로 이루어진 내용들 데이터정보 호출 ex) data-sizing속성은 dataset.sizing으로 호출

document.documentElement.style.setProperty - document의 최상위 요소에 style 요소 적용 후 속성 적용

:root - HTML 최상위 요소 선택자

--name var(--name) - CSS 변수선언,호출

끝!


'개발 > JavaScript30' 카테고리의 다른 글

5. Flex Panel Gallery  (0) 2017.04.05
4. Array Cardio Day 1  (0) 2017.04.04
3. CSS Variables  (0) 2017.04.03
2. CSS + JS Clock  (0) 2017.04.03
1. JavaScript Drum Kit  (0) 2017.03.30
0. JavaScript30 Challenge  (0) 2017.03.30

CSS + JS Clock

자바스크립트로 현재시간 받을 수 있는건 알았지만
CSS로 아날로그 시계를 구현할 수 있어서 신기했다
자바스크립트공부를 하려고 시작했는데 CSS도 많이 알게 되는것 같음

기본 코드

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JS + CSS Clock</title>
</head>
<body>


    <div class="clock">
      <div class="clock-face">
        <div class="hand hour-hand"></div>
        <div class="hand min-hand"></div>
        <div class="hand second-hand"></div>
      </div>
    </div>


  <style>
    html {
      background:#018DED url(http://unsplash.it/1500/1000?image=881&blur=50);
      background-size:cover;
      font-family:'helvetica neue';
      text-align: center;
      font-size: 10px;
    }
    body {
      margin: 0;
      font-size: 2rem;
      display:flex;
      flex:1;
      min-height: 100vh;
      align-items: center;
    }
    .clock {
      width: 30rem;
      height: 30rem;
      border:20px solid white;
      border-radius:50%;
      margin:50px auto;
      position: relative;
      padding:2rem;
      box-shadow:
        0 0 0 4px rgba(0,0,0,0.1),
        inset 0 0 0 3px #EFEFEF,
        inset 0 0 10px black,
        0 0 10px rgba(0,0,0,0.2);
    }
    .clock-face {
      position: relative;
      width: 100%;
      height: 100%;
      transform: translateY(-3px); /* account for the height of the clock hands */
    }
    .hand {
      width:50%;
      height:6px;
      background:black;
      position: absolute;
      top:50%;
    }
  </style>

  <script>
  </script>
</body>
</html>

목표

현재 시간을 아날로그 시계로 구현

과정

  1. 시계바늘 중심위치 잡기, 효과 적용
  2. 시계바늘 변수로 등록
  3. 시계바늘 현재 시간에 맞게 설정

코드 분석

  1. 시계바늘 중심위치 잡기, 효과 적용

    .hand {
     transform-origin: 100%;
     transform: rotate(90deg);
     transition: all 0.05s;
     transition-timing-function: cubic-bezier(0.1, 2.7, 0.58, 1);
    }
    

    transform - 변형 효과를 줄 때 기준 설정
    hand 클래스에 위의 코드를 추가해
    기준축을 100% 즉 가장 오른쪽으로 잡고, 방향을 90도만큼 돌려서
    시침, 분침, 초침이 12시 방향에 있도록 바꿔줌
    transition - 변형 효과를 줄 때 효과 설정
    all 0.05s - 모든곳에 효과를 주며 0.05초에 실행완료하겠다
    transition-timing-function: cubic-bezier(0.1, 2.7, 0.58, 1) - 속성의 중간값을 계산하는 방법을 정의하며 cubic-bezier는 가장 많이 사용되는 속성으로 네 점에 의해 정의되며, 그래프로 제공해서 명시할 수 있음
    괄호안의 값은 대충 그래프로 시계 움직임처럼 찍은 값을 적은것

  2. 시계바늘을 변수로 등록

    const secondHand = document.querySelector('.second-hand');
    const minsHand = document.querySelector('.min-hand');
    const hourHand = document.querySelector('.hour-hand');
    

    세개의 바늘을 HTML요소에서 클래스로 찾아서 변수로 등록

  3. 시계바늘을 현재 시간에 맞게 설정

    function setDate() {
     const now = new Date();
    
     const seconds = now.getSeconds();
     const secondsDegrees = ((seconds / 60) * 360) + 90;
     secondHand.style.transform = `rotate(${secondsDegrees}deg)`;
    
     const mins = now.getMinutes();
     const minsDegrees = ((mins / 60) * 360) + ((seconds/60)*6) + 90;
     minsHand.style.transform = `rotate(${minsDegrees}deg)`;
    
     const hour = now.getHours();
     const hourDegrees = ((hour / 12) * 360) + ((mins/60)*30) + 90;
     hourHand.style.transform = `rotate(${hourDegrees}deg)`;
    
    setInterval(setDate, 1000);
    setDate();
    }
    

    setDate라는 함수에 현재 시간에 대한 정보를 담는 now라는 변수를 만들고
    초, 분, 시 단위로 변수를 만들어 시간에 맞게 돌아가도록 각도를 계산해주고
    각 시계바늘에 transform: rotate 속성을 삽입해줌
    이때 각도 조절값은 곰곰이 생각해보시길..(적기가 넘나힘든것)
    setIntervalsetDate를 1000ms(1초) 마다 실행한다는 뜻
    마지막 코드 setDate()는 켰을 때 바로 함수 한번 실행함을 나타내고,
    그 뒤부터는 위의 setInterval이 1초마다 실행해줌

찾아본 내용, 알게된 내용들

transform-origin - 변형 효과를 줄 때 원점을 지정해줌
transform: rotate() - 원점으로부터 회전 각도를 설정할 때 사용
transition - 변형 효과를 줄때 애니메이션 속도를 조절할 때 사용
setInterval - 특정 시간마다 함수를 실행할 때 사용

끝!

'개발 > JavaScript30' 카테고리의 다른 글

5. Flex Panel Gallery  (0) 2017.04.05
4. Array Cardio Day 1  (0) 2017.04.04
3. CSS Variables  (0) 2017.04.03
2. CSS + JS Clock  (0) 2017.04.03
1. JavaScript Drum Kit  (0) 2017.03.30
0. JavaScript30 Challenge  (0) 2017.03.30


JavaScript Drum Kit

위에 첨부한 사진처럼 해당하는 키보드를 누르면 화면에 효과와 함께 소리가 나는 드럼 킷을 만드는 것

기본 코드

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JS Drum Kit</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="keys">
    <div data-key="65" class="key">
      <kbd>A</kbd>
      <span class="sound">clap</span>
    </div>
    <div data-key="83" class="key">
      <kbd>S</kbd>
      <span class="sound">hihat</span>
    </div>
    <div data-key="68" class="key">
      <kbd>D</kbd>
      <span class="sound">kick</span>
    </div>
    <div data-key="70" class="key">
      <kbd>F</kbd>
      <span class="sound">openhat</span>
    </div>
    <div data-key="71" class="key">
      <kbd>G</kbd>
      <span class="sound">boom</span>
    </div>
    <div data-key="72" class="key">
      <kbd>H</kbd>
      <span class="sound">ride</span>
    </div>
    <div data-key="74" class="key">
      <kbd>J</kbd>
      <span class="sound">snare</span>
    </div>
    <div data-key="75" class="key">
      <kbd>K</kbd>
      <span class="sound">tom</span>
    </div>
    <div data-key="76" class="key">
      <kbd>L</kbd>
      <span class="sound">tink</span>
    </div>
  </div>
  <audio data-key="65" src="sounds/clap.wav"></audio>
  <audio data-key="83" src="sounds/hihat.wav"></audio>
  <audio data-key="68" src="sounds/kick.wav"></audio>
  <audio data-key="70" src="sounds/openhat.wav"></audio>
  <audio data-key="71" src="sounds/boom.wav"></audio>
  <audio data-key="72" src="sounds/ride.wav"></audio>
  <audio data-key="74" src="sounds/snare.wav"></audio>
  <audio data-key="75" src="sounds/tom.wav"></audio>
  <audio data-key="76" src="sounds/tink.wav"></audio>

<script>

</script>
</body>
</html>

여기서 div 속성중 data-key 는 어떤 키를 눌러서 실행 시킬수 있는지 설정하는 것이며
http://keycode.info/ 에서 각 키의 키코드를 알 수 있다.
<kbd>태그는 처음봤는데 키보드 입력을 지정할 때 쓰는 코드라고 한다.
data-key 속성은 위의 div와 아래 audio를 하나로 묶어주는 속성이라 할 수 있다.

목표

키보드 키 입력시 애니메이션효과와 소리를 출력해 드럼 킷을 만드는 것

과정

  1. 해당 키 입력시 효과음 추가하는 함수 생성
  2. 키 재입력 시간 설정(연속 입력 가능하도록)
  3. 효과 종료시 변화하는 함수 생성
  4. 효과음 출력 및 종료 설정

코드 분석

  1. 해당 키 입력시 효과음 추가하는 함수 생성

    function playSound(e) {
     const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
     const key = document.querySelector(`div[data-key="${e.keyCode}"]`);
     if (!audio) return;
    
     key.classList.add('playing');
     audio.play();
    }
    

    audio, key에 각각 누른 키보드의 keyCode와 일치하는 속성을 가진 요소들을 담아주고
    일치하는 audio가 없다면 아래코드를 실행하지 않고, 일치한다면 누른 버튼에 playing클래스를 추가해주고
    해당 소리를 play하는 playSound()함수를 생성

  2. 키 재입력 시간 설정(연속 입력 가능하도록)

    audio.currentTime = 0;
    

    오디오 재생의 현재 위치를 0초로 이동함. 이로써 입력 후 다시입력하면 같은 소리를 재생시킬 수 있어
    소리가 끝나야 입력이 가능했던게 연속으로도 입력이 가능함
    위의 코드를 audio.play() 위에 삽입함

  3. 효과 종료시 변화하는 함수 생성

    function removeTransition(e) {
     if (e.propertyName !== 'transform') return;
     e.target.classList.remove('playing');
    }
    

    누른 키의 속성명중 transform이 이 없으면 다음 코드를 실행하지 않고,
    존재한다면 playing이란 클래스를 지우도록하는 removeTransition()함수를 생성

  4. 효과음 출력 및 종료 설정

    const keys = Array.from(document.querySelectorAll('.key'));
    keys.forEach(key => key.addEventListener('transitionend', removeTransition));
    window.addEventListener('keydown', playSound);
    

    key 클래스를 가진 모든 요소를 keys에 배열로 담고
    반복자 forEach를 사용해 각각의 요소에 변화가 끝나면(transitionend) removeTransition 함수를 실행하고,
    keydown 이라는 이벤트 타입을 실행하면 playSound함수가 작동함

찾아본 내용, 알게된 내용들

const - const는 ES6 문법으로 내용이 변하지 않는 값을 넣을 때 사용함(상수 선언)
keydown - 키를 누를 때 작동하는 것, 참고로 keyup은 키를 누르고 뗄 때 작동

'개발 > JavaScript30' 카테고리의 다른 글

5. Flex Panel Gallery  (0) 2017.04.05
4. Array Cardio Day 1  (0) 2017.04.04
3. CSS Variables  (0) 2017.04.03
2. CSS + JS Clock  (0) 2017.04.03
1. JavaScript Drum Kit  (0) 2017.03.30
0. JavaScript30 Challenge  (0) 2017.03.30

+ Recent posts