From: Vincent Vanwaelscappel Date: Fri, 18 Aug 2023 17:26:35 +0000 (+0200) Subject: wip #6182 @1 X-Git-Url: http://git.cubedesigners.com/?a=commitdiff_plain;h=71882c59c474f77e3332d1d47fba237eab48c7e5;p=fluidbook-toolbox-quiz.git wip #6182 @1 --- diff --git a/js/quiz.animations.js b/js/quiz.animations.js index 97bc6b7..8c45b75 100644 --- a/js/quiz.animations.js +++ b/js/quiz.animations.js @@ -5,12 +5,13 @@ const $ = require("cash-dom"); function QuizAnimations(quiz) { this.quiz = quiz; + this.instantReviewAnimationTimeout = 0; this.initEvents(); } QuizAnimations.prototype = { - initEvents:function(){ + initEvents: function () { // Animate buttons on mouse down and up $(document).on("mousedown", ".btn", function () { gsap.to($(this), {scale: .95, duration: .2, ease: "back.inOut"}); @@ -20,7 +21,6 @@ QuizAnimations.prototype = { }, - // Load the animation "name" in container load: function (name, container, replace) { let json = this.quiz.data.animations[name]; @@ -38,7 +38,23 @@ QuizAnimations.prototype = { } }, - triggeredBtn: function() { + instantReviewAnimation: function (status) { + let selector = $("#instantReviewAnimation") + let text = status === "NOK" ? "Not quite" : "Perfect" + let $this = this + this.quiz.animations.load(status, selector, {'\\$text': text}); + selector.addClass("active") + this.instantReviewAnimationTimeout = setTimeout(function (e) { + $this.stopInstantReviewAnimation() + }, 10000) + }, + + stopInstantReviewAnimation: function () { + $("#instantReviewAnimation").removeClass("active").empty() + clearTimeout(this.instantReviewAnimationTimeout); + }, + + triggeredBtn: function () { /*$(document).on("mousedown", ".btn", function() { gsap.to($(this), { scale: .9, duration: 0.3 }); }).on("mouseup", ".btn", function() { diff --git a/js/quiz.js b/js/quiz.js index 3f74281..ec114b4 100644 --- a/js/quiz.js +++ b/js/quiz.js @@ -27,22 +27,21 @@ Quiz.prototype = { init: function () { let $this = 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 + this.data = data; + // Initialisation des modules this.animations = new QuizAnimations(this); + this.question = new QuizQuestion(this); this.score = new QuizScore(this); this.scorm = new QuizScorm(this); this.resize = new QuizResize(this); - this.question = new QuizQuestion(this); 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 - this.data = data; - this.responses = [] - console.log(this.data); // ICI tout commence vraiment console.log(this.data.theme) diff --git a/js/quiz.progressbar.js b/js/quiz.progressbar.js index f0cef40..cf19511 100644 --- a/js/quiz.progressbar.js +++ b/js/quiz.progressbar.js @@ -3,28 +3,20 @@ function QuizProgressbar(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") + update: function () { + let $this = this; + const questionStatus = this.quiz.score.questionStatus + console.log(questionStatus); + $('.progress-container').each(function () { + let $cont = this; + $.each(questionStatus, function (questionIndex, status) { + if (status.ok !== 'not answered') { + // Si l'instant review est désactivé, on passe l'item en blanc pour pas donner d'indice sur le fait que la réponse était ok ou pas + $($cont).find('span').eq(questionIndex).addClass($this.quiz.data.instantReview ? status.ok : 'active'); } - } - } + }); + }); }, } -export default QuizProgressbar; \ No newline at end of file +export default QuizProgressbar; diff --git a/js/quiz.score.js b/js/quiz.score.js index c395771..b205d1c 100644 --- a/js/quiz.score.js +++ b/js/quiz.score.js @@ -14,7 +14,7 @@ function QuizScore(quiz) { QuizScore.prototype = { init: function () { - + this.updateScore(); }, /** diff --git a/js/quiz.screens.js b/js/quiz.screens.js index ebac792..a578f8d 100644 --- a/js/quiz.screens.js +++ b/js/quiz.screens.js @@ -46,12 +46,16 @@ QuizScreens.prototype = { } } else { // Bouton continuer, on était dans la revue instantanée, on passe à la question suivante + $this.quiz.animations.stopInstantReviewAnimation(); $this.nextQuestion(); } }); }, instantReview: function (review) { + this.quiz.progressbar.update(); + this.quiz.animations.instantReviewAnimation(review.ok === 'ok' ? 'OK' : 'NOK'); + let form = this.getCurrentForm(); let activeScreen = this.getActiveScreen(); // Disable form, we don't want the user be able to click on items @@ -118,42 +122,11 @@ QuizScreens.prototype = { callback(); } $this.activeScreen = screenToShow; + $this.currentQuestionAnswers = []; + $this.quiz.progressbar.update(); }); }, - 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.quiz.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(); - } - }, getCurrentForm: function () { return this.getActiveScreen().find('form'); @@ -163,75 +136,12 @@ QuizScreens.prototype = { this.getCurrentForm().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); - } - }, getActiveScreen() { return this.activeScreen; }, - validateResponse: function (responses) { - const form = this.getCurrentForm(); - const questionIndex = this.quiz.question.currentPosition(); - - if (form) { - if (form.length > 0) { - let validated = quiz.score.setAnswer(questionIndex, responses); - if (validated.ok === "ok") { - this.animationValidation("OK") - } else { - this.animationValidation("NOK") - } - this.resultAfterValidation(validated.status[questionIndex].answers) - } - return false - } - }, - - - resultAfterValidation: function (results) { - for (let k in results) { - let answerResult = results[k]; - - 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(answerResult) - if (answerResult === "nok") { - icon = getSpriteIcon("quiz-wrong") - } - if (answerResult !== "neutral") { - $el.find(".access").addClass(answerResult).html(icon) - } else { - $el.find(".access").remove(); - } - } - }, - - /** * Si un écran est affiché, on le masque puis on exécute le callback. Sinon, on exécute immédiatement le callback * @param callback diff --git a/style/101-header-footer.sass b/style/101-header-footer.sass index 4775a07..0e65766 100644 --- a/style/101-header-footer.sass +++ b/style/101-header-footer.sass @@ -61,9 +61,8 @@ header .btn.primary width: 100% - +above(992px) - max-width: 400px - position: absolute - left: 50% - bottom: 24px - transform: translateX(-50%) + max-width: 400px + position: absolute + left: 50% + bottom: 24px + transform: translateX(-50%) diff --git a/style/104-animations.sass b/style/104-animations.sass index 4ef9ee3..9012171 100644 --- a/style/104-animations.sass +++ b/style/104-animations.sass @@ -1,4 +1,4 @@ -#anim +#instantReviewAnimation position: absolute top: 50% left: 50% diff --git a/views/header_question.blade.php b/views/header_question.blade.php index 5909879..1fa42bd 100644 --- a/views/header_question.blade.php +++ b/views/header_question.blade.php @@ -2,7 +2,7 @@

{{ __('Question').' '.($position+1).'/'.$max }}

@for($i = 0; $i < $max; $i++) - + @endfor

{{$question['question']}}

diff --git a/views/index.blade.php b/views/index.blade.php index 9272efd..a25a03d 100644 --- a/views/index.blade.php +++ b/views/index.blade.php @@ -24,7 +24,7 @@ @include('screens.question_'.$question['type'], ['theme' => $data->theme,'data'=>$data, 'question'=> $question, 'max' => $totalQuestion, 'position' => $key, 'alphabet' => $alphabet]) @endforeach @include('screens.outro', ['data'=> $data]) -
+