diff --git a/public/scripts/controllers/yourscore.js b/public/scripts/controllers/yourscore.js new file mode 100644 index 0000000..53dfcd5 --- /dev/null +++ b/public/scripts/controllers/yourscore.js @@ -0,0 +1,90 @@ +import { Controller } from "https://unpkg.com/@hotwired/stimulus/dist/stimulus.js"; +import { gameState } from "./gamestate.js"; + +const ANIMATION_DURATION = 1500.0; + +export default class extends Controller { + static targets = ['path', 'count']; + + connect() { + this._startT = 0; + + requestAnimationFrame(this._startAnimating.bind(this)); + } + + _startAnimating(t) { + this._finalScore = 3; + + this._startT = t; + this._finalArcPostition = 360 * this._finalScore / 10; + this._updateCounterEvery = ANIMATION_DURATION / this._finalScore; + this._updateCounterAt = 0; + + this._currentlyDisplayedScore = 0; + this.countTarget.innerText = "0"; + requestAnimationFrame(this._animateFrame.bind(this)); + } + + _animateFrame(t) { + let tt = t - this._startT; + + if (tt >= ANIMATION_DURATION) { + + if (this._finalArcPostition == 360) { + this.pathTarget.setAttribute("d", this._describeCircle(50, 50, 45)); + } else { + this.pathTarget.setAttribute("d", this._describeArc(50, 50, 45, 0, this._finalArcPostition)); + } + + this.countTarget.innerText = this._finalScore.toString(); + return; + } + + let arcT = Math.sin(tt / ANIMATION_DURATION * Math.PI / 2.0); + + this.pathTarget.setAttribute("d", this._describeArc(50, 50, 45, 0, this._finalArcPostition * arcT)); + + if (tt >= this._updateCounterAt) { + this._currentlyDisplayedScore++; + this.countTarget.innerText = this._currentlyDisplayedScore.toString(); + this._updateCounterAt += this._updateCounterEvery; + } + + 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; + } + +} \ No newline at end of file diff --git a/public/scripts/main.js b/public/scripts/main.js index 56298f7..f797a9d 100644 --- a/public/scripts/main.js +++ b/public/scripts/main.js @@ -2,8 +2,10 @@ import { Application } from "https://unpkg.com/@hotwired/stimulus/dist/stimulus. import ClearStateController from "./controllers/clearstate.js"; import PickerController from "./controllers/picker.js"; +import YourScoreController from "./controllers/yourscore.js"; window.Stimulus = Application.start(); Stimulus.register("picker", PickerController); -Stimulus.register("clearstate", ClearStateController); \ No newline at end of file +Stimulus.register("clearstate", ClearStateController); +Stimulus.register("yourscore", YourScoreController); \ No newline at end of file diff --git a/views/end.html b/views/end.html index ea4de5e..f76a0f0 100644 --- a/views/end.html +++ b/views/end.html @@ -1,3 +1,12 @@

Well Done

You reached the end

+ +
+ + + + + +
0
+