Pages

Thursday, November 14, 2024

Creating an Interactive, Responsive Quiz with Fireworks Animation

 

Creating an Interactive, Responsive Quiz with Fireworks Animation

By weelookang@gmail.com


Introduction

In this blog post, we'll explore the step-by-step process of creating an interactive, responsive quiz application using HTML, CSS, and JavaScript. The quiz features multiple-choice questions, allows unlimited attempts until all answers are correct, and includes a festive fireworks animation for each correct answer. This project is perfect for educational purposes, helping learners understand how to build dynamic web applications with engaging user experiences.

quiz template start
quiz template start

quiz template middle
quiz template middle


quiz template end
quiz template end


https://iwant2study.org/lookangejss/quiz/quiz.html


Table of Contents

  1. Project Overview
  2. Setting Up the HTML Structure
  3. Styling with CSS
  4. Adding Interactivity with JavaScript
  5. Implementing the Fireworks Animation
  6. Making the Quiz Responsive
  7. Integrating Google Analytics 
  8. Final Touches and Credits
  9. Conclusion
  10. Full Source Code

Project Overview

Features:

  • Multiple-choice quiz on world capitals.
  • Unlimited attempts until all answers are correct.
  • Dynamic score recalculation after each submission.
  • Fireworks animation for each correct answer.
  • Responsive design for various devices and orientations.
  • Integration with Google Analytics 
  • Credit line for authorship.

Setting Up the HTML Structure

The HTML structure forms the backbone of our quiz application.

Steps:

  1. DOCTYPE Declaration and HTML Skeleton:

    Begin with the <!DOCTYPE html> declaration and set up the basic HTML structure.

    html
    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>World Capitals Quiz</title> <!-- Additional scripts and styles will go here --> </head> <body> <!-- Quiz container --> <div id="quiz-container"> <h1>World Capitals Quiz</h1> <div id="quiz"></div> <button id="submit">Submit Quiz</button> <div id="results"></div> <!-- Credit Line --> <p style="text-align: center; margin-top: 20px;">Credits: Created by weelookang@gmail.com</p> </div> <!-- Scripts will go here --> </body> </html>
  2. Quiz Container:

    The #quiz-container div will hold the quiz title, questions, submit button, results, and credits.

  3. Quiz and Results Divs:

    • <div id="quiz"></div>: Placeholder for the quiz questions generated by JavaScript.
    • <div id="results"></div>: Displays the user's score after submission.
  4. Submit Button:

    The <button id="submit">Submit Quiz</button> allows users to submit their answers.


Styling with CSS

The CSS styles enhance the visual appeal and ensure responsiveness.

