1

In my code, I am trying to set up an experiment with the following flow:

  1. Participant ID (insert participant ID)

  2. Consent Form

  3. Explanation (explanation of how to respond in the experiment and that next will be a practice set)

  4. Practice Set (first array with five practice videos)

  5. Experiment explanation (a page that displays the end of the practice and explains the eye-tracking calibration instructions)

  6. Eyetracking Calibration

  7. Experiment starting screen (screen that explains the instructions for the next two blocks of videos)

  8. Block 1 (block of 20 videos)

  9. Break (5-minute timer to pause between the two blocks)

  10. Block 2 (block of 20 videos)

  11. Experiment completion page (the page that informs the participant the two blocks are completed, the eye tracking is completed, and the experiment will move on to the final questionnaire)

  12. Questionnaire

I am having difficulties with the videos as they display on every screen rather than on the pages I want them on (practicePage, block1Page, and block2Page). I am also receiving a TypeError when reading 'play' when I try to play the videos (Cannot read properties of null (reading 'play')when trying to play the videos).

// Common elements
const btn1 = document.getElementById("btn1");
const btn2 = document.getElementById("btn2");
const questionText = document.getElementById("questionText");
const optionsDiv = document.querySelector(".options");

// Video elements for each page
const videoElementpractice = document.getElementById("practice");
const videoElementBlock1 = document.getElementById("block1");
const videoElementBlock2 = document.getElementById("block2");

const practiceinteraction = [{
    videoPath: "Videopath.1",
    question: "Question",
    options: ["1", "2"]
  },
  {
    videoPath: "Videopath.2",
    question: "Question",
    options: ["1", "2"]
  },
];

const block1Interactions = [{
    videoPath: "Videopath.1",
    question: "Question",
    options: ["1", "2"]
  },
  {
    videoPath: "Videopath.2",
    question: "Question",
    options: ["1", "2"]
  },
];

const block2Interactions = [{
    videoPath: "Videopath.1",
    question: "Question",
    options: ["1", "2"]
  },
  {
    videoPath: "Videopath.2",
    question: "Question",
    options: ["1", "2"]
  },
];

// Interaction state
let currentVideoIndex = 0;
let responses = [];
let currentPage = "participantIDpage"; // Define the current page

// Define interaction arrays for each page
const interactionsMap = {
  "practice": practiceinteraction,
  "block1Page": block1Interactions,
  "block2Page": block2Interactions
};

// Page 1: Participant ID Page
function showParticipantID() {
  //        participantId = id;
  document.getElementById("participantIDPage").style.display = "block";
  //        storeParticipantId(participantId);
}

// Page 2: Consent Form
function showConsent() {
  document.getElementById("participantIDPage").style.display = "none";
  document.getElementById("consentFormPage").style.display = "block";
}

// Page 3: Explanation
function showExplanation() {
  document.getElementById("consentFormPage").style.display = "none";
  document.getElementById("explanationPage").style.display = "block";
}

// Page 4: Practice
function showPractice() {
  currentPage = "practicePage";
  document.getElementById("explanationPage").style.display = "none";
  document.getElementById("practicePage").style.display = "block";
  currentVideoIndex = 0;
  currentVideoElement = videoElementpractice;
  playpracticevideo(practiceinteraction, videocontainer);
}

// Page 5: Calibration Explanation
function showCalibrationExplanation() {
  currentPage = "calibrationExplanation";
  document.getElementById('practicePage').style.display = 'none';
  document.getElementById('calibrationExplanationPage').style.display = 'block';
}

// Page 6: Calibration
function showCalibration() {
  currentPage = "calibration";
  document.getElementById('calibrationExplanationPage').style.display = 'none';
  document.getElementById('calibrationPage').style.display = 'block';
}

// Page 7: Experimental Start
function showExperiment() {
  currentPage = "experiment";
  document.getElementById('calibrationPage').style.display = 'none';
  document.getElementById('experimentPage').style.display = 'block';
}

// Page 8: Block 1
function showBlock1() {
  currentPage = "block1";
  document.getElementById("experimentPage").style.display = "none";
  document.getElementById("block1Page").style.display = "block";
  currentVideoIndex = 0;
  currentVideoElement = videoElementBlock1;
  playblock1video(block1Interactions, videocontainer);
}

// Page 9: Break
let breakTimerInterval;
let breakTimer = 300; // 5 minutes in seconds

