You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

179 lines
3.8 KiB

"use strict"
class Loader{
constructor(type, title, loadedCallback){
this.type = type;
this.title = title;
this.loadedCallback = loadedCallback;
this.spinnerAngle = 0;
$("#menu, #menuOpener").hide();
}
static Bar(){
return 0;
}
static Circle(){
return 1;
}
updateProgress(progress, infoText){
this.progress = progress > 1 ? 1 : progress;
this.radianAngle = progress * TWO_PI;
this.strokeWidth = progress * 8 + 2;
this.infoText = infoText;
}
update(){
this.display(this.getColors());
this.spinnerAngle += PI / 16;
this.spinnerAngle %= TWO_PI;
if (this.progress === 1 && this.loadedCallback){
this.loadedCallback();
}
}
display(c){
background(c.background);
switch (this.type){
case Loader.Bar():
this.bar(c);
break;
case Loader.Circle():
this.circle(c);
break;
}
}
bar(c){
let w = width * 0.6,
h = 30;
let x = (width - w) / 2,
y = (height - h) / 2;
this.displayBar(x, y, w, h, c);
this.displaySpinner(width / 2, height * 3 / 4, 30, c.spinner);
fill(c.text.fill);
stroke(c.text.stroke);
strokeWeight(5);
textAlign(CENTER, CENTER);
textSize(height / 32);
text(str(this.title), width / 2, height / 8);
strokeWeight(2);
textSize(h / 2);
text(str(this.infoText), width / 2, y - h * 1.5);
strokeWeight(5);
stroke(c.progress);
textSize(height / 16);
text(int(this.progress * 100) + "%", width / 2, height * 5 / 8);
}
circle(c){
let size = min(width, height) / 2;
size = size < 100 ? 100 : size;
let posX = width / 2;
let posY = height / 2;
this.displayCircle(posX, posY, size, c);
this.displaySpinner(posX, height * 7 / 8, 30, c.spinner);
fill(c.text.fill);
stroke(c.text.stroke);
strokeWeight(5);
textSize(height / 32);
text(this.title, posX, height / 8);
strokeWeight(2);
textSize(15);
text(str(this.infoText), width / 2, posY + size / 2 + 30);
stroke(c.progress);
strokeWeight(5);
textSize(height / 16);
text(str(int(this.progress * 100)) + "%", posX, posY);
}
displayBar(x, y, w, h, c){
noFill();
stroke(0);
strokeWeight(5);
rect(x, y, w, h, h / 4);
w -= (1 - this.progress) * w;
noStroke();
fill(c.progress);
rect(x + 1, y + 1, w - 2 < 0 ? w : w - 2, h - 2, h / 4);
}
displayCircle(posX, posY, size, c){
noFill();
for (let i = 0; i < 3; i++){
stroke(i == 1 ? c.progress: 0);
strokeWeight(i == 1 ? 5 : 2);
if (this.radianAngle < TWO_PI && i == 1){
arc(posX, posY, size, size, -HALF_PI, this.radianAngle - HALF_PI);
} else {
ellipse(posX, posY, size + (i - 1) * 10);
}
}
}
displaySpinner(x, y, r, c){
let c2 = c;
colorMode(HSB);
let c1 = color(hue(c2), saturation(c2), brightness(c2) / 5);
colorMode(RGB);
let length = PI + HALF_PI;
for (let i = this.spinnerAngle; i < this.spinnerAngle + length; i += PI / 16){
strokeWeight((i - this.spinnerAngle) / length * 10);
//stroke(lerpColor(c1, c2, (i - this.spinnerAngle) / length));
stroke(c2);
let x1 = sin(i) * r + x,
y1 = cos(i) * r + y,
x2 = sin(i + PI / 16) * r + x,
y2 = cos(i + PI / 16) * r + y;
line(x1, y1, x2, y2);
}
}
getColors(){
return {
background: color(colors.loader.background),
progress: color(colors.loader.finished),
spinner: color(colors.loader.spinner),
text: {
fill: color(colors.loader.text.fill),
stroke: color(colors.loader.text.stroke)
},
};
}
destroy(){
$("#loader").html("");
$("#menu, #menuOpener").show();
loader = null;
}
}
function drawGradient(x, y, w, h, c1, c2, r){
strokeWeight(1);
for (let i = x; i <= x + w; i++){
let inter = map(i, x, x + w, 0, 1);
let c = lerpColor(c1, c2, inter);
let b = r - pow(r * r - (i - x - r) * (i - x - r), 0.5);
b = (i - x > r && i < x + w - r) ? 0 : b;
b = i > x + w - r ? r - pow(r * r - (i - x - w + r) * (i - x - w + r), 0.5) : b;
stroke(c);
line(i, y + b + 1, i, y + h - b - 2);
}
}