Sticky Nav

목표

요즘 웹 브라우저에 많이 쓰이는 상단에 네비게이션바 고정을 자바스크립트로 구현

기본 코드

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Sticky Nav</title>
  <link rel="stylesheet" href="style-START.css">
</head>
<body>
  <header>
    <h1>A story about getting lost.</h1>
  </header>
  <nav id="main">
    <ul>
      <li class="logo"><a href="#">LOST.</a></li>
      <li><a href="#">Home</a></li>
      <li><a href="#">About</a></li>
      <li><a href="#">Images</a></li>
      <li><a href="#">Locations</a></li>
      <li><a href="#">Maps</a></li>
    </ul>
  </nav>
  <div class="site-wrap">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>

    <img src="http://unsplash.it/400/400" class="align-right slide-in">

    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>
  </div>
<script>
</script>
</body>
</html>

원래 쓸모없는 내용이 많지만 다 짤랐음, CSS속성도 따로 작성하지 않았음

과정

  1. 상수, 변수 생성
  2. 스크롤시 상단에 nav바를 고정하도록 함수 생성 및 실행

코드 분석

  1. 상수, 변수 생성

     const nav = document.querySelector('#main');
     let topOfNav = nav.offsetTop;
    

    nav에 id가 main인 태그를 담고, topOfNav에 nav태그의 상단 좌표값을 담음

  2. 스크롤시 상단에 nav바를 고정하도록 함수 생성 및 실행

     function fixNav() {
         if(window.scrollY >= topOfNav) {
             document.body.style.paddingTop = nav.offsetHeight + 'px';
             document.body.classList.add('fixed-nav');
         } else {    document.body.classList.remove('fixed-nav');
             document.body.style.paddingTop = 0;
         }
     }
     window.addEventListener('scroll', fixNav);
    

    fixNav에 스크롤을 nav바의 높이 이상으로 내리면 fixed-nav 클래스를 추가해 nav의 상단에 패딩을 줘서
    스크롤을 내려도 상단에 nav바가 고정되도록 함.
    그 이하만큼 스크롤한다면 fixed-nav 클래스를 삭제하고 패딩을 0으로 줌
    스크롤을할 때 fixNav 함수를 실행

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

offset() - 문서에서 요소의 상대적인 위치를 알아낼 때 사용, 보통 nav바를 만들 때 사용

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

26. Stripe Follow Along Nav  (0) 2017.04.19
25. Event Capture, Propagation, Bubbling and Once  (0) 2017.04.19
24. Sticky Nav  (0) 2017.04.18
23. Speech Synthesis  (0) 2017.04.18
22. Following Along Link Highlight  (0) 2017.04.18
21. Geolocation  (0) 2017.04.17

Speech Synthsis

목표

자바스크립트 SpeechSynthesisUtterance API로 글을 읽어주는 도구 구현

기본 코드

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Speech Synthesis</title>
  <link href='https://fonts.googleapis.com/css?family=Pacifico' rel='stylesheet' type='text/css'>
  <link rel="stylesheet" href="style.css">
</head>
<body>

    <div class="voiceinator">

      <h1>The Voiceinator 5000</h1>

      <select name="voice" id="voices">
        <option value="">Select A Voice</option>
      </select>

      <label for="rate">Rate:</label>
      <input name="rate" type="range" min="0" max="3" value="1" step="0.1">

      <label for="pitch">Pitch:</label>

      <input name="pitch" type="range" min="0" max="2" step="0.1">
      <textarea name="text">Hello! I love JavaScript 👍</textarea>
      <button id="stop">Stop!</button>
      <button id="speak">Speak</button>
    </div>
<script>
</script>
</body>
</html>

과정

  1. 사용 가능한 목소리 리스트 출력
  2. 재생, 정지 버튼 생성
  3. 목소리 설정
  4. 옵션 설정

코드 분석

  const msg = new SpeechSynthesisUtterance();
  let voices = [];
  const voicesDropdown = document.querySelector('[name="voice"]');
  const options = document.querySelectorAll('[type="range"], [name="text"]');
  const speakButton = document.querySelector('#speak');
  const stopButton = document.querySelector('#stop');
