WEB/REACT

[REACT] 이미지 좌우 스와이프 퀴즈 페이지 만들기

자바칩 프라푸치노 2021. 6. 27. 21:09

출처: 스파르타 코딩 클럽

<결과 화면>

 

꼬미 사진을 스와이프해서 o나 x에 갖다 놓으면 다음 문제로 넘어가는 코드

 

 

 


 

App.js

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import logo from './logo.svg';
import './App.css';
import React from "react";
 
import Start from "./Start";
import Quiz from "./Quiz";
import Score from "./Score";
 
class App extends React.Component{
  constructor(props){
    super(props);
// state에 필요한 데이터를 넣어줘요!
    this.state = {
      name"꼬미와 친구들",
      page: "quiz",
      scoreMsg: "이 정도면 아주 친한 친구 사이! 앞으로도 더 친하게 지내요! :)",
      list: [
        { question: "꼬미는 2살이다.", answer: "X" },
        { question: "꼬미는 남자다.", answer: "O" },
        { question: "꼬미는 딸기를 좋아한다.", answer: "O" },
        { question: "꼬미는 눈물이 많다.", answer: "O" },
        { question: "꼬미는 혼자 있을 때 잔다.", answer: "O" },
        { question: "꼬미는 수박을 좋아한다.", answer: "O" },
        { question: "꼬미는 엄마를 제일 좋아한다.", answer: "O" },
        { question: "꼬미는 3KG이다.", answer: "X" },
        { question: "꼬미는 귀엽다.", answer: "O" },
        { question: "꼬미는 풀을 좋아한다.", answer: "O" },
        { question: "꼬미는 청소기를 무서워한다.", answer: "O" },
      ],
      ranking: [
        { rank: 1name"이현주", message: "꼬미♥" },
        { rank: 1name"이현주", message: "꼬미♥" },
        { rank: 1name"이현주", message: "꼬미♥" },
        { rank: 1name"이현주", message: "꼬미♥" },
        { rank: 1name"이현주", message: "꼬미♥" },
        { rank: 1name"이현주", message: "꼬미♥" },
        { rank: 1name"이현주", message: "꼬미♥" },
      ],
    };
  }
 
  render () {
    return (
      <div className="App">
        {/* 조건부 랜더링을 합니다 / state의 page를 바꿔가면서 확인해봐요! */}
        {this.state.page === "quiz" && (<Quiz list={this.state.list} />)}
        {this.state.page === "start" && (<Start name={this.state.name/>)}
        {this.state.page === "score" && (<Score name={this.state.name} scoreMsg={this.state.scoreMsg}/>)}
      </div>
    );
  }
}
 
export default App;
cs

 

Score.js

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import React from "react";
import styled from "styled-components";
 
const Score = (props) => {
  // 컬러셋 참고: https://www.shutterstock.com/ko/blog/pastel-color-palettes-rococo-trend/
  return (
    <ScoreContainer>
      
        <Text>
          <span>{props.name}</span>
          퀴즈에 <br />
          대한 내 점수는?
        </Text>
        <MyScore>
          <span>100</span>
          <p>{props.scoreMsg}</p>
        </MyScore>
 
        {/* <Button>다시 하기</Button> */}
        <Button outlined>랭킹보기</Button>
      
    </ScoreContainer>
  );
};
 
const ScoreContainer = styled.div`
display:flex;
width: 100vw;
height: 100vh;
overflow: hidden;
padding: 16px;
box-sizing: border-box;
flex-direction: column;
justify-content: center;
align-items: center;
`;
 
const Text = styled.h1`
font-size: 1.5em;
margin: 0px;
line-height: 1.4;
& span {
    background-color: #fef5d4;
    padding: 5px 10px;
    border-radius: 30px;
}`;
 
const MyScore = styled.div`
  & span {
    border-radius: 30px;
    padding: 5px 10px;
    background-color: #fef5d4;
  }
  font-weight: 600;
  font-size: 2em;
  margin: 24px;
 
  & > p{
      margin: 24px 0px;
      font-size: 16px;
      font-weight: 400;
  }
`;
const Button = styled.button`
  padding: 8px 24px;
  background-color: ${(props) => (props.outlined ? "#ffffff" : "#dadafc")};
  border-radius: 30px;
  margin: 8px;
  border: 1px solid #dadafc;
  width: 80vw;
`;
 
export default Score;
cs

 

Quiz.js

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import React from "react";
import styled from "styled-components";
import img from "./scc_img.jpg";
import TinderCard from "react-tinder-card";
 
//
const Quiz = (props) => {
  console.log(props);
  // state로 관리하자!
  const [num, setNum] = React.useState(0);
 
  const onSwipe = (direction) => {
    console.log("You swiped: " + direction);
    setNum(num + 1);
  };
 
  if (num > 10) {
    return <div>퀴즈 끝!</div>;
  }
 
  return (
    <QuizContainer>
      <p>
        <span>{num + 1}번 문제</span>
      </p>
      {props.list.map((l, idx) => {
        if (num === idx) {
            // props의 list에 있는 question의 값들을 순서대로 불러온다.
          return <Question key={idx}>{l.question}</Question>;
        }
      })}
 
      <AnswerZone>
        <Answer>{"O "}</Answer>
        <Answer>{" X"}</Answer>
      </AnswerZone>
 
      {props.list.map((l, idx) => {
        if (idx === num) {
          return (
            <DragItem key={idx}>
              <TinderCard
                onSwipe={onSwipe}
                onCardLeftScreen={onSwipe}
                onCardRightScreen={onSwipe}
                preventSwipe={["up""down"]}
              >
                <img src={img} />
              </TinderCard>
            </DragItem>
          );
        }
      })}
    </QuizContainer>
  );
};
 
const QuizContainer = styled.div`
  & > p > span {
    padding: 8px 16px;
    background-color: #fef5d4;
    // border-bottom: 3px solid #ffd6aa;
    border-radius: 30px;
  }
`;
 
const Question = styled.h1`
  font-size: 1.5em;
`;
 
const AnswerZone = styled.div`
  width: 100%;
  display: flex;
  flex-direction: row;
  min-height: 70vh;
`;
 
const Answer = styled.div`
  width: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 100px;
  font-weight: 600;
  color: #dadafc77;
`;
 
const DragItem = styled.div`
  display: flex;
  align-items: center;
  justify-content: center;
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
 
  & > div {
    border-radius: 500px;
    background-color: #ffd6aa;
  }
  & img {
    max-width: 150px;
  }
`;
export default Quiz;
cs
728x90