"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); } }