In this tutorial, you will learn how to make a Pokemon Go Trainer Level Speed Calculator in JavaScript. Basically, Pokemon Go level calculator tool will help you determine when can you reach Level 40 in Pokémon Go.
The main source code of Pokemon Go Level Calculator is given below. It was a bit difficult to add the complete source code here. So, I have provided a download button at the end of this tutorial from where you can download the full source code of Pokemon Go Trainer Level Speed Calculator.
Pokemon Go Trainer Level Speed Calculator
index.html
HTML
x
33
33
1
2
<html lang="en">
3
<head>
4
<meta charset="utf-8">
5
<meta name="viewport" content="width=device-width, initial-scale=1">
6
<title>Pokemon Go Trainer Level Calculator</title>
7
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
8
<meta property="og:image" content="https://trainerlevelspeed.de/thumb.png" />
9
</head>
10
<body>
11
12
<div id="root"></div>
13
<!--
14
This HTML file is a template.
15
If you open it directly in the browser, you will see an empty page.
16
17
You can add webfonts, meta tags, or analytics to this file.
18
The build step will place the bundled scripts into the <body> tag.
19
20
To begin the development, run `npm start` in this folder.
21
To create a production bundle, use `npm run build`.
22
-->
23
<script>
24
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
25
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
26
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
27
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
28
29
ga('create', 'UA-83285379-1', 'auto');
30
ga('send', 'pageview');
31
</script>
32
</body>
33
</html>
/src/index.js
JavaScript
1
22
22
1
import React from 'react';
2
import ReactDOM from 'react-dom';
3
import { Provider } from 'react-redux';
4
5
import 'bootstrap/dist/css/bootstrap.css';
6
7
window.$ = window.jQuery=require('jquery');
8
window.Tether=require('tether');
9
require('bootstrap/dist/js/bootstrap');
10
11
import configureStore from './store/configureStore';
12
13
import App from './containers/app/App';
14
15
const store = configureStore();
16
17
ReactDOM.render(
18
<Provider store={store}>
19
<App/>
20
</Provider>,
21
document.getElementById('root')
22
);
/src/components/calc/Calc.js
JavaScript
1
119
119
1
import React, { Component } from 'react'
2
import './calc.css';
3
4
import Input from "./Input";
5
import Result from "./Result";
6
import Visualization from './Visualization';
7
import Github from '../Github';
8
9
import levelXp, {totalXp} from './levels';
10
var MAX_LEVEL = levelXp.length;
11
12
function calcStats(xp) {
13
if (xp === '?') {
14
return {
15
level : '?',
16
xpLeft : '?????',
17
xpGoal : 200000
18
};
19
}
20
var level = 0;
21
var xpLeft = xp;
22
while (level < MAX_LEVEL && xpLeft - levelXp[level] >= 0) {
23
xpLeft -= levelXp[level];
24
level++;
25
}
26
if (level === 40) {
27
xpLeft = levelXp[levelXp.length-1]
28
}
29
return {
30
level : level,
31
xpLeft : xpLeft,
32
xpGoal : levelXp[level] || levelXp[levelXp.length-1]
33
};
34
}
35
36
export default class Header extends Component {
37
38
render() {
39
40
var stats = calcStats(this.props.xp);
41
42
var perc = stats.xpLeft / stats.xpGoal;
43
var progressStyle = {
44
width : (100*perc) + '%'
45
};
46
var totalPerc = Math.min(1, this.props.xp / totalXp[this.props.goal]);
47
48
var validData = totalPerc >= 0 && this.props.date !== null
49
&& this.props.date < (new Date());
50
51
var resultComponents = (<div className="rollDown">
52
<div className="line"></div>
53
ENTER XP AND START DATE<br />
54
TO SEE YOUR RESULTS
55
</div>);
56
if (validData) {
57
resultComponents = (<div className="rollDown opened">
58
<div className="line"></div>
59
<Result startDate={this.props.date} xp={this.props.xp} goal={this.props.goal} />
60
<Visualization perc={totalPerc} goal={this.props.goal} />
61
</div>);
62
}
63
64
var disabledStyle = this.props.xp === '?' ? ' disabled' : '';
65
66
// this is really getting messed up now...
67
68
return (
69
<div className="calc">
70
<h1>POKEMON GO<br/>LEVEL SPEED CALCULATOR</h1>
71
<div className="xp">
72
<div className="fakeInput" onClick={()=>{this.input1.focus();}}>
73
<Input value={this.props.xp} className="inputXp" ref={(c) => {this.input1 = c}}
74
onChange={(evt) => this.props.setXp(evt.target.value)}
75
/> XP
76
</div>
77
</div>
78
<div className={"level"+disabledStyle}>
79
Level {stats.level}
80
</div>
81
<div className={"progress"+disabledStyle}>
82
<div className="progressBg"></div>
83
<div className="progressFront" style={progressStyle}><div className="progressHandle"></div></div>
84
<div className="progressXp">{stats.xpLeft} / {stats.xpGoal} XP</div>
85
</div>
86
<div className="bottom">
87
<div className="startDate">
88
START DATE:<br />
89
<div className="fakeInput" onClick={()=>{this.input2.focus();}}>
90
<Input value={this.props.dateStr} className="inputDate" ref={(c) => {this.input2 = c}}
91
onChange={(evt) => this.props.setStartDate(evt.target.value)}
92
/>
93
</div>
94
</div>
95
<div className="startDate levelchoice">
96
LEVEL:<br />
97
<div className="btn-group" data-toggle="buttons">
98
<label className={"btn btn-secondary"+(this.props.goal === 30 ? ' active':'')} onClick={()=>this.props.setGoal(30)}>
99
<input type="radio" name="options" id="option1" autoComplete="off" defaultChecked={this.props.goal === 30 ? 'checked':''} /> 30
100
</label>
101
<label className={"btn btn-secondary"+(this.props.goal === 40 ? ' active':'')} onClick={()=>this.props.setGoal(40)}>
102
<input type="radio" name="options" id="option2" autoComplete="off" defaultChecked={this.props.goal === 40 ? 'checked':''} /> 40
103
</label>
104
</div>
105
</div>
106
</div>
107
{resultComponents}
108
<Github/>
109
</div>
110
);
111
}
112
}
113
/*
114
<ContentEditable
115
tagName="span"
116
html="as"
117
disabled={false}
118
onChange={(evt) => this.props.setXp(evt.target.value)}
119
/> XP*/
/src/components/calc/calc.css
CSS
1
256
256
1
body {
2
background: #eee;
3
margin: 0;
4
cursor: default;
5
white-space: nowrap;
6
}
7
h1 {
8
font-size: 25px;
9
font-weight: bold;
10
margin: 0 0 30px 0;
11
line-height: 35px;
12
}
13
.calc {
14
padding: 20px 60px 15px;
15
max-width: calc(80% - 120px);
16
margin: 0 auto;
17
width: 600px;
18
background: #fff;
19
background-size: 80%;
20
background-repeat: no-repeat;
21
background-position: center;
22
color: #44696c;
23
text-align: center;
24
font-family: 'Lato', sans-serif;
25
}
26
@media (max-width:700px) {
27
.calc {
28
max-width: 100%;
29
width: 100%;
30
}
31
.bigOnly {
32
display: none;
33
}
34
}
35
*:focus, .active {
36
outline: none !important;
37
}
38
input.variableSize {
39
padding: 0;
40
border: none;
41
}
42
.inputXp {
43
color: #44696c;
44
font-size: 25px;
45
font-family: 'Lato', sans-serif;
46
}
47
.xp {
48
font-size: 25px;
49
}
50
.level, .timeNeeded {
51
line-height: 45px;
52
font-size: 47px;
53
white-space: nowrap;
54
}
55
.level {
56
margin-top: 30px;
57
}
58
.timeNeeded {
59
padding: 10px 0;
60
font-size: 43px;
61
}
62
.progress, .xpProg {
63
margin: 20px auto;
64
width: 100%;
65
position: relative;
66
}
67
.progressBg, .progressFront {
68
background: #d7dfd6;
69
height: 9px;
70
width: 100%;
71
border-radius: 7px;
72
position: absolute;
73
left: 0;
74
top: 0;
75
transition: width 0.3s;
76
}
77
.progressFront {
78
background: #ee5b5b;
79
width: 50%;
80
}
81
.progressHandle{
82
position: absolute;
83
right: -4px;
84
top: -4px;
85
height: 17px;
86
width: 17px;
87
background: #ee5b5b;
88
border-radius: 50%;
89
}
90
.progressXp {
91
padding-top: 17px;
92
font-size: 26px;
93
color: #87a19f;
94
}
95
.bottom {
96
padding-top: 10px;
97
padding-bottom: 15px;
98
}
99
.startDate {
100
padding-top: 35px;
101
font-size: 19px;
102
font-weight: bold;
103
letter-spacing: 2px;
104
}
105
.inputDate {
106
font-size: 19px;
107
font-weight: bold;
108
letter-spacing: 2px;
109
color: #44696c;
110
}
111
.testSpan {
112
position: absolute;
113
left: -1000px;
114
top: -100000px;
115
/*position: relative;
116
left: -1px;
117
top: -30px;
118
border: 1px solid red;*/
119
}
120
121
.line {
122
margin: 15px auto 30px;
123
width: 100%;
124
border-top: 1px solid #bbb;
125
}
126
.result {
127
padding-bottom: 30px;
128
letter-spacing: 2px;
129
}
130
.rollDown {
131
font-size: 19px;
132
height: 120px;
133
transition: height 0.5s;
134
overflow: hidden;
135
margin: 0 -50px;
136
padding: 0 50px;
137
}
138
.rollDown.opened {
139
height: 370px; /* 370px */
140
}
141
142
.line2 {
143
margin: 15px auto 15px;
144
}
145
.github {
146
opacity: 0.7;
147
font-size: 80%;
148
}
149
150
/*********** visualization *********/
151
.xpProg {
152
margin-top: 35px;
153
}
154
.xpProgBg {
155
background: #d7dfd6;
156
height: 9px;
157
width: 100%;
158
border-radius: 7px;
159
position: absolute;
160
left: 0;
161
top: 0;
162
}
163
.xpLabel.minor {
164
opacity: 0.4;
165
}
166
.xpLabel {
167
position: absolute;
168
left: 0%;
169
margin-left:-8px;
170
top: -4px;
171
height: 17px;
172
width: 17px;
173
background: #d7dfd6;
174
border-radius: 50%;
175
}
176
.xpLabel .text {
177
position: relative;
178
top: 18px;
179
font-size: 13px;
180
font-weight: bold;
181
}
182
.xpLabel.you {
183
background: #ee5b5b;
184
transition: left 0.3s;
185
}
186
.youBox {
187
position: absolute;
188
top: -53px;
189
margin-left: -29px;
190
background: #ee5b5b;
191
transition: opacity 1s;
192
transition: left 0.3s;
193
}
194
.youBox:after {
195
top: 100%;
196
left: 50%;
197
border: solid transparent;
198
content: " ";
199
height: 0;
200
width: 0;
201
position: absolute;
202
pointer-events: none;
203
border-color: rgba(238, 91, 91, 0);
204
border-top-color: #ee5b5b;
205
border-width: 10px;
206
margin-left: -10px;
207
}
208
.innerBox {
209
font-weight: bold;
210
padding: 5px 10px;
211
color: #fff;
212
}
213
214
.fakeInput {
215
padding: 3px 10px;
216
display: inline-block;
217
border: 1px solid #ddd;
218
width: 200px;
219
cursor: text;
220
user-select: none;
221
}
222
223
.level, .progress {
224
transition: filter 0.3s, opacity 0.3s;
225
}
226
227
.disabled {
228
opacity: 0.5;
229
filter: blur(4px);
230
filter: blur(4px);
231
filter: blur(4px);
232
filter: blur(4px);
233
}
234
235
.level30 {
236
margin: 10px 0 0 0;
237
238
}
239
240
/******* custom bootstrap **********/
241
.btn-group .btn {
242
border-radius: 0;
243
border-color: #ddd;
244
color: #44696c;
245
font-size: 160%;
246
}
247
.btn.focus, .btn.active, .btn:active { /* remove bootstrap style */
248
border-color: #ddd !important;
249
color: #44696c !important;
250
background: #ddd !important;
251
}
252
.levelchoice {
253
padding-top: 25px;
254
}
255
.btn-group {
256
}
Screenshot

Download Pokemon Go Level Calculator
You can download the complete source code of Pokemon Go Level Calculator using the link given below.