Finished the remaining screens

I think it's good to ship
This commit is contained in:
Leon Mika 2025-06-23 13:50:50 +02:00
parent aaf91f33e2
commit 0b20017408
10 changed files with 146 additions and 39 deletions

View file

@ -1,4 +1,5 @@
const GAME_STATE_KEY = "gameState";
const MAX_QUESTIONS = 10;
class GameState {
getQuestionChoice(qId) {
@ -19,6 +20,10 @@ class GameState {
localStorage.removeItem(GAME_STATE_KEY);
}
getMaxQuestions() {
return MAX_QUESTIONS;
}
getSummary() {
let savedItem = this._readGameState();
let summary = { totalAnswered: 0, totalRight: 0 };
@ -30,6 +35,22 @@ class GameState {
}
}
if (summary.totalAnswered != MAX_QUESTIONS) {
summary.rank = "Incompletionist";
} else if (summary.totalRight <= 2) {
summary.rank = "Developer";
} else if (summary.totalRight <= 5) {
summary.rank = "Senior Developer";
} else if (summary.totalRight <= 7) {
summary.rank = "Standard Enthusiast";
} else if (summary.totalRight <= 9) {
summary.rank = "Standard Maker";
} else if (summary.totalRight == 10) {
summary.rank = "ISO President";
} else {
summary.rank = "Beta Tester";
}
return summary;
}

View file

@ -2,7 +2,7 @@ import { Controller } from "https://unpkg.com/@hotwired/stimulus/dist/stimulus.j
import { gameState } from "./gamestate.js";
export default class extends Controller {
static targets = ["radio", "answerDetails", "submit"];
static targets = ["radio", "submitButton", "answerDetails", "submit", "result"];
static values = {
qid: String,
@ -12,7 +12,7 @@ export default class extends Controller {
connect() {
let hasAnswer = gameState.getQuestionChoice(this.qidValue);
if (hasAnswer) {
this._revealAnswer();
this._revealAnswer(hasAnswer.isRight);
let e = this.radioTargets.find((e) => e.value == hasAnswer.cId);
if (e) {
@ -35,24 +35,32 @@ export default class extends Controller {
return;
}
gameState.setQuestionChoice(this.qidValue, e.value, e.value === this.answerValue);
let wasRight = e.value === this.answerValue;
gameState.setQuestionChoice(this.qidValue, e.value, wasRight);
this.element.classList.add("reveal");
window.setTimeout(() => { this._revealAnswer(); });
window.setTimeout(() => { this._revealAnswer(wasRight); });
}
_revealAnswer() {
_revealAnswer(wasRight) {
this.element.classList.add("reveal");
this.radioTargets.forEach(e => {
e.disabled = true;
if (e.value === this.answerValue) {
e.classList.add("answer");
e.classList.add("answer");
} else {
e.classList.add("wrong");
}
});
if (wasRight) {
this.resultTarget.innerText = "Correct";
} else {
this.resultTarget.innerText = "Sorry, that's incorrect";
}
this.submitButtonTarget.classList.add("hidden");
this.answerDetailsTarget.classList.remove("hidden");
}
};

View file

@ -2,7 +2,6 @@ import { Controller } from "https://unpkg.com/@hotwired/stimulus/dist/stimulus.j
import { gameState } from "./gamestate.js";
const ANIMATION_DURATION = 1500.0;
const MAX_QUESTIONS = 10;
const CIRCLE_RADIUS = 50;
export default class extends Controller {
@ -11,14 +10,16 @@ export default class extends Controller {
connect() {
this._startT = 0;
requestAnimationFrame(this._startAnimating.bind(this));
window.setTimeout(() => {
requestAnimationFrame(this._startAnimating.bind(this));
}, 500);
}
_startAnimating(t) {
this._finalScore = gameState.getSummary().totalRight;
this._startT = t;
this._finalArcPostition = 360 * this._finalScore / MAX_QUESTIONS;
this._finalArcPostition = 360 * this._finalScore / gameState.getMaxQuestions();
this._currentlyDisplayedScore = 0;
this.countTarget.innerText = "0%";
@ -36,7 +37,7 @@ export default class extends Controller {
this.pathTarget.setAttribute("d", this._describeArc(CIRCLE_RADIUS, CIRCLE_RADIUS, CIRCLE_RADIUS - 5, 0, this._finalArcPostition));
}
let scoreToDisplay = (this._finalScore * 100 / MAX_QUESTIONS) | 0;
let scoreToDisplay = (this._finalScore * 100 / gameState.getMaxQuestions()) | 0;
this.countTarget.innerText = `${scoreToDisplay}%`;
window.setTimeout(() => this._showPostStore(), 1);
return;
@ -46,7 +47,7 @@ export default class extends Controller {
this.pathTarget.setAttribute("d", this._describeArc(CIRCLE_RADIUS, CIRCLE_RADIUS, CIRCLE_RADIUS - 5, 0, this._finalArcPostition * arcT));
let scoreToDisplay = (arcT * this._finalScore * 100 / MAX_QUESTIONS) | 0;
let scoreToDisplay = (arcT * this._finalScore * 100 / gameState.getMaxQuestions()) | 0;
if (scoreToDisplay != this._currentlyDisplayedScore) {
this._currentlyDisplayedScore = scoreToDisplay;
this.countTarget.innerText = `${scoreToDisplay}%`;
@ -90,7 +91,8 @@ export default class extends Controller {
}
_showPostStore() {
this.rankTarget.innerText = "Developer";
let rank = gameState.getSummary().rank;
this.rankTarget.innerText = rank;
this.postScoreTarget.classList.remove("hidden");
}

View file

@ -2,10 +2,32 @@
--score-color: green;
}
div.center-prose {
max-width: 60vh;
margin-inline: auto;
}
div.offscreen {
position: fixed;
left: -100px;
top: -100px;
position: fixed;
left: -100px;
top: -100px;
}
div.center-align {
text-align: center;
}
img.logo {
display: inline-block;
width: 60vh;
height: auto;
}
/***
* Question
*/
.submit-and-answer {
margin-block-start: 1.5em;
}
div.question.reveal label {
@ -93,6 +115,10 @@ input[type=radio] {
height: 2em;
}
h4 {
margin-bottom: 0.8rem;
}
/**
* Your score
*/
@ -206,6 +232,14 @@ div.rank {
animation: 0.3s ease-in both move-in;
}
:root.fade-transition::view-transition-old(root) {
animation: 0.3s ease-in both fade-out;
}
:root.fade-transition::view-transition-new(root) {
animation: 0.3s ease-in both fade-in;
}
@media (prefers-reduced-motion: reduce) {
::view-transition-old(root) {
animation: 0.3s ease-in both fade-out;