function updateTimerDisplay() {
  const timerValueElement = document.getElementById("timerValue");
  const minutes = Math.floor(breakTimer / 60);
  const seconds = breakTimer % 60;
  timerValueElement.textContent = `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
}

function startBreakTimer() {
  breakTimerInterval = setInterval(() => {
    if (breakTimer > 0) {
      breakTimer--;
      updateTimerDisplay();
    } else {
      clearInterval(breakTimerInterval);
      document.getElementById("timerContainer").style.display = "none";
      document.getElementById("nextButton").style.display = "block";
    }
  }, 1000); // Update every second
}

function showBreak() {
  document.getElementById('block1Page').style.display = 'none';
  document.getElementById('breakPage').style.display = 'block';
  startBreakTimer(); // Start the timer when the page is displayed
}

// Page 10: Start Block 2
function showBlock2() {
  currentPage = "block2";
  document.getElementById("breakPage").style.display = "none";
  document.getElementById("block2Page").style.display = "block";
  currentVideoIndex = 0;
  currentVideoElement = videoElementBlock2;
  playblock2video(block2Interactions, videocontainer);
}

// Page 11: Experiment Completion
function showCompletion() {
  document.getElementById('block2Page').style.display = 'none';
  document.getElementById('completionPage').style.display = 'block';
}

// Page 12: Questionnaire
function showQuestionnaire() {
  document.getElementById('completionPage').style.display = 'none';
  document.getElementById('questionnairePage').style.display = 'block';
}

let eventListenerActive = false; // Flag to track if the event listener is active

// Bind play to space bar
document.addEventListener("keydown", (event) => {
  if (event.key === " ") {
    event.preventDefault(); // Prevent default spacebar behavior (like scrolling)

    // Check if the space bar should play the video based on the current page
    if (currentPage === "practicePage") {
      videoElementpractice.play();
    } else if (currentPage === "block1Page") {
      videoElementBlock1.play();
    } else if (currentPage === "block2Page") {
      videoElementBlock2.play();
    }
  }
});

function spaceBarEventHandler(event) {
  if (event.key === " ") {
    event.preventDefault(); // Prevent default spacebar behavior (like scrolling)
  }
}

function addSpaceBarEventListener() {
  if (!eventListenerActive) {
    document.addEventListener("keydown", spaceBarEventHandler);
    eventListenerActive = true;
  }
}

function removeSpaceBarEventListener() {
  if (eventListenerActive) {
    document.removeEventListener("keydown", spaceBarEventHandler);
    eventListenerActive = false;
  }
}

// Enable space bar event listener
addSpaceBarEventListener();

const blankScreenDiv = document.getElementById("blankScreenDiv");

function displayInteraction1(practiceinteraction) {
  if (videoElementpractice) {
    // Pause the video and reset currentTime before changing the src
    videoElementpractice.pause();
    videoElementpractice.currentTime = 0;

    videoElementpractice.src = practiceinteraction.videoPath + ".mp4";
    questionText.textContent = practiceinteraction.question;
    optionsDiv.style.display = "none"; // Hide options initially

    videoElementpractice.removeAttribute("autoplay"); // Remove autoplay attribute

    videoElementpractice.onended = () => {
      optionsDiv.style.display = "block"; // Show options after video ends
    };
  }
}

function displayInteraction2(block1interactions) {
  if (videoElementBlock1) {
    // Pause the video and reset currentTime before changing the src
    videoElementBlock1.pause();
    videoElementBlock1.currentTime = 0;

    videoElementBlock1.src = practiceinteraction.videoPath + ".mp4";
    questionText.textContent = practiceinteraction.question;
    optionsDiv.style.display = "none"; // Hide options initially

    videoElementBlock1.removeAttribute("autoplay"); // Remove autoplay attribute

    videoElementBlock1.onended = () => {
      optionsDiv.style.display = "block"; // Show options after video ends
    };
  }
}

function displayInteraction3(block2interaction) {
  if (videoElementBlock2) {
    // Pause the video and reset currentTime before changing the src
    videoElementBlock2.pause();
    videoElementBlock2.currentTime = 0;

    videoElementBlock2.src = practiceinteraction.videoPath + ".mp4";
    questionText.textContent = practiceinteraction.question;
    optionsDiv.style.display = "none"; // Hide options initially

    videoElementBlock2.removeAttribute("autoplay"); // Remove autoplay attribute

    videoElementBlock2.onended = () => {
      optionsDiv.style.display = "block"; // Show options after video ends
    };
  }
}

function createVideoContainers(videocontainer, interactionArray) {
  for (let i = 1; i <= 3; i++) {
    const videoContainer = document.createElement("div");
    videoContainer.id = videocontainer + "container" + i;
    videoContainer.className = videocontainer + "container";
    document.body.appendChild(videoContainer);
  }
}

// Function to show a video container
function showContainer(videocontainer) {
  const container = document.getElementById(videocontainer);
  if (container) {
    container.style.display = "block"; // Show the container
  }
}

// Function to hide a video container
function hideContainer(videocontainer) {
  const container = document.getElementById(videocontainer);
  if (container) {
    container.style.display = "none"; // Hide the container
  }
}

// Determine the current video element based on the page
let currentVideoElement;

// Function to play the next video in an interaction array
function playpracticevideo(currentVideoIndex, practiceinteraction, currentVideoElement, videocontainer) {
  if (currentPage === "practicePage") {
    currentVideoElement = videoElementpractice;
    if (currentVideoIndex < practiceinteraction.length) {
      createVideoContainers("practice", practiceinteraction + currentVideoIndex);
      displayInteraction1(practiceinteraction[currentVideoIndex], currentVideoElement);
      currentVideoIndex++;
    } else {
      hideContainer(videocontainer + "practicecontainer" + (currentVideoIndex - 1)); // Use hideContainer() instead
      if (currentPage === "block1Page" || currentPage === "block2Page") {
        proceedToNextStep();
      }
    }
  }
}

function playblock1video(currentVideoIndex, block1interactions, currentVideoElement, videocontainer) {
  if (currentPage === "block1Page") {
    currentVideoElement = videoElementBlock1;
    if (currentVideoIndex < block1interactions.length) {
      showContainer(videocontainer + "block1container" + currentVideoIndex);
      displayInteraction2(block1interactions[currentVideoIndex], currentVideoElement);
      currentVideoIndex++;
    } else {
      hideContainer(videocontainer + "practicecontainer" + (currentVideoIndex - 1)); // Use hideContainer() instead
      if (currentPage === "block1Page" || currentPage === "block2Page") {
        proceedToNextStep();
      }
    }
  }
}

function playblock2video(currentVideoIndex, block2interactions, currentVideoElement, videocontainer) {
  if (currentPage === "block2Page") {
    currentVideoElement = videoElementBlock1;
    if (currentVideoIndex < block2interactions.length) {
      showContainer(videocontainer + "block2container" + currentVideoIndex);
      displayInteraction3(block2interactions[currentVideoIndex], currentVideoElement);
      currentVideoIndex++;
    } else {
      hideContainer(videocontainer + "practicecontainer" + (currentVideoIndex - 1)); // Use hideContainer() instead
      if (currentPage === "block1Page" || currentPage === "block2Page") {
        proceedToNextStep();
      }
    }
  }
}

// Handle option selection
function optionSelected(option) {
  responses.push(option);
  optionsDiv.style.display = "none";
}

function proceedToNextStep() {
  // Logic to navigate to the next page
  if (currentPage === "practicePage") {
    // Navigate to the next step/page for the practice section
    // For example:
    showCalibrationExplanation();
  } else if (currentPage === "block1Page") {
    // Navigate to the next step/page for block 1
    // For example:
    showBreak();
  } else if (currentPage === "block2Page") {
    // Navigate to the next step/page for block 2
    // For example:
    showCompletionPage()
  } else {

  }
}

// Continue to the next page
function continueToNextPage() {
  blankScreenDiv.style.display = "none";
  displayResponses();
}

document.addEventListener("keydown", (event) => {
  if (event.key === "1") {
    optionSelected(1);
  } else if (event.key === "2") {
    optionSelected(2);
  }

  function hideContainers(videocontainer, index) {
    hideContainer(videocontainer + "practicecontainer");
    hideContainer(videocontainer + "block1container");
    hideContainer(videocontainer + "block2container");
  }

  // Check if the space bar should be disabled
  const disabledPages = [
    "participantID",
    "consentForm",
    "explanation",
    "calibrationExplanation",
    "calibration",
    "experiment",
    "break",
    "completion",
    "questionaire"
  ];

  if (event.key === " " && disabledPages.includes(currentPage)) {
    event.preventDefault(); // Prevent spacebar action
    hideContainers(videocontainer, currentVideoIndex); // Hide video containers
  }
});

blankScreenDiv.style.display = "none";

// Start the experiment flow when the page loads
window.onload = function() {
  //  participantId = "someParticipantId"; // Get the actual participant ID here
  showParticipantID();
};
body {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100vh;
  margin: 0;
  font-family: Arial, sans-serif;
}

#consentFormPage {
  max-width: 800px;
  margin: 0 auto;
  overflow: auto;
}

#videoContainer {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  margin: 5px auto;
}

.video-wrapper {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

video {
  max-width: 75%;
  max-height: calc(100vh - 20px);
}

.options,
.blank-screen {
  display: none;
  text-align: center;
  margin: none;
}

.options p,
.options button {
  margin: none;
}

#controls {
  display: flex;
  justify-content: center;
  margin-top: 20px;
}

button {
  margin: 0 10px;
  padding: 5px 10px;
}

.hidden {
  display: none;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Eye Tracking Experiment</title>


  <div id="blankScreenDiv"></div>
</head>

<body>

  <!-- Define the video elements -->
  <video id="videoElementpractice" controls></video>
  <video id="videoElementBlock1" controls></video>
  <video id="videoElementBlock2" controls></video>

  <!-- Page 1: Participant ID -->
  <div id="participantIDPage">
    <!-- Participant ID form -->
    <h2>Participant ID</h2>
    <p>参加者IDを入力してください:</p>
    <form id="participantIdForm">
      <input type="text" id="participantIdInput" placeholder="Enter Participant ID">
      <button type="button" id="participantIdNextButton" onclick="showConsent()">次へ</button>
    </form>
  </div>

  <!-- Page 2: Consent Form -->
  <div id="consentFormPage" style="display: none;">
    <!-- Consent form content -->
    <p>Input Text...</p>
    <br>
    <button type="button" id="explanationNextButton" onclick="showPractice()">同意します</button>
  </div>

  <!-- Page 7: Experiment Starting Screen -->
  <div id="experimentPage" style="display: none;">
    <!-- Starting screen content -->
    <p>Input Text</p>
    <button type="button" id="block" onclick="showBlock1()">次へ</button>
  </div>

  <!-- Page 4: Practice Set -->
  <div id="practicePage" style="display: none;">
  </div>

  <!-- Page 5: Experiment Starting Screen -->
  <div id="calibrationExplanationPage" style="display: none;">
    <!-- Starting screen content -->
    <p>Input Text</p>
    <button type="button" id="calibration" onclick="showCalibration()">次へ</button>
  </div>

  <!-- Page 6: Eye Tracking Calibration -->
  <div id="calibrationPage" style="display: none;">
    <!-- Calibration instructions -->
    <p>Calibration instructions...</p>
    <button type="button" id="experiment" onclick="showExperiment()">次へ</button>
  </div>

  <!-- Page 7: Experiment Starting Screen -->
  <div id="experimentPage" style="display: none;">
    <!-- Starting screen content -->
    <p>Input Text</p>
    <button type="button" id="block" onclick="showBlock1()">次へ</button>
  </div>

  <!-- Page 8: Block 1 ... -->
  <div id="block1Page" style="display: none;">
  </div>

  <div class="options" style="display:none;">
    <br><br>
    <p id="questionTextBlock1"></p>
    <button onclick="optionSelectedBlock1(1)">1</button>
    <button onclick="optionSelectedBlock1(2)">2</button>
  </div>
  </div>

  <!-- Page 9: Break Screen -->
  <div id="breakPage" style="display: none;">
    <!-- Break screen content -->
    <p>Input Text</p>
    <div id="timerContainer">
      <p id="timerText">残り時間: <span id="timerValue">5:00</span></p>
      <button type="button" id="Block2" onclick="showBlock2()">次へ</button>
    </div>
  </div>

  <!-- Page 10: Block 2 ... -->
  <div id="Block2Page" style="display: none;">
  </div>

  <div class="options" style="display:none;">
    <br><br>
    <p id="questionTextBlock2"></p>
    <button onclick="optionSelectedBlock2(1)">1</button>
    <button onclick="optionSelectedBlock2(2)">2</button>
  </div>
  </div>

  <!-- Page 11: Experiment Completion Screen -->
  <div id="completionPage" style="display: none;">
    <p>Input Text</p>
    <button type="button" id="Questionairre" onclick="showQuestionairre()">次へ</button>
  </div>

  <!-- Page 12: Questionairre Screen -->
  <div id="questionairrePage" style="display: none;">
    <p>ADD QUESTIONAIRRE</p>
  </div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Kitten
  • 11
  • 1

0 Answers0