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"});
},
-
// Load the animation "name" in container
load: function (name, container, replace) {
let json = this.quiz.data.animations[name];
}
},
- 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() {
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)
}
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;
QuizScore.prototype = {
init: function () {
-
+ this.updateScore();
},
/**
}
} 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
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');
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
.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%)
-#anim
+#instantReviewAnimation
position: absolute
top: 50%
left: 50%
<p class="abovetitle">{{ __('Question').' '.($position+1).'/'.$max }} </p>
<div class="progress-container">
@for($i = 0; $i < $max; $i++)
- <span class="progress-item"></span>
+ <span class="progress-item {{$i===$position?'active':''}}"></span>
@endfor
</div>
<h1 id="titleQuestion">{{$question['question']}}</h1>
@include('screens.question_'.$question['type'], ['theme' => $data->theme,'data'=>$data, 'question'=> $question, 'max' => $totalQuestion, 'position' => $key, 'alphabet' => $alphabet])
@endforeach
@include('screens.outro', ['data'=> $data])
- <div id="anim"></div>
+ <div id="instantReviewAnimation"></div>
</div>
</div>
<script src="js/quiz.js"></script>