msg.text = document.querySelector('[name="text"]).value;

기능을 구현하기 위한 변수, 상수 설정

  1. 사용 가능한 목소리 리스트 출력

    function populateVoices() {
     voices = this.getVoices();
     voicesDropdown.innerHTML = voices
         .filter(voice => voice.lang.includes('en'))
         .map(voice => `<option value="${voice.name}">${voice.name} (${voice.lang})</option>`)
         .join('');
    }
    speechSynthesis.addEventListener('voiceschanged', populateVoices);
    

    voices에 사용 가능한 모든 목소리들을 담고, en즉 영어를 지원하는 목소리들만 option으로 걸러내 HTML에 출력하는 함수 populateVoices에 담음
    getVoices가 변경되면 populateVoices를 실행

  2. 재생, 정지 버튼 생성

    function toggle(startOver =true) {
     speechSynthesis.cancel();
     if(startOver) {
         speechSynthesis.speak(msg);
     }
    }
    speakButton.addEventListener('click', toggle);
    stopButton.addEventListener('click', () => toggle(false));
    

    toggle함수로 메세지를 읽을 수 있도록 함. 이때 이미 speechSynthesis가 실행, 즉 음성이 재생중이면 종료하고 재시작함.
    speak 버튼으로 실행, stop 버튼으로 정지함.

  3. 목소리 설정

    function setVoice() {
     msg.voice = voices.find(voice => voice.name === this.value);
     toggle();
    }
    voicesDropdown.addEventListener('change', setVoice)
    

    setVoice에 메세지의 목소리를 선택한 이름에 따라서 선택할 수 있도록 함수 생성.
    목소리 선택 후에 자동으로 toggle() 함수 실행으로 글을 읽을 수 있도록 함

  4. 옵션 설정

     function setOption() {
         msg[this.name] = thi s.value;
         toggle();
     }
     options.forEach(option => option.addEventListener('change', setOption));
    

    options 레인지바에서 값을 조정하면 바뀐 값으로 글을 한번 읽어줌

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

이번꺼 역시도 “별게 다되네” 라는 생각이 들지만, 새로운 API를 알게된 것 이외에 나왔던 함수, 이벤트들이 반복되어 익숙하게 다룰 수 있도록 하는것이 중요함

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

25. Event Capture, Propagation, Bubbling and Once  (0) 2017.04.19
24. Sticky Nav  (0) 2017.04.18
23. Speech Synthesis  (0) 2017.04.18
22. Following Along Link Highlight  (0) 2017.04.18
21. Geolocation  (0) 2017.04.17
20. Native Speech Recognition  (1) 2017.04.17

Follow Along Link Highlighter

목표

표시해놓은 링크에 포인터가 올라가면 효과를 주는 방법을 알아봄.

기본 코드

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>👀👀👀Follow Along Nav</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>

    <nav>
      <ul class="menu">
        <li><a href="">Home</a></li>
        <li><a href="">Order Status</a></li>
        <li><a href="">Tweets</a></li>
        <li><a href="">Read Our History</a></li>
        <li><a href="">Contact Us</a></li>
      </ul>
    </nav>

    <div class="wrapper">
      <p>Lorem ipsum dolor sit amet, <a href="">consectetur</a> adipisicing elit. Est <a href="">explicabo</a> unde natus necessitatibus esse obcaecati distinctio, aut itaque, qui vitae!</p>
      <p>Aspernatur sapiente quae sint <a href="">soluta</a> modi, atque praesentium laborum pariatur earum <a href="">quaerat</a> cupiditate consequuntur facilis ullam dignissimos, aperiam quam veniam.</p>
      <p>Cum ipsam quod, incidunt sit ex <a href="">tempore</a> placeat maxime <a href="">corrupti</a> possimus <a href="">veritatis</a> ipsum fugit recusandae est doloremque? Hic, <a href="">quibusdam</a>, nulla.</p>
      <p>Esse quibusdam, ad, ducimus cupiditate <a href="">nulla</a>, quae magni odit <a href="">totam</a> ut consequatur eveniet sunt quam provident sapiente dicta neque quod.</p>
  <script>
  </script>
</body>
</html>

과정

  1. 상수, 태그 생성
  2. 효과 적용을 위한 함수 생성
  3. 효과 적용

코드 분석

  1. 상수, 태그 생성

    const triggers = document.querySelectorAll('a');
    const hightlight = document.createElement('span');
    highlight.classList.add('highlight');
    document.body.appendChild(highlight);
    

    a태그를 triggers에 담고. highlight로 새로운 span태그를 만들어 highlight클래스를 붙여 body의 최하단에 붙임.

  2. 효과 적용을 위한 함수 생성

    function highlightLink() {
     const linkCoords = this.getBoundingClientRect();
     console.log(linkCoords);
     const coords = {
         width: linkCoords.width,
         height: linkCoords.height,
         top: linkCoords.top + window.scrollYm
         left: linkCoords.left + window.scrollX
     };
     highlight.style.width = `${coords.width}px`;
     highlight.style.height = `${coords.height}px`;
     highlight.style.transform = `translate(${coords.left}px, ${coords.top}px)`;
    }
    

    coords로 현재 태그의 길이,높이, 좌표값을 알아 낸 후에 highlight 클래스에 적용된 효과를 그대로 적용해줌.

  3. 효과 적용

    triggers.forEach(a => a.addEventListener('mouseenter', hightlightLink));
    

    각각의 a태그에 대해 마우스가 올라갔을 때 highlightLink를 실행

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

appenChild() - 한 노드를 특정 부모노드의 자식 노드 리스트중 마지막에 삽입
getBoundingClientRect() - 요소의 사이즈를 설정하는 함수

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

24. Sticky Nav  (0) 2017.04.18
23. Speech Synthesis  (0) 2017.04.18
22. Following Along Link Highlight  (0) 2017.04.18
21. Geolocation  (0) 2017.04.17
20. Native Speech Recognition  (1) 2017.04.17
19. Webcam Fun  (0) 2017.04.17

Geolocation

목표

나침반과 현재속도를 출력

기본 코드

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <meta name="viewport" content="width=device-width">
</head>
<body>
  <h1 class="speed">
    <span class="speed-value">0</span>
    <span class="units">KM/H</span>
  </h1>

  <style>
    html {
      font-size: 100px;
    }
    body {
      margin: 0;
      font-family: sans-serif;
      min-height:100vh;
      display:flex;
      justify-content: center;
      align-items: center;
      flex-direction: column;
      background:
        radial-gradient(black 15%, transparent 16%) 0 0,
        radial-gradient(black 15%, transparent 16%) 8px 8px,
        radial-gradient(rgba(255,255,255,.1) 15%, transparent 20%) 0 1px,
        radial-gradient(rgba(255,255,255,.1) 15%, transparent 20%) 8px 9px;
      background-color:#282828;
      background-size:16px 16px;
      background-attachment: fixed;
    }

    .arrow {
      width:250px;
      overflow: hidden;
      transition: all 0.2s;
      transform:rotate(0deg);
      display: inline-block;
    }

    h1 {
      color:white;
      font-weight: 100;
      font-size: 60px;
      display:flex;
      align-items: center;
    }

    .units {
      font-size: 15px;
    }
    /*Compass: https://thenounproject.com/search/?q=compass&i=592352*/
  </style>
  <script>
  </script>
</body>
</html>

과정

  1. 상수 선언
  2. 현재위치, 속도 값 얻는 함수 생성 및 출력

코드 분석

  1. 상수 선언

     const arrow = document.querySelector('.arrow');
     const speed = document.querySelector('.speed-value');
    

    arrowspeed에 요소들을 선택

  2. 현재위치, 속도 값 얻는 함수 생성 및 출력

    navigator.geolocation.watchPosition((data) => {
         console.log(data);
         speed.textContent = data.coords.speed;
         arrow.style.transform = `rotate(${data.coords.heading}deg)`;
     }, (err) => {
         console.error(err);
     });
    

    navigator.geolocation으로 geolocation API를 사용 가능하며 watchPosition으로 현재 위치를 식별하는데 사용되며 data.coords.speed로 현재 속도를 알아내 HTML 요소에 바인딩함

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

geolocation API - 웹 어플리케이션에서 사용자의 위치 정보를 받아 제공, 나침반이나 속도계를 만들 때 사용할 수 있음

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

23. Speech Synthesis  (0) 2017.04.18
22. Following Along Link Highlight  (0) 2017.04.18
21. Geolocation  (0) 2017.04.17
20. Native Speech Recognition  (1) 2017.04.17
19. Webcam Fun  (0) 2017.04.17
18. Adding Up Times with Reduce  (0) 2017.04.16

데일리 후보란

대선후보들의 행선지를 쉽게 알아볼 수 있도록 타임라인에 표시 해놓은 웹사이트
데일리 후보 링크

후기

반년넘게 개발 공부하면서 제대로 프로젝트를 마쳐본적이 없는데, 우연히 멋사를 하면서 이런 기회가 생겨 중간합류해서 팀원들과 3일동안 같이 머리 싸매서 만들었다.

“정치”의 “정” 자도 모르지만 일단 프로젝트라길래 하고 싶었음.

이번 프로젝트에서 전반적인 프론트 작업을 맡아 했는데, 결과물을 막상 보니까 디자이너의 부재를 크게 실감했다..주륵

그래도 3일정도에 기능구현이나 전반적인 시스템자체는 다른분들이 맡아서 잘해주셔서 구현하려고 했던 기능들은 잘 돌아가는것 같아서 그건 그나마 다행인듯..ㅋㅎ

의견이 갈리는 부분에서 맞춰가고 각자 맡은 역할에서 열심히 코드짜고 합치는 과정 하나하나가 생각보다 더 재밌었던것 같고 기회가 되면 또 하고 싶다. 대형 프로젝트면 더 재미있을 듯 함!

셀프 피드백

  1. 디자이너가 있었으면 어땠을까
    확실히 지금보다 아름답고 정교한 결과물이 나오지 않았을까 생각해봄. 프로젝트 하기 전까지는 “디자이너가 뭐가 중요하겠어”라는 위험한 생각을 했는데 막상 해보니 부재가 아주 크게 느껴졌음.

  2. 깃허브를 좀 잘 다뤘으면 파일 관리가 더 쉽지 않았을까
    내가 혼자 할때의 명령어밖에 모르고 브랜치, 머지같은 협업할 때 필요한 명령어들을 제대로 사용할 줄을 모르니까 아주 고전적인 압축>파일전송으로 코드를 나눴는데 자괴감이..후~

  3. 페이지를 짜는 도중에 시안이 너무 많이 수정돼서 시간이 조금 더 걸렸다는 점?
    처음 설계할 때 조금더 정교하게 토의하면서 같이 작성했다면 더 좋은 결과물을 더 빨리 뽑아냈을 것 같다. 물론 이번 프로젝트는 짧은 기간에 결과물을 만들어 내야했기에 아쉬웠던점은 있지만, 시간에 대비해서는 양질의 기획서였던것 같다.

  4. 호스팅 방법을 좀 알아볼 필요가 있음
    직접 서버에 띄워본적도 없고 AWS도 쓸줄 모르는데 그냥 도메인 사서 AWS에 올리면 되지 하고 생각만 했는데 도메인사는 사이트도 엄청 많고, 찾아보니까 속도도 제각각이라하고.. 모르는부분들을 좀 찾아서 공부할 필요가 있을 것 같음

  5. CSS 공부
    해도해도 내가 원하는 포지션이 안나오는지 당최 이해할 수가 없다. 아주 스트레스 공부가 더 필요함을 다시 느낌 flex, media query 좀 자세히 알아야 할 것 같다

그래도 완성하고나니까 뿌듯하다 흐흐
가셔서 댓글한번씩만.. 쿠흠..


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

Coin Push 프로젝트  (0) 2018.01.29
티스토리 블로그 폰트 바꾸기  (4) 2017.10.14
[git]Git 간편 사용 설명서  (0) 2017.05.27
Git, Github 10분만에 익히기  (0) 2017.04.25
"데일리후보" 단기 프로젝트 완성  (3) 2017.04.17
HTML,CSS용 VIM(8.0)세팅하기  (0) 2017.02.21
  1. 홍지환 2017.04.17 18:31 신고

    W😮W

  2. BlogIcon takeu takeU 2017.04.18 15:14 신고

    ㅋㅋㅋㅋㅋ아놔

  3. 홍지환 2017.04.19 23:15 신고

    휼륭합니다

Native Speech Recognition

목표

웹캠 촬영에 이어 음성인식을 구현해 보려함
진짜 자바스크립트는 안되는게 없나봄

기본 코드

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Speech Detection</title>
</head>
<body>
  <div class="words" contenteditable>
  </div>
<script>
  window.SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
</script>

<style>
html {
  font-size: 10px;
}
body {
  background:#ffc600;
  font-family: 'helvetica neue';
  font-weight: 200;
  font-size: 20px;
}

.words {
  max-width:500px;
  margin:50px auto;
  background:white;
  border-radius:5px;
  box-shadow:10px 10px 0 rgba(0,0,0,0.1);
  padding:1rem 2rem 1rem 5rem;
  background: -webkit-gradient(linear, 0 0, 0 100%, from(#d9eaf3), color-stop(4%, #fff)) 0 4px;
  background-size: 100% 3rem;
  position: relative;
  line-height:3rem;
}
p {
  margin: 0 0 3rem;
}

.words:before {
  content: '';
  position: absolute;
  width: 4px;
  top: 0;
  left: 30px;
  bottom: 0;
  border: 1px solid;
  border-color: transparent #efe4e4;
}
</style>
</body>
</html>

과정

코드 분석

  1. 브라우저에서 음성인식을 위해 설정

    window.SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
    

    브라우저에 따라 webkit속성을 적용

  2. 음성인식을 할 수 있도록 상수 생성

    const recognition = new SpeechRecognition();
    recognition.interimResults = true;
    

    recognition에 음성인식을 할 수 있는 함수를 담아 반환값을 주도록 함

  3. 말한 내용을 p태그로 브라우저에 표시

    let p = document.createElement('p');
    const words = document.querySelector('.words');
    words.appendChild(p);
    
    recognition.addEventListener('result', e => {
     const transcript = Array.from(e.results)
       .map(result => result[0])
       .map(result => result.transcript)
       .join('');
    
       const poopScript = transcript.replace(/poop|poo|shit|dump/gi, '💩');
       p.textContent = poopScript;
    
       if (e.results[0].isFinal) {
         p = document.createElement('p');
         words.appendChild(p);
       }
    });
    

    words에 클래스가 word인 요소를 담아 말하는 내용을 담음
    음성인식의 결과를 배열로 변환해 텍스트에 담고, 비속어는 💩로 표시함
    말이 끝나면 p에 한 문장으로 내용을 담고 말이 끝나면 새로운 문장에 다시 시작됨

  4. 이벤트 실행

    recognition.addEventListener('end', recognition.start);
    
    recognition.start();
    

    말을 하면 음성인식이 시작되고, 멈추면 음성인식이 다시 시작된다

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

webkit - 사파리에서 사용하다 브라우저 전역으로 확대, 각종 기능들을 가지고 있음


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

22. Following Along Link Highlight  (0) 2017.04.18
21. Geolocation  (0) 2017.04.17
20. Native Speech Recognition  (1) 2017.04.17
19. Webcam Fun  (0) 2017.04.17
18. Adding Up Times with Reduce  (0) 2017.04.16
17. Sort Without Articles  (0) 2017.04.13
  1. JW 2018.06.15 10:29 신고

    안녕하세요:0
    자바스크립트로 STT를 구현하려고 하는데 정말 잘 봤습니다.
    제가 그대로 진행해보았는데 마이크가 차단된 페이지라고 나오네요ㅠ
    setting에서 마이크차단을 풀어도 계속 그러네요,,
    혹시 해결방법을 아시나요?ㅠ
    좋은 내용 정말 감사합니다!!

Webcam Fun

목표

페이지로 사진을 찍을 수 있게 웹캠기능을 적용

기본 코드

//HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Get User Media Code Along!</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>

  <div class="photobooth">
    <div class="controls">
      <button onClick="takePhoto()">Take Photo</button>
<!--       <div class="rgb">
        <label for="rmin">Red Min:</label>
        <input type="range" min=0 max=255 name="rmin">
        <label for="rmax">Red Max:</label>
        <input type="range" min=0 max=255 name="rmax">

        <br>

        <label for="gmin">Green Min:</label>
        <input type="range" min=0 max=255 name="gmin">
        <label for="gmax">Green Max:</label>
        <input type="range" min=0 max=255 name="gmax">

        <br>

        <label for="bmin">Blue Min:</label>
        <input type="range" min=0 max=255 name="bmin">
        <label for="bmax">Blue Max:</label>
        <input type="range" min=0 max=255 name="bmax">
      </div> -->
    </div>

    <canvas class="photo"></canvas>
    <video class="player"></video>
    <div class="strip"></div>
  </div>

  <audio class="snap" src="http://wesbos.com/demos/photobooth/snap.mp3" hidden></audio>

  <script src="scripts-FINISHED.js"></script>

</body>
</html>

과정

  1. 요소에 대응되는 상수 생성
  2. 화면에 웹캠 출력
  3. 웹캠의 크기, 위치조정
  4. 사진을 찍고, 저장할 수 있도록 함수 생성
  5. 웹캠에 효과 설정 레인지바 생성, 실행

코드 분석

  1. 요소에 대응되는 상수 생성

    const video = document.querySelector('.player');
    const canvas = document.querySelector('.photo');
    const ctx = canvas.getContext('2d');
    const strip = document.querySelector('.strip');
    const snap = document.querySelector('.snap');
    
  2. 화면에 웹캠 출력

    function getVideo() {
    navigator.mediaDevices.getUserMedia({ video: true, audio: false })
     .then(localMediaStream => {
       console.log(localMediaStream);
       video.src = window.URL.createObjectURL(localMediaStream);
       video.play();
     })
     .catch(err => {
       console.error(`OH NO!!!`, err);
     });
    }
    

    getViedo함수에 실시간으로 웹캠의 화면이 나올수 있도록 내용을 작성해주고,
    에러가 있을때 콘솔에 ‘OH NO!!!’라는 메세지가 실행되도록 함

  3. 웹캠의 크기, 위치조정

    function paintToCanvas() {
    const width = video.videoWidth;
    const height = video.videoHeight;
    canvas.width = width;
    canvas.height = height;
    
    return setInterval(() => {
     ctx.drawImage(video, 0, 0, width, height);
     let pixels = ctx.getImageData(0, 0, width, height);
    
     ctx.putImageData(pixels, 0, 0);
    }, 16);
    }
    

    웹캠에서 효과를 적용할 범위를 웹캠의 가로, 세로길이에 맞춰 widthheight에 담고
    중앙에 효과가 적용될 새로운 웹캠 화면을 띄워줌

  4. 사진을 찍고, 저장할 수 있도록 함수 생성

    function takePhoto() {
    // played the sound
    snap.currentTime = 0;
    snap.play();
    
    // take the data out of the canvas
    const data = canvas.toDataURL('image/jpeg');
    const link = document.createElement('a');
    link.href = data;
    link.setAttribute('download', 'handsome');
    link.innerHTML = `<img src="${data}" alt="Handsome Man" />`;
    strip.insertBefore(link, strip.firsChild);
    }
    

    takePhoto()에 버튼을 눌러 사진을 찍으면 찰칵 소리가나도록 소리를 삽입하고,
    이미지를 저장할 수 있도록 파일 형식을 설정하고 다운받을수 있도록 함
    또한 찍은 이미지가 웹캠 아래에 순서대로 정렬되도록 함

  5. 웹캠에 효과 설정 레인지바 생성, 실행

    function redEffect(pixels) {
    for(let i = 0; i < pixels.data.length; i+=4) {
     pixels.data[i + 0] = pixels.data[i + 0] + 200; // RED
     pixels.data[i + 1] = pixels.data[i + 1] - 50; // GREEN
     pixels.data[i + 2] = pixels.data[i + 2] * 0.5; // Blue
    }
    return pixels;
    }
    function rgbSplit(pixels) {
    for(let i = 0; i < pixels.data.length; i+=4) {
     pixels.data[i - 150] = pixels.data[i + 0]; // RED
     pixels.data[i + 500] = pixels.data[i + 1]; // GREEN
     pixels.data[i - 550] = pixels.data[i + 2]; // Blue
    }
    return pixels;
    }
    function greenScreen(pixels) {
    const levels = {};
    
    document.querySelectorAll('.rgb input').forEach((input) => {
     levels[input.name] = input.value;
    });
    for (i = 0; i < pixels.data.length; i = i + 4) {
     red = pixels.data[i + 0];
     green = pixels.data[i + 1];
     blue = pixels.data[i + 2];
     alpha = pixels.data[i + 3];
    
     if (red >= levels.rmin
       && green >= levels.gmin
       && blue >= levels.bmin
       && red <= levels.rmax
       && green <= levels.gmax
       && blue <= levels.bmax) {
       // take it out!
       pixels.data[i + 3] = 0;
     }
    }
    return pixels;
    }
    getVideo();
    video.addEventListener('canplay', paintToCanvas);
    

    이미지에 효과 부여 및 이벤트 실행

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

길기도 길고 실용성이 너무 떨어지지만 빼먹긴 싫어서 일단 포스팅했지만, 나중에 내용 보충해야할듯..

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

21. Geolocation  (0) 2017.04.17
20. Native Speech Recognition  (1) 2017.04.17
19. Webcam Fun  (0) 2017.04.17
18. Adding Up Times with Reduce  (0) 2017.04.16
17. Sort Without Articles  (0) 2017.04.13
16. Mouse Move Shadow  (0) 2017.04.13

Adding Up Times with Reduce

목표

목록의 동영상들의 총 재생시간을 구하는 것

기본 코드

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Videos</title>
</head>
<body>
  <ul class="videos">
    <li data-time="5:43">
      Video 1
    </li>
    <li data-time="2:33">
      Video 2
    </li>
    <li data-time="3:45">
      Video 3
    </li>
    <li data-time="0:47">
      Video 4
    </li>
    <li data-time="5:21">
      Video 5
    </li>
    <li data-time="6:56">
      Video 6
    </li>
    <li data-time="3:46">
      Video 7
    </li>
    <li data-time="5:25">
      Video 8
    </li>
    <li data-time="3:14">
      Video 9
    </li>
    <li data-time="3:31">
      Video 10
    </li>
  </ul>
<script>
</script>
</body>
</html>

과정

  1. 배열 선언
  2. 동영상들의 총 재생시간을 초단위로 구함
  3. 총 재생시간을 시, 분, 초로 바꿔줌

코드 분석

  1. 배열 선언

    const timeNodes = Array.from(document.querySelectorAll('[data-time]'));
    

    timeNode[data-time]을 가진 태그들을 배열로 담아준다.

  2. 동영상들의 총 재생시간을 초단위로 구함

    const seconds = timeNodes
     .map(node => node.dataset.time)
     .map(timeCode => {
       const [mins, secs] = timeCode.split(':').map(parseFloat);
       return (mins * 60) + secs;
     })
     .reduce((total, vidSeconds) => total + vidSeconds);
    

    seconds에 배열의 값들의 재생시간을 담고,
    재생시간을 :를 기준으로 분, 초로 나눠 분값에 60을 곱해 총 재생 시간을 초단위로 뽑아내 정수로 출력,
    그 뒤에 total에 모든 동영상의 재생시간을 합한 값을 출력한다.

  3. 총 재생시간을 시, 분, 초로 바꿔줌

     let secondsLeft = seconds;
     const hours = Math.floor(secondsLeft / 3600);
     secondsLeft = secondsLeft % 3600;
    
     const mins = Math.floor(secondsLeft / 60);
     secondsLeft = secondsLeft % 60;
    
     console.log(hours, mins, secondsLeft);
    

    secondsLeft에 총 재생시간(초단위)를 담아,
    3600으로 나눈 몫, 즉 시간을 hours에 담고
    나머지를 secondsLeft에 담아 60으로 나눈 몫을 mins에 담고 그나머지를 secondsLeft에 담는다.
    결과적으로 hours,mins,secondsLeft에 총 재생시간이 시, 분, 초 단위로 담기게 된다.

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

reduce - 누산기 역할을 함. 전에도 찾아본건데 또 찾아봄.. 복습이 중요한걸 다시 깨달았다.

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

20. Native Speech Recognition  (1) 2017.04.17
19. Webcam Fun  (0) 2017.04.17
18. Adding Up Times with Reduce  (0) 2017.04.16
17. Sort Without Articles  (0) 2017.04.13
16. Mouse Move Shadow  (0) 2017.04.13
15. LocalStorage  (0) 2017.04.13

Sort Without Articles

목표

배열의 내용에서 부사를 제거한 뒤 알파벳 순으로 재배열

기본 코드

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Sort Without Articles</title>
</head>
<body>
  <ul id="bands"></ul>
<script>
const bands = ['The Plot in You', 'The Devil Wears Prada', 'Pierce the Veil', 'Norma Jean', 'The Bled', 'Say Anything', 'The Midway State', 'We Came as Romans', 'Counterparts', 'Oh, Sleeper', 'A Skylit Drive', 'Anywhere But Here', 'An Old Dog'];
</script>
</body>
</html>

과정

  1. 부사를 제거할 수 있는 함수 생성
  2. 배열을 재정렬
  3. 문서에 매핑

코드 분석

  1. 부사를 제거할 수 있는 함수 생성

    function strip(bandName) {
     return bandName.replace(/^(a |the |an )/i, '').trim();
    }
    

    인자로 bandName을 넣으면 내용중 a, the, an 을 공백으로 바꾸고 공백을 제거하는 함수 strip()을 생성

  2. 배열을 재정렬

    const sortedBands = bands.sort((a, b) => strip(a) > strip(b) ? 1 : -1);
    

    sortedBandsbands의 내용을 알파벳 순서대로 재정렬해 담음

  3. 문서에 매핑

    document.querySelector('#bands').innerHTML = sortedBands.map(band => '<li>${band}</li>').join('');
    

    새 배열을 리스트에 하나씩 담아 bands를 id로 갖는 요소에 매핑한다

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

trim() - 데이터에 있는 공백과 탭을 제거하는 메소드

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

19. Webcam Fun  (0) 2017.04.17
18. Adding Up Times with Reduce  (0) 2017.04.16
17. Sort Without Articles  (0) 2017.04.13
16. Mouse Move Shadow  (0) 2017.04.13
15. LocalStorage  (0) 2017.04.13
14. JavaScript Reference VS Copying  (0) 2017.04.12

Mouse Move Shadow

목표

마우스 움직임에 따라 텍스트에 효과가 적용돼 움직이도록 해보려 함

기본 코드

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Mouse Shadow</title>
</head>
<body>

  <div class="hero">
    <h1 contenteditable>🔥WOAH!</h1>
  </div>
<script>
</script>
</body>
</html>

CSS코드는 뺐음

과정

  1. 함수 생성을 위한 상수 생성
  2. 그림자를 만드는 함수 생성 및 좌표값 기준 설정
  3. 마우스 이동시 그림자의 위치, 색상 설정
  4. 함수 호출

코드 분석

  1. 함수 생성을 위한 상수 생성

    const hero = document.querySelector('.hero');
    const text = hero.querySelector('h1');
    const walk = 500; // 100px
    

    hero에 클래스가 hero인 요소를 담고, texthero중 h1태그를 담고 walk에 500을 담음

  2. 그림자를 만드는 함수 생성 및 좌표값 기준 설정

    function shadow(e) {
     const { offsetWidth: width, offsetHeight: height } = hero;
     let { offsetX: x, offsetY: y } = e;
    
     if (this !== e.target) {
       x = x + e.target.offsetLeft;
       y = y + e.target.offsetTop;
     }
    

    가장 위에 선언된 상수는 아래 두줄을 한줄로 합친것과 같다

    const { offsetWidth: width, offsetHeight: height} = hero
    const width = hero.offsetWidth
    const height = hero.offsetHeight
    

    width에 hero의 가로길이, height에 hero의 세로길이를 담고(border까지의 길이)
    x,y에 현재 요소를 기준으로 마우스 위치의 절대좌표를 담는다
    조건문의 조건을 해석해보면 현재 마우스의 위치가 <div class="hero">안의 h1태그 위에 있을때 참임을 반환한다는 뜻이고 이때 x,y값을 뷰포트를 기준으로 값이 나올 수 있도록 재 설정해준다는 의미이다.
    즉 마우스가 h1태그 위에 있던 없던간에 좌표값(x,y)은 전체 뷰포트를 기준으로 찍힌다.

  3. 마우스 이동시 그림자의 위치, 색상 설정

     const xWalk = Math.round((x / width * walk) - (walk / 2));
     const yWalk = Math.round((y / height * walk) - (walk / 2));
    
     text.style.textShadow = `
       ${xWalk}px ${yWalk}px 0 rgba(255,0,255,0.7),
       ${xWalk * -1}px ${yWalk}px 0 rgba(0,255,255,0.7),
       ${yWalk}px ${xWalk * -1}px 0 rgba(0,255,0,0.7),
       ${yWalk * -1}px ${xWalk}px 0 rgba(0,0,255,0.7)
     `;
    }
    

    xWalkyWalk의 좌표값 기준을 -250에서 250으로 변경해주고
    그림자의 방향을 각각 설정해 총 4개의 그림자가 나오도록 설정해줌

  4. 함수 호출

     hero.addEventListener('mousemove', shadow);
    

    마우스가 움직이면 shadow 함수를 실행

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

contenteditable - 컨텐츠를 수정할 수 있게 해주는 속성

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

18. Adding Up Times with Reduce  (0) 2017.04.16
17. Sort Without Articles  (0) 2017.04.13
16. Mouse Move Shadow  (0) 2017.04.13
15. LocalStorage  (0) 2017.04.13
14. JavaScript Reference VS Copying  (0) 2017.04.12
13. Slide in on scroll  (0) 2017.04.12

+ Recent posts