본문 바로가기
토이 프로젝트

나에게 맞는 운동은? (TraingFit TEST)

by 보보트레인 2023. 8. 27.

<목표>

본인에게 맞는 운동을 유형검사를 통해 쉽고 빠르게 찾아주는 간단한 서비스

 

<서비스 페이지 링크>

https://bobotrainfit.netlify.com

 

<참고 소스코드> 

https://github.com/bobotrain/TrainingFit-_Test.git

 

<사용 기술스텍>

 

<서비스 설명>

· Javascript Export함수를 응용 →  유형별 DATA를 종합

· 데이터 결과를 코드화 하여 parameter로 전달 → 해당 파라미터에 해당하는 결과지 출력

· 외부 공유기능 제공

· 어울리는 추천 성격 키워드 제공

· 배포는 netlify를 통해 자동화 배포.

 

<코드분석>

css / js / html 로  분리 

 

1. html / css : 소스코드 참고 - 생략

2. js 분석

1) data.js - export함수로 객체배열 형성 - 결과를 const변수에 담아 활용

export const questions = [ //export / 자바스크립트 객체배열 내보내기
  {
    number: '01',
    question: '너는 무슨 목적을 가지고 운동을 시작하니?',
    choices: [
      { text: '남들에게 멋있어 보이고 싶어<br>(당장 빠르게 성과를 내고싶어!)', value: 'a' },
      { text: '체력을 기르고 싶어!<br>내 건강이 우선이야...', value: 'b' }
    ]
  },
  {
    number: '02',
    question: '얼마만큼 투자할 수 있니?<br>나의 지갑 사정은?',
    choices: [
      { text: '한 푼도 쓰고싶지 않아~', value: 'a' },
      { text: '효과만 좋다면야...<br>얼마든지 쓸 수 있지!', value: 'b' }
    ]
  },
  {
    number: '03',
    question: '너가 운동하고 싶은<br>분위기는?',
    choices: [
      { text: '북적북적 씨끌씨끌 으쌰으쌰! ', value: 'a' },
      { text: '조용히 고독하게. 한산한 곳에서 나에게만 집중!', value: 'b' }
    ]
  },
  {
    number: '04',
    question: '나의 의지 수준은?',
    choices: [
      { text: '목표한 바는 혼자서도 끝까지 경주하는 독한 성격!', value: 'a' },
      { text: '남이 나를 머리채 잡고 끌어줬으면 좋겠어 ㅠㅠㅠ', value: 'b' }
    ]
  },
  {
    number: '05',
    question: '내가 생각하는 운동이란?',
    choices: [
      { text: '땀을 시원하게 쏟아내는 고강도의 운동<br>(암 그래야 운동이지!)', value: 'a' },
      { text: '천천히 하지만 내실있게 꾸준히!<br>(부상조심 휴우~) ', value: 'b' }
    ]
  },
]
export const results = [
  {
    title: '웨이트 트레이닝<br>고독한 헬서',
    character: '/images/result_character1.png',
    results: [
      '혼자서 멘탈 케어가 가능해요!<br>끈기 있게 혼자서 운동을 잘 다녀요!',
      '몸에 대한 욕심이 많아요.<br>행복한 헬스장 출근이에요!',
      '자유로운 환경에서 더 잘해요!<br>하지만 누구보다 스스로 시간 관리가 철저해요:)',
      '효율적이고 낭비가 적어요!.<br>야무지다는 소리 많이듣죠 (뿌듯)'
    ],
    minds: ['고통에 익숙한', '끈기있는'],
    lectureImg: '/images/result_lecture1.png',
  },
  {
    title: '크로스핏<br>완벽한 인싸!',
    character: '/images/result_character2.png',
    results: [
      '나는야 센스쟁이!<br>언제나 토닥토닥 으샤으샤 응원하며 다니는 파워 인싸!',
      '강해지고 싶고 건강증진이 최고에요!',
      '진행력 갑! 추진력 갑!<br>빠른 속도로 강도높게!',
      '함께 운동하는것이 좋아요,<br>함께의 가치를 즐겨요!'
    ],
    minds: ['함께하는', '고양된'],
    lectureImg: '/images/result_lecture2.png',
  },
  {
    title: '필라테스&요가<br>정적인 수양',
    character: '/images/result_character3.png',
    results: [
      '스스로의 관조를 즐겨요.<br>조용한게 좋아요',
      '섬세함이 장점으로<br>신체 하나하나의 통제력을 높히고 싶어요',
      '선을 이쁘게 만들고 싶어요<br>거북목 싫어요 ㅠㅠ',
      '하루가 너무 지치지만,<br>그래도 지친몸을 다스리는 시간이 필요해요!'
    ],
    minds: ['섬세한', '정적인'],
    lectureImg: '/images/result_lecture3.png',
  },
  {
    title: '클라이밍<br>야심찬 정복가',
    character: '/images/result_character4.png',
    results: [
      '전략적으로 계획을 세우는 걸 좋아해요! 지독한 나!',
      '목표가 분명하면 몰입도가 올라가요!',
      '성취감이 정말 중요해요<br>성공했을 때의 도파민에 취해있어요',
      '일할 땐 일하고! 놀 땐 놀고!<br>뭐든 확실한 게 좋아요.'
    ],
    minds: ['야망러', '목표가 분명한'],
    lectureImg: '/images/result_lecture4.png',
  }
]
export const sports = {
  aaaaa : 1, 
  aaaab : 0,
  aaaba : 0,
  aaabb : 3,
  aabaa : 0,
  aabab : 0,
  aabba : 1,
  aabbb : 0,
  abaaa : 1,
  abaab : 3,
  ababa : 1,
  ababb : 1,
  abbaa : 3,
  abbab : 2,
  abbba : 3,
  abbbb : 2,
  baaaa : 0,
  baaab : 1,
  baaba : 0,
  baabb : 0,
  babaa : 0,
  babab : 2,
  babba : 0,
  babbb : 2,
  bbaaa : 1,
  bbaab : 1,
  bbaba : 3,
  bbabb : 3,
  bbbaa : 2,
  bbbab : 2,
  bbbba : 2,
  bbbbb : 2

}

