import { Controller } from "https://unpkg.com/@hotwired/stimulus/dist/stimulus.js"; import { gameState } from "./gamestate.js"; const ANIMATION_DURATION = 1500.0; const CIRCLE_RADIUS = 50; export default class extends Controller { static targets = ['path', 'pathBack', 'count', 'postScore', 'rank']; connect() { this._startT = 0; window.setTimeout(() => { requestAnimationFrame(this._startAnimating.bind(this)); }, 500); } _startAnimating(t) { this._finalScore = gameState.getSummary().totalRight; this._startT = t; this._finalArcPostition = 360 * this._finalScore / gameState.getMaxQuestions(); this._currentlyDisplayedScore = 0; this.countTarget.innerText = "0%"; requestAnimationFrame(this._animateFrame.bind(this)); } _animateFrame(t) { let tt = t - this._startT; let tScaled = tt / ANIMATION_DURATION; if (tt >= ANIMATION_DURATION) { if (this._finalArcPostition == 360) { this.pathTarget.setAttribute("d", this._describeCircle(CIRCLE_RADIUS, CIRCLE_RADIUS, CIRCLE_RADIUS - 5)); } else { this.pathTarget.setAttribute("d", this._describeArc(CIRCLE_RADIUS, CIRCLE_RADIUS, CIRCLE_RADIUS - 5, 0, this._finalArcPostition)); } let scoreToDisplay = (this._finalScore * 100 / gameState.getMaxQuestions()) | 0; this.countTarget.innerText = `${scoreToDisplay}%`; window.setTimeout(() => this._showPostStore(), 1); return; } let arcT = Math.sin(tt / ANIMATION_DURATION * Math.PI / 2.0); this.pathTarget.setAttribute("d", this._describeArc(CIRCLE_RADIUS, CIRCLE_RADIUS, CIRCLE_RADIUS - 5, 0, this._finalArcPostition * arcT)); let scoreToDisplay = (arcT * this._finalScore * 100 / gameState.getMaxQuestions()) | 0; if (scoreToDisplay != this._currentlyDisplayedScore) { this._currentlyDisplayedScore = scoreToDisplay; this.countTarget.innerText = `${scoreToDisplay}%`; } requestAnimationFrame(this._animateFrame.bind(this)); } _polarToCartesian(centerX, centerY, radius, angleInDegrees) { var angleInRadians = (angleInDegrees - 180) * Math.PI / 180; return { x: centerX + (radius * Math.cos(angleInRadians)), y: centerY + (radius * Math.sin(angleInRadians)) }; } _describeCircle(x, y, radius) { var start = this._polarToCartesian(x, y, radius, 0); var mid = this._polarToCartesian(x, y, radius, 180); var end = this._polarToCartesian(x, y, radius, 360); var d = [ "M", start.x, start.y, "A", radius, radius, 0, 0, 0, mid.x, mid.y, "A", radius, radius, 0, 1, 0, end.x, end.y, ].join(" "); return d; } _describeArc(x, y, radius, startAngle, endAngle){ var start = this._polarToCartesian(x, y, radius, endAngle); var end = this._polarToCartesian(x, y, radius, startAngle); var largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1"; var d = [ "M", start.x, start.y, "A", radius, radius, 0, largeArcFlag, 0, end.x, end.y ].join(" "); return d; } _showPostStore() { let rank = gameState.getSummary().rank; this.rankTarget.innerText = rank; this.postScoreTarget.classList.remove("hidden"); } }