-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.js
More file actions
147 lines (126 loc) · 3.63 KB
/
utils.js
File metadata and controls
147 lines (126 loc) · 3.63 KB
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
const colors = ['red', 'blue', 'green', 'gray', 'pink', 'purple', 'orange', 'AliceBlue', 'Azure'];
const MAX_TOP_EXCELERATION = 75;
const SIZE_FACTOR = 15;
const GRAVITY_FACTOR = 2;
const ROTATION_FACTOR = 0.1;
const ROTATION_SPEED_FACTOR = 0.01;
/**
* Piece constructor
* @param x
* @param y
* @param canvas
* @param ctx
* @param right
* @param left
* @constructor
*/
export function Piece ({x, y, canvas, ctx, right, left}) {
this.x = x;
this.y = y;
this.size = (Math.random() * 0.5 + 0.75) * SIZE_FACTOR;
this.gravity = (Math.random() * 0.5 + 0.75) * GRAVITY_FACTOR;
this.ratation = (Math.PI * 2) * Math.random() * ROTATION_FACTOR;
this.rotationSpeed = (Math.PI * 2) * Math.random() * ROTATION_SPEED_FACTOR;
this.color = randomColor();
this.canvas = canvas;
this.ctx = ctx;
this.right = right;
this.left = left;
this._isPeak = false;
this._upPoints = 0;
this._upPointsMAx = MAX_TOP_EXCELERATION;
this._easeOutQuadNormalize = easeOutCircNormalize(this._upPointsMAx, 0);
}
/**
* Update piece positions
* @param isInfinite
*/
Piece.prototype.update = function(isInfinite = false) {
if(this.y > this.canvas.height) {
if (isInfinite) {
this.y = - (this.size);
this.x = Math.random() * this.canvas.width;
this.color = randomColor();
}
return;
}
switch (true) {
case (this.right || this.left) && !this._isPeak:
const _easeOutQuadNormalize = this._easeOutQuadNormalize(this._upPoints);
this.y -= this.gravity * _easeOutQuadNormalize * 3;
this._upPoints++;
break
}
// stop going upward
if (this._upPoints > this._upPointsMAx) {
this._isPeak = true;
}
// add momentum to the sides
if (this.right && !this._isPeak) this.x += this.gravity * 0.8;
if (this.left && !this._isPeak) this.x -= this.gravity * 0.8;
if (this.left && this._isPeak) this.x -= this.gravity * 0.3;
if (this.right && this._isPeak) this.x += this.gravity * 0.3;
// add gravity to the piece
this.y += this.gravity;
this.ratation += this.rotationSpeed;
};
/**
* Draw the piece on the canvas
* @param isInfinite
*/
Piece.prototype.draw = function (isInfinite) {
this.update(isInfinite);
this.ctx.save();
this.ctx.fillStyle = this.color;
this.ctx.translate(this.x + this.size / 2, this.y + this.size / 2)
this.ctx.rotate(this.ratation);
this.ctx.fillRect(-this.size / 2, this.size / 2, this.size, this.size)
this.ctx.restore();
}
/**
* Get random color
* @returns {string}
*/
export function randomColor(num = Math.random()) {
return colors[Math.floor( num * colors.length)]
}
/**
*
* @param min
* @param max
* @returns {function(number): number}
*/
function easeOutQuadNormalize(min, max) {
return (value) => {
return easeOutQuad((value - min) / (max - min))
}
}
/**
* easeOut for piece going up
* @param min
* @param max
* @returns {function(number): number}
*/
function easeOutCircNormalize(min, max) {
return (value) => {
return easeOutCirc((value - min) / (max - min))
}
}
function easeOutCirc(x){
return Math.sqrt(1 - Math.pow(x - 1, 2));
}
function easeOutQuad(x) {
return 1 - (1 - x) * (1 - x);
}
function norm(value, min, max) {
return (value - min) / (max - min);
}
/**
* Get random number
* @param min
* @param max
* @returns {*}
*/
export function randomFromRange(min, max) {
return Math.random() * (max - min + 1) + min
}