2) question.js

- EventListener를 이용하여 질문 페이지를 통제

- data.js객체배열에 담아둔 결과를 뽑아와 import → querySelector를 통해 원하는 위치에 뿌려줌

- 특정 초이스를 선택 시 , 해당 값을 변수에 담아 저장 → 문자열로 형성하여 결과문자열을 파라미터로 전송

- 문제 번호에 따라  progressValue의 width값을 변경 → 테스트의 진행상황을 그래프로 표현

 

import { questions, sports } from './data.js'

// 질문 화면의 각 요소를 찾아요!
const progressValueEl = document.querySelector('.progress .value')
const numberEl = document.querySelector('.number')
const questionEl = document.querySelector('.question')
const choice1El = document.querySelector('.choice1')
const choice2El = document.querySelector('.choice2')

let currentNumber = 0 // 현재 질문 번호
let sport = '' // 선택지 결과

// 화면에 질문을 랜더링하는 함수에요!
function renderQuestion() {
  const question = questions[currentNumber]
  questionEl.innerHTML = question.question
  numberEl.innerHTML = question.number
  choice1El.innerHTML = question.choices[0].text
  choice2El.innerHTML = question.choices[1].text
  progressValueEl.style.width = (currentNumber + 1) * 20 + '%'
}
// 다음 질문으로 넘어가는 함수에요!
function nextQuestion(choiceNumber) {
  const question = questions[currentNumber]

  // 더 이상 질문이 없으면, 결과 페이지를 보여줘요!
  if (currentNumber === questions.length - 1) {
    //sport = sport + 'a'
    sport = sport + question.choices[choiceNumber].value
    showResultPage()
    return
  }
  
  sport = sport + question.choices[choiceNumber].value
  currentNumber = currentNumber + 1
  renderQuestion()
}
// 결과 페이지로 이동!
function showResultPage() {
  location.href = 'results.html?sport=' + sport
}

// '답변1' 혹은 '답변2'를 클릭했을 때 동작하는 코드에요!
choice1El.addEventListener('click', function () {
  nextQuestion(0)
})
choice2El.addEventListener('click', function () {
  nextQuestion(1)
})

// 첫 번째 질문을 렌더링해요!
renderQuestion()

2) result.js

- data.js객체배열에 담아둔 결과를 뽑아와 import 

- 파라미터의 값을 가져와 Key값으로 이용

  → data.js에서 가져온 객체 中 일치하는 결과 값만 따로 분류 

 

import { results, sports } from './data.js'

// 주소 쿼리스트링에서 sport 값을 가져오기!
const sport = new URLSearchParams(location.search).get('sport')
const result = results[sports[sport]]

// 결과를 출력할 각 요소를 찾아요!
const titleEl = document.querySelector('.page-title')
const characterEl = document.querySelector('.character')
const boxEls = document.querySelectorAll('.box')
const mindEls = document.querySelectorAll('.mind')
const lectureEl = document.querySelector('.lecture')
const lectureImgEl = document.querySelector('.lecture img')

// 각 요소에 내용을 채워넣어요!
titleEl.innerHTML = result.title
characterEl.src = result.character
boxEls.forEach(function (boxEl, index) {
  boxEl.innerHTML = result.results[index]
})
mindEls.forEach(function (mindEl, index) {
  mindEl.innerHTML = result.minds[index]
})
lectureImgEl.src = result.lectureImg

 

 

<참고 사진>

 

시작페이지
질문페이지 1
결과페이지 상단
결과페이지 하단.

반응형