bjoluc / jspsych-builder

A CLI utility to easily develop and package jsPsych experiments
MIT License
46 stars 12 forks source link

How to add webgazer into the experiments? #55

Open rahatzamancse opened 4 months ago

rahatzamancse commented 4 months ago

I do not have experience with webpack that much. Can you please point out on how I can add additional javascript extensions in the experiment.ts file?

Here is what I tried inside the run function:

const jsPsych = initJsPsych({
  extensions: [
    {
      type: jsPsychExtensionWebgazer,
      params: {
        auto_initialize: true,
      }
    }
  ]
});
const timeline: { type: any; [key: string]: any }[] = [];

// Preload assets
timeline.push({
  type: PreloadPlugin,
  images: assetPaths.images,
  audio: assetPaths.audio,
  video: assetPaths.video,
});

// initialize eye tracking
timeline.push({
  type: jsPsychWebgazerInitCamera
})
timeline.push({
  type: jsPsychWebgazerCalibrate,
  calibration_points: [[25,50], [50,50], [75,50], [50,25], [50,75]],
  calibration_mode: 'click'
})

But I get the following error while running:

Error: Webgazer extension failed to initialize. webgazer.js not loaded. Load webgazer.js before calling initJsPsych()
    at JsPsych.<anonymous> (http://localhost:3000/js/app.js:31248:15)
    at Generator.throw (<anonymous>)
    at rejected (http://localhost:3000/js/app.js:27640:32)

How can I load webgazer.js before calling initJsPsych()?

rahatzamancse commented 4 months ago

I found a way to load webgazer.js using html-webpack-plugin.

Modified the build.config.mjs to add the script and recreate the html.

import HtmlWebpackPlugin from 'html-webpack-plugin';

/** @param {import("webpack").Configuration} config */
export function webpack(config) {
    // Find the HtmlWebpackPlugin instance in the plugins array
    const htmlWebpackPluginIndex = config.plugins.findIndex(
        plugin => plugin instanceof HtmlWebpackPlugin
    );

    if (htmlWebpackPluginIndex !== -1) {
        // Modify the HtmlWebpackPlugin options to include webgazer.js
        const originalOptions = config.plugins[htmlWebpackPluginIndex].userOptions;
        config.plugins[htmlWebpackPluginIndex] = new HtmlWebpackPlugin({
            ...originalOptions,
            scriptLoading: 'blocking',
            templateContent: ({ htmlWebpackPlugin }) => `<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>first-experiment (Development Build)</title>
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.jsdelivr.net/gh/jspsych/jspsych@jspsych@7.0.0/examples/js/webgazer/webgazer.js"></script>
    <script defer src="js/app.js"></script>
    <link href="css/main.css" rel="stylesheet">
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html>`});
    }

    return config;
}

However, in future if jspsych-builder would add/change anything from the default html template, this may not work. Is there a better way to get this working?