Steps:

  1. Basic Reset:

    Reset margins and paddings for consistency across browsers.

    css
    * { box-sizing: border-box; margin: 0; padding: 0; }
  2. Body Styling:

    Set the font, background color, and text color.

    css
    body { font-family: Arial, sans-serif; background-color: #f0f8ff; color: #333; line-height: 1.6; }
  3. Container and Heading:

    Center the quiz container and style the heading.

    css
    #quiz-container { max-width: 800px; margin: 20px auto; padding: 20px; } h1 { text-align: center; margin-bottom: 20px; color: #007acc; }
  4. Question and Answers Styling:

    Style the questions and answer options.

    css
    .question { margin-bottom: 20px; } .question h3 { margin-bottom: 10px; } .answers { list-style-type: none; } .answers li { margin-bottom: 10px; } label { display: block; cursor: pointer; } input[type="radio"] { margin-right: 10px; }
  5. Submit Button:

    Style the submit button with hover effects.

    css
    #submit { display: block; background-color: #007acc; color: #fff; border: none; padding: 15px; cursor: pointer; font-size: 16px; width: 100%; max-width: 300px; margin: 20px auto; border-radius: 5px; } #submit:hover { background-color: #005999; }
  6. Results Styling:

    Center and style the results text.

    css
    #results { text-align: center; margin-top: 20px; font-size: 20px; }

Adding Interactivity with JavaScript

JavaScript brings the quiz to life by generating questions and handling user interactions.

Steps:

  1. Quiz Questions Array:

    Define an array of question objects.

    javascript
    const quizQuestions = [ { question: "What is the capital of France?", answers: { a: "Paris", b: "Rome", c: "Madrid", d: "Berlin" }, correctAnswer: "a" }, // Add more questions... ];
  2. Building the Quiz:

    Create a buildQuiz() function to dynamically generate the quiz HTML.

    javascript
    function buildQuiz() { const quizContainer = document.getElementById('quiz'); const output = []; quizQuestions.forEach((currentQuestion, questionNumber) => { const answers = []; for (let letter in currentQuestion.answers) { answers.push( `<li> <label> <input type="radio" name="question${questionNumber}" value="${letter}"> ${letter.toUpperCase()}: ${currentQuestion.answers[letter]} </label> </li>` ); } output.push( `<div class="question"> <h3>Q${questionNumber + 1}. ${currentQuestion.question}</h3> <ul class="answers"> ${answers.join('')} </ul> </div>` ); }); quizContainer.innerHTML = output.join(''); }
  3. Showing Results:

    Implement showResults() to check answers, calculate the score, and provide feedback.

    javascript
    function showResults() { const answerContainers = document.querySelectorAll('.answers'); let numCorrect = 0; // Remove previous fireworks const previousFireworks = document.querySelectorAll('.firework'); previousFireworks.forEach(firework => firework.remove()); quizQuestions.forEach((currentQuestion, questionNumber) => { const answerContainer = answerContainers[questionNumber]; const selector = `input[name=question${questionNumber}]:checked`; const userAnswerElem = answerContainer.querySelector(selector); const userAnswer = userAnswerElem ? userAnswerElem.value : undefined; // Reset the question color answerContainer.parentElement.style.color = '#333'; if (userAnswer === currentQuestion.correctAnswer) { numCorrect++; answerContainer.parentElement.style.color = 'green'; // Add fireworks (implemented in the next section) } else if (userAnswer) { answerContainer.parentElement.style.color = 'red'; } else { answerContainer.parentElement.style.color = 'orange'; } }); const resultsContainer = document.getElementById('results'); resultsContainer.innerHTML = `<p>You got ${numCorrect} out of ${quizQuestions.length} correct!</p>`; if (numCorrect === quizQuestions.length) { resultsContainer.innerHTML += `<p>Congratulations! You answered all questions correctly!</p>`; } }
  4. Event Listener:

    Add an event listener to the submit button.

    javascript
    document.getElementById('submit').addEventListener('click', showResults);
  5. Initialize the Quiz:

    Call buildQuiz() when the page loads.

    javascript
    buildQuiz();

Implementing the Fireworks Animation

Adding a visual reward enhances user engagement.

Steps:

  1. Firework CSS Styles:

    Define styles for the fireworks animation.

    css
    .firework { position: relative; width: 0; height: 0; margin: 10px auto; } .firework span { position: absolute; width: 4px; height: 20px; background: gold; border-radius: 2px; transform-origin: bottom center; animation: explode 0.6s ease-out forwards; } .firework span:nth-child(1) { transform: rotate(0deg); } .firework span:nth-child(2) { transform: rotate(72deg); } .firework span:nth-child(3) { transform: rotate(144deg); } .firework span:nth-child(4) { transform: rotate(216deg); } .firework span:nth-child(5) { transform: rotate(288deg); } @keyframes explode { from { opacity: 1; transform: rotate(var(--rotate-angle)) translateY(0) scaleY(1); } to { opacity: 0; transform: rotate(var(--rotate-angle)) translateY(-50px) scaleY(0.5); } }
  2. Adding Fireworks in JavaScript:

    Update the showResults() function to create the fireworks when a correct answer is detected.

    javascript
    if (userAnswer === currentQuestion.correctAnswer) { numCorrect++; answerContainer.parentElement.style.color = 'green'; // Create a firework animation const fireworkDiv = document.createElement('div'); fireworkDiv.classList.add('firework'); // Create 5 spark spans for(let i = 1; i <= 5; i++) { const spark = document.createElement('span'); spark.style.setProperty('--rotate-angle', `${(i - 1) * 72}deg`); fireworkDiv.appendChild(spark); } answerContainer.parentElement.appendChild(fireworkDiv); }
  3. Preserving Rotation in Animation:

    Use CSS custom properties to maintain the rotation angle during the animation.

    css
    /* In @keyframes explode */ transform: rotate(var(--rotate-angle)) translateY(-50px) scaleY(0.5);

Making the Quiz Responsive

Ensuring the quiz looks good on all devices is crucial.

Steps:

  1. Viewport Meta Tag:

    Included in the <head> section.

    html
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
  2. Responsive Font Sizes:

    Adjust font sizes for smaller screens using media queries.

    css
    @media (max-width: 600px) { body { font-size: 18px; } #submit { font-size: 18px; padding: 20px; } }
  3. Flexible Layouts:

    Use percentage-based widths and flexible margins.

    css
    #quiz-container { max-width: 800px; margin: 20px auto; padding: 20px; }

Integrating Google Analytics 

Integrating analytics and ads can help track user engagement and monetize the application.

Steps:

  1. Google Analytics Script:

    Add the following scripts to the <head> section.

    html
    <!-- Google Analytics --> <script async="true" src="https://www.googletagmanager.com/gtag/js?id=G-S9EWRY1CPJ"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-S9EWRY1CPJ'); </script>

Final Touches and Credits

  1. Adding a Credit Line:

    Include a credit line at the bottom of the quiz container.

    html
    <p style="text-align: center; margin-top: 20px;">Credits: Created by weelookang@gmail.com</p>
  2. Ensuring Accessibility:

    • Use semantic HTML elements.
    • Add lang="en" attribute to the <html> tag.
    • Ensure sufficient color contrast.

Conclusion

We've successfully created an interactive, responsive quiz application with engaging animations and essential web integrations. This project demonstrates how HTML, CSS, and JavaScript can work together to build dynamic educational tools.


Full Source Code

html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>World Capitals Quiz</title> <!-- Google Analytics --> <script async="true" src="https://www.googletagmanager.com/gtag/js?id=G-S9EWRY1CPJ"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-S9EWRY1CPJ'); </script> <style> /* Basic Reset */ * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: Arial, sans-serif; background-color: #f0f8ff; color: #333; line-height: 1.6; } #quiz-container { max-width: 800px; margin: 20px auto; padding: 20px; } h1 { text-align: center; margin-bottom: 20px; color: #007acc; } .question { margin-bottom: 20px; } .question h3 { margin-bottom: 10px; } .answers { list-style-type: none; } .answers li { margin-bottom: 10px; } label { display: block; cursor: pointer; } input[type="radio"] { margin-right: 10px; } #submit { display: block; background-color: #007acc; color: #fff; border: none; padding: 15px; cursor: pointer; font-size: 16px; width: 100%; max-width: 300px; margin: 20px auto; border-radius: 5px; } #submit:hover { background-color: #005999; } #results { text-align: center; margin-top: 20px; font-size: 20px; } /* Fireworks Animation */ .firework { position: relative; width: 0; height: 0; margin: 10px auto; } .firework span { position: absolute; width: 4px; height: 20px; background: gold; border-radius: 2px; transform-origin: bottom center; animation: explode 0.6s ease-out forwards; } /* Position the 5 lines at different angles */ .firework span:nth-child(1) { transform: rotate(0deg); } .firework span:nth-child(2) { transform: rotate(72deg); } .firework span:nth-child(3) { transform: rotate(144deg); } .firework span:nth-child(4) { transform: rotate(216deg); } .firework span:nth-child(5) { transform: rotate(288deg); } @keyframes explode { from { opacity: 1; transform: rotate(var(--rotate-angle)) translateY(0) scaleY(1); } to { opacity: 0; transform: rotate(var(--rotate-angle)) translateY(-50px) scaleY(0.5); } } /* Responsive Design */ @media (max-width: 600px) { body { font-size: 18px; } #submit { font-size: 18px; padding: 20px; } } </style> </head> <body> <div id="quiz-container"> <h1>World Capitals Quiz</h1> <div id="quiz"></div> <button id="submit">Submit Quiz</button> <div id="results"></div> <!-- Credit Line --> <p style="text-align: center; margin-top: 20px;">Credits: Created by weelookang@gmail.com</p> </div> <script> // Array of quiz questions const quizQuestions = [ { question: "What is the capital of France?", answers: { a: "Paris", b: "Rome", c: "Madrid", d: "Berlin" }, correctAnswer: "a" }, { question: "What is the capital of Japan?", answers: { a: "Seoul", b: "Tokyo", c: "Beijing", d: "Bangkok" }, correctAnswer: "b" }, { question: "What is the capital of Canada?", answers: { a: "Toronto", b: "Ottawa", c: "Vancouver", d: "Montreal" }, correctAnswer: "b" }, { question: "What is the capital of Australia?", answers: { a: "Sydney", b: "Melbourne", c: "Canberra", d: "Perth" }, correctAnswer: "c" }, { question: "What is the capital of Brazil?", answers: { a: "Rio de Janeiro", b: "São Paulo", c: "Brasília", d: "Salvador" }, correctAnswer: "c" } ]; // Function to build the quiz function buildQuiz() { const quizContainer = document.getElementById('quiz'); const output = []; quizQuestions.forEach((currentQuestion, questionNumber) => { const answers = []; for (let letter in currentQuestion.answers) { answers.push( `<li> <label> <input type="radio" name="question${questionNumber}" value="${letter}"> ${letter.toUpperCase()}: ${currentQuestion.answers[letter]} </label> </li>` ); } output.push( `<div class="question"> <h3>Q${questionNumber + 1}. ${currentQuestion.question}</h3> <ul class="answers"> ${answers.join('')} </ul> </div>` ); }); quizContainer.innerHTML = output.join(''); } // Function to show the results function showResults() { const answerContainers = document.querySelectorAll('.answers'); let numCorrect = 0; // Remove previous fireworks const previousFireworks = document.querySelectorAll('.firework'); previousFireworks.forEach(firework => firework.remove()); quizQuestions.forEach((currentQuestion, questionNumber) => { const answerContainer = answerContainers[questionNumber]; const selector = `input[name=question${questionNumber}]:checked`; const userAnswerElem = answerContainer.querySelector(selector); const userAnswer = userAnswerElem ? userAnswerElem.value : undefined; // Reset the question color answerContainer.parentElement.style.color = '#333'; if (userAnswer === currentQuestion.correctAnswer) { numCorrect++; answerContainer.parentElement.style.color = 'green'; // Create a firework animation const fireworkDiv = document.createElement('div'); fireworkDiv.classList.add('firework'); // Create 5 spark spans for(let i = 1; i <= 5; i++) { const spark = document.createElement('span'); spark.style.setProperty('--rotate-angle', `${(i - 1) * 72}deg`); fireworkDiv.appendChild(spark); } answerContainer.parentElement.appendChild(fireworkDiv); } else if (userAnswer) { answerContainer.parentElement.style.color = 'red'; } else { answerContainer.parentElement.style.color = 'orange'; } }); const resultsContainer = document.getElementById('results'); resultsContainer.innerHTML = `<p>You got ${numCorrect} out of ${quizQuestions.length} correct!</p>`; if (numCorrect === quizQuestions.length) { resultsContainer.innerHTML += `<p>Congratulations! You answered all questions correctly!</p>`; } } // Event listener for submit button document.getElementById('submit').addEventListener('click', showResults); // Build the quiz on page load buildQuiz(); </script> </body> </html>

Conclusion

Building this quiz application demonstrates the power and flexibility of combining HTML, CSS, and JavaScript to create interactive and educational web content. By adding features like unlimited attempts, dynamic scoring, animations, and responsiveness, we've enhanced the user experience and provided a practical learning tool.


Credits: Created by weelookang@gmail.com

No comments:

Post a Comment