From b6234784f6ca3aa4b3830cc39f9c2e74124da919 Mon Sep 17 00:00:00 2001 From: Vincent Vanwaelscappel Date: Fri, 18 Aug 2023 09:38:57 +0200 Subject: [PATCH] wip #6182 @3 --- js/quiz.accessibility.js | 2 +- js/quiz.animations.js | 2 +- js/quiz.js | 157 +-------------------------------------- js/quiz.progressbar.js | 30 ++++++++ js/quiz.question.js | 2 +- js/quiz.resize.js | 2 +- js/quiz.score.js | 2 +- js/quiz.scorm.js | 2 +- js/quiz.screen.intro.js | 13 +++- js/quiz.screens.js | 143 ++++++++++++++++++++++++++++++++++- js/quiz.utils.js | 2 +- 11 files changed, 190 insertions(+), 167 deletions(-) create mode 100644 js/quiz.progressbar.js diff --git a/js/quiz.accessibility.js b/js/quiz.accessibility.js index 6866787..17a49fd 100644 --- a/js/quiz.accessibility.js +++ b/js/quiz.accessibility.js @@ -24,5 +24,5 @@ QuizAccessibility.prototype = { }, } -module.exports = QuizAccessibility; +export default QuizAccessibility; diff --git a/js/quiz.animations.js b/js/quiz.animations.js index d43a719..bd83cba 100644 --- a/js/quiz.animations.js +++ b/js/quiz.animations.js @@ -34,4 +34,4 @@ QuizAnimations.prototype = { } -module.exports = QuizAnimations; +export default QuizAnimations; diff --git a/js/quiz.js b/js/quiz.js index f8078e0..fc6ae4f 100644 --- a/js/quiz.js +++ b/js/quiz.js @@ -11,6 +11,7 @@ import QuizQuestion from './quiz.question'; import QuizAccessibility from './quiz.accessibility'; import QuizUtils from './quiz.utils'; import QuizScreens from './quiz.screens'; +import QuizProgressbar from "./quiz.progressbar"; window.cubeSCORM = new CubeSCORM(); window.$ = window.jQuery = $; @@ -35,6 +36,7 @@ Quiz.prototype = { this.utils = new QuizUtils(this); this.accessibility = new QuizAccessibility(this); this.screens = new QuizScreens(this); + this.progressbar=new QuizProgressbar(this); // Ici seront injectées dans this.data toutes les données du quiz et du thème pour qu'elles soient disponibles // dans l'object à tout moment @@ -46,12 +48,6 @@ Quiz.prototype = { console.log(this.data.theme) this.timeoutAnimation = false - - // commencer - $(document).on("click", "#start", function () { - $this.start() - }) - // $("#quiz").css("background-image", "url(" + this.data.theme.backgroundImage + ")") @@ -92,20 +88,7 @@ Quiz.prototype = { gsap.to($(this), {scale: 1, duration: .2}); }) - // - this.activeNav() - }, - - start: function () { - const $this = this - gsap.timeline().to("#welcome-screen", { - opacity: 0, - onComplete: function () { - let responses = $this.responses - $this.next(responses); - $("#welcome-screen").removeClass("next active-screen").addClass("none").next(".container-screen").removeClass("none").addClass("next active-screen") - } - }) + this.progressbar.update(); }, updateIcons: function () { @@ -132,140 +115,6 @@ Quiz.prototype = { this.resize.resize(); }, - next: function (responses) { - // on arrête l'animation si le joueur passe à la question suivante - this.stopAnimationValidation() - - let status = quiz.score.questionStatus - let currentPosition = quiz.score.lastAnsweredQuestion + 1 - - const $el = $(".active-screen .btn.action") - - quiz.score.updateScore() - // if form exist and responses are validated - // dont miss to add this second condition - if ($(".active-screen form").length > 0) { - if (status.length > 0) { - if (status[this.question.currentPosition()].ok === "not answered") { - this.validateResponse(responses); - this.updateBtnValidation("validated") - return false - } - } - } - - $el.parents(".container-screen").addClass("none").removeClass("next active-screen").next(".container-screen").removeClass("none").addClass("next active-screen") - this.resetForm() - // on incrémente de 1 la position actuelle de la question (qui commence à l'index zero) - // pour récupérer le premier enfant de la nav - this.activeNav((parseInt(this.question.currentPosition()) + 1)) - this.updateBtnValidation() - // si c'est la dernière question a été validée alors on affiche le résultat au prochain screen - if (this.question.last(currentPosition)) { - this.screens.outro.show(); - } - }, - - // marque page automatique - // si le joueur recharge la page, le rediriger là où il en était - setDisplay: function () { - const currentQuestion = quiz.score.lastAnsweredQuestion + 1, - questions = this.quiz.questions - - if (questions.length > 0) { - if (quiz.score.lastAnsweredQuestion > -1 && questions.length <= currentQuestion) { - // - } - } - }, - - resetForm: () => { - $("form").find("input").prop("checked", false) - }, - - updateBtnValidation: function (status) { - let $btnAction = $(".footer-question .action"), - validationText = $btnAction.data("validation-text"), - continueText = $btnAction.data("continue-text") - - $btnAction.find('.text').text(status === "validated" ? continueText : validationText) - }, - - validateResponse: function (responses) { - const form = $(".active-screen form") - const activeScreen = $(".active-screen") - const position = activeScreen.data("position") - - if (form) { - if (form.length > 0) { - let validated = quiz.score.setAnswer(position, responses); - if (validated.ok === "ok") { - this.animationValidation("OK") - } else { - this.animationValidation("NOK") - } - this.resultAfterValidation(validated.status[position].answers) - } - return false - } - }, - - activeNav: function (position = 1) { - const questionStatus = quiz.score.questionStatus - const lastAnsweredQuestion = quiz.score.lastAnsweredQuestion - if ($(".active-screen").find(".progress-item").length > 0) { - let $el = $(".progress-container .progress-item:nth-child(" + position + ")") - - $(".progress-container .progress-item").removeClass("active") - $el.addClass("active") - - let n = (lastAnsweredQuestion + 1) - let $_el = $(".progress-container .progress-item:nth-child(" + n + ")") - - if (lastAnsweredQuestion > -1) { - if (questionStatus[lastAnsweredQuestion].ok === 'ok') { - $_el.addClass("ok") - } - if (questionStatus[lastAnsweredQuestion].ok === 'nok') { - $_el.addClass("nok") - } - } - } - }, - - animationValidation: function (status) { - let selector = $("#anim") - let text = status === "NOK" ? "Not quite" : "Perfect" - let $this = this - this.animations.load(status, selector, {'\\$text': text}); - selector.addClass("active") - this.timeoutAnimation = setTimeout(function (e) { - $this.stopAnimationValidation() - }, 10000) - }, - - stopAnimationValidation: function () { - $("#anim").removeClass("active").empty() - if (this.timeoutAnimation) - clearTimeout(this.timeoutAnimation) - }, - - resultAfterValidation: function (datas) { - for (let k in datas) { - let n = (parseInt(k) + 1) - let icon = getSpriteIcon("quiz-ok") - let $el = $(".active-screen .question-multiple .list-item:nth-of-type(" + n + ") label") - $el.addClass(datas[k]) - if (datas[k] === "nok") { - icon = getSpriteIcon("quiz-wrong") - } - if (datas[k] !== "neutral") { - $el.find(".access").addClass(datas[k]).html(icon) - } - } - }, - - restart: function () { } diff --git a/js/quiz.progressbar.js b/js/quiz.progressbar.js new file mode 100644 index 0000000..f0cef40 --- /dev/null +++ b/js/quiz.progressbar.js @@ -0,0 +1,30 @@ +function QuizProgressbar(quiz) { + this.quiz = quiz; +} + +QuizProgressbar.prototype = { + update: function (position = 1) { + const questionStatus = quiz.score.questionStatus + const lastAnsweredQuestion = quiz.score.lastAnsweredQuestion + if ($(".active-screen").find(".progress-item").length > 0) { + let $el = $(".progress-container .progress-item:nth-child(" + position + ")") + + $(".progress-container .progress-item").removeClass("active") + $el.addClass("active") + + let n = (lastAnsweredQuestion + 1) + let $_el = $(".progress-container .progress-item:nth-child(" + n + ")") + + if (lastAnsweredQuestion > -1) { + if (questionStatus[lastAnsweredQuestion].ok === 'ok') { + $_el.addClass("ok") + } + if (questionStatus[lastAnsweredQuestion].ok === 'nok') { + $_el.addClass("nok") + } + } + } + }, +} + +export default QuizProgressbar; \ No newline at end of file diff --git a/js/quiz.question.js b/js/quiz.question.js index f659d07..8c90f4d 100644 --- a/js/quiz.question.js +++ b/js/quiz.question.js @@ -34,4 +34,4 @@ QuizQuestion.prototype = { }, } -module.exports = QuizQuestion; +export default QuizQuestion; diff --git a/js/quiz.resize.js b/js/quiz.resize.js index b68ab5a..aa1c17e 100644 --- a/js/quiz.resize.js +++ b/js/quiz.resize.js @@ -11,4 +11,4 @@ QuizResize.prototype = { }, } -module.exports = QuizResize; +export default QuizResize; diff --git a/js/quiz.score.js b/js/quiz.score.js index b336788..8e0284c 100644 --- a/js/quiz.score.js +++ b/js/quiz.score.js @@ -149,5 +149,5 @@ QuizScore.prototype = { }, }; -module.exports = QuizScore; +export default QuizScore; diff --git a/js/quiz.scorm.js b/js/quiz.scorm.js index b5e5570..1a6409d 100644 --- a/js/quiz.scorm.js +++ b/js/quiz.scorm.js @@ -4,4 +4,4 @@ function QuizScorm(quiz) { QuizScorm.prototype = {}; -module.exports = QuizScorm; +export default QuizScorm; diff --git a/js/quiz.screen.intro.js b/js/quiz.screen.intro.js index 5c37e6a..e52ce3c 100644 --- a/js/quiz.screen.intro.js +++ b/js/quiz.screen.intro.js @@ -1,15 +1,22 @@ import gsap from "gsap"; import SplitType from 'split-type'; -function QuizScreenIntro(quiz) { - this.quiz = quiz; +function QuizScreenIntro(screens) { + this.quiz = screens.quiz; + this.screens = screens; } QuizScreenIntro.prototype = { show: function () { - console.log(':)'); + let $this = this; + $("#welcome-screen").addClass('active-screen next').removeClass('none'); this.animate(); + + $(document).on("click", "#start", function () { + $this.screens.gotoQuestion(1); + return false; + }); }, animate: function () { diff --git a/js/quiz.screens.js b/js/quiz.screens.js index 2d94412..4e9a507 100644 --- a/js/quiz.screens.js +++ b/js/quiz.screens.js @@ -1,12 +1,149 @@ +import gsap from "gsap"; + import QuizScreenIntro from './quiz.screen.intro'; import QuizScreenOutro from "./quiz.screen.outro"; function QuizScreens(quiz) { this.quiz = quiz; - this.intro = new QuizScreenIntro(quiz); - this.outro = new QuizScreenOutro(quiz); + this.intro = new QuizScreenIntro(this); + this.outro = new QuizScreenOutro(this); } -QuizScreens.prototype = {}; +QuizScreens.prototype = { + gotoQuestion: function (question) { + const $this = this; + let callback = function () { + let responses = $this.quiz.responses + $this.next(responses); + } + + let screen; + if (question == 1) { + screen = $("#welcome-screen"); + } + + this.hideScreen(screen, callback); + }, + + next: function (responses) { + // on arrête l'animation si le joueur passe à la question suivante + this.stopAnimationValidation() + + let status = quiz.score.questionStatus + let currentPosition = quiz.score.lastAnsweredQuestion + 1 + + const $el = $(".active-screen .btn.action") + + this.quiz.score.updateScore() + // if form exist and responses are validated + // dont miss to add this second condition + if ($(".active-screen form").length > 0) { + if (status.length > 0) { + if (status[this.question.currentPosition()].ok === "not answered") { + this.validateResponse(responses); + this.updateBtnValidation("validated") + return false + } + } + } + + $el.parents(".container-screen").addClass("none").removeClass("next active-screen").next(".container-screen").removeClass("none").addClass("next active-screen") + this.resetForm() + // on incrémente de 1 la position actuelle de la question (qui commence à l'index zero) + // pour récupérer le premier enfant de la nav + this.quiz.progressbar.update((parseInt(this.quiz.question.currentPosition()) + 1)) + this.updateBtnValidation() + // si c'est la dernière question a été validée alors on affiche le résultat au prochain screen + if (this.quiz.question.last(currentPosition)) { + this.outro.show(); + } + }, + + + resetForm: () => { + $("form").find("input").prop("checked", false) + }, + + updateBtnValidation: function (status) { + let $btnAction = $(".footer-question .action"), validationText = $btnAction.data("validation-text"), + continueText = $btnAction.data("continue-text") + + $btnAction.find('.text').text(status === "validated" ? continueText : validationText) + }, + + animationValidation: function (status) { + let selector = $("#anim") + let text = status === "NOK" ? "Not quite" : "Perfect" + let $this = this + this.quiz.animations.load(status, selector, {'\\$text': text}); + selector.addClass("active") + this.timeoutAnimation = setTimeout(function (e) { + $this.stopAnimationValidation() + }, 10000) + }, + + stopAnimationValidation: function () { + $("#anim").removeClass("active").empty() + if (this.timeoutAnimation) { + clearTimeout(this.timeoutAnimation); + } + }, + + + validateResponse: function (responses) { + const form = $(".active-screen form") + const activeScreen = $(".active-screen") + const position = activeScreen.data("position") + + if (form) { + if (form.length > 0) { + let validated = quiz.score.setAnswer(position, responses); + if (validated.ok === "ok") { + this.animationValidation("OK") + } else { + this.animationValidation("NOK") + } + this.resultAfterValidation(validated.status[position].answers) + } + return false + } + }, + + + + resultAfterValidation: function (datas) { + for (let k in datas) { + let n = (parseInt(k) + 1) + let icon = getSpriteIcon("quiz-ok") + let $el = $(".active-screen .question-multiple .list-item:nth-of-type(" + n + ") label") + $el.addClass(datas[k]) + if (datas[k] === "nok") { + icon = getSpriteIcon("quiz-wrong") + } + if (datas[k] !== "neutral") { + $el.find(".access").addClass(datas[k]).html(icon) + } + } + }, + + + hideScreen: function (screen, callback) { + let cb = function () { + $(screen).removeClass("next active-screen").addClass("none"); + //next(".container-screen").removeClass("none").addClass("next active-screen"); + callback(); + }; + + if (this.quiz.utils.isVisible(screen)) { + gsap.timeline().to("#welcome-screen", { + autoAlpha: 0, onComplete: function () { + cb(); + } + }) + } else { + cb(); + } + }, +}; export default QuizScreens; \ No newline at end of file diff --git a/js/quiz.utils.js b/js/quiz.utils.js index 2abb2ba..4e28901 100644 --- a/js/quiz.utils.js +++ b/js/quiz.utils.js @@ -12,4 +12,4 @@ QuizUtils.prototype = { } } -module.exports = QuizUtils; \ No newline at end of file +export default QuizUtils; \ No newline at end of file -- 2.39.5