Giter Club home page Giter Club logo

jspsych-psychophysics's People

Contributors

bjoluc avatar ffigari avatar kohske avatar kurokida avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

jspsych-psychophysics's Issues

event handlers compatible with gabor parameters

Hi, I can change certain gabor parameters with the event handler examples, for startX, but I cannot change others, such as tilt. for example, jsPsych.currentTrial().stim_array[0].startX = 50 changes the position as expected. jsPsych.currentTrial().stim_array[0].tilt=50 does not change the tilt. any thoughts? much thanks.

This example should change both tilt and startX, but it only shifts the gabor and does not change the tilt :(

let current = 90;

  var circle_obj = {
    obj_type: 'gabor',
    startX: current,
    startY: 150,
    tilt: current,
    sf: 0.05,
    phase: 90,
    width: 150,
    sc: 10,
    contrast: 0.5,
    disableNorm: true
  };

  const trial = {
      type: 'psychophysics',
      canvas_height: 500,
      prompt: '<p>Pressing the ArrowUp/ArrowDown key, the color of the circle will change. <br>Press the space key to finish the program.</p>',
      stimuli: [circle_obj], // These can be referenced using the jsPsych.currentTrial().stimuli array.
      response_type: 'key',
      choices: [' '],
      key_down_func: function(event){ // The key_up_func is also available. In that case, the color of the circle changes when you release the key. 
        if (event.key === 'ArrowUp'){
          current += 2;
        } else if (event.key === 'ArrowDown'){
          current -= 2;
        }

        // Note that when specify the space bar, you need to write event.key === ' ' not event.key === 'space'.
        
        jsPsych.currentTrial().stim_array[0].startX = current;
        jsPsych.currentTrial().stim_array[0].tilt = current;
      },
  }

resize

when using the jspsych-resize prior to use the jspsych-psychophysics if the resize is a little too big scrollbars are automatically activated.
Using document.body.classList.add("stop-scrolling"); doesn't prevent the appearance of the scrollbars. Would be better to disable them by default?

Recolour SVG image

Hello,

I wonder if there is an easy way to change the color of an SVG image. In my experiment, I want to display several object with varied colour. The colour is assigned according to the experimental manipulation.

At the moment, I have tried to display the image with image stimulus or using manual stimulus to display it. When I use the image stimulus, I did not find an argument to change the color of the image. And when I tried to use drawFunc, I just found that the image did not display even if I didn't code anything in the drawFunc.

In this case, I started to use manual stimulus. Here is my code:

const iconObject = {
        obj_type: 'manual',
        drawFunc: function (stimulus, canvas, context) {
            // Create a new image element
            var img = new Image();

            // Set the source of the image to the provided imgPath
            img.src = file;

            // When the image is loaded, draw it on the canvas
            img.onload = function () {
                // Clear the canvas
                context.clearRect(0, 0, canvas.width, canvas.height);
                // Draw the image on the canvas
                context.drawImage(img, 0, 0, canvas.width, canvas.height);
            }
        }

I found even if I only want to display the image, it did not work.

It would be very helpful if there were an easy solution to do it. Thank you in advance!

How do I change the contrast level on every trial?

Hi! I am using a function called gabor to draw my stimulus which I am calling in the drawFunc function using the object property. In the gabor function, I want to change the contrast level randomly. That is, everytime the stimulus 'Left0' is presented, I want the gabor to have a different contrast level. I give pass the contrast level through the input parameter 'con'. When I use Math.random() to generate the contrast level, my gabor patch flickers because the contrast gets changed on every call of the drawFunc function. If I store Math.random () in a variable and then pass the variable in the stim.gabor function as an input parameter, the contrast level does not change for Left0 everytime the stimulus is used in a trial. I have set the number of repetitions to the number of times I want the trial to be repeated in the variable block50_50. I want the contrast level of the stimulus to be changed every time the trial is repeated in the block. Could you help me with it?
var stim = { gabor: function draw(x1, y1, x2, y2, x, y, con) { context = jsPsych.currentTrial().context; const gradLength = 100; const my_gradient = context.createLinearGradient(x1, y1, x2, y2); const bands = 10; const colors = ["#000", "#FFF"]; const stops = bands * colors.length; var pos = 0; while (pos <= stops) { my_gradient.addColorStop(pos / stops, colors[pos % colors.length]); pos++; } context.fillStyle = my_gradient; context.filter = 'contrast(' + con + ')' context.fillRect(x, y, gradLength, gradLength); context.stroke() } }
var Left0 = { obj_type: 'manual', horiz_pix_sec: 30, show_start_time: 0, motion_start_time: 2000, startX: 950, startY: 325, endX: 1150, endY: 325, // location in the canvas width: 300, height: 200, // of the rectangle drawFunc: function () { stim.gabor(400, 0, 600, 0, 500, 325, array[y]) } };

var trial1a = { type: 'psychophysics', stimuli: [Left0, Right0, fixation], choices: [37, 39], trial_duration: 2000, data: { stimulus_type: '1a' }, on_finish: function (data) { if (data.key_press == 39) { data.correct = true; } else { data.correct = false; } } }

var block50_50 = { timeline: [fix, trial1a, fb], repetitions: 5, randomize_order: true }

Integrating gaborgen-js with jspsych-psychophysics

Hello,
I tried to use to gaborgen-js with jspsych-psychophysics. I can easily use gaborgen-js with the basic jspsych plug-ins for example with img src= gaborgen(50, 50) as a HTML stimulus.
I didn't find an easy way with jspsych-psychophysics, I tried to draw directly the matrix with obj_type: 'manual' but since I got stuck I was wondering if there was an easier way. Do you have any suggestions?
Thank you again for your great work.
Best,
Giulio.

Use function() to set the parameter of an object

I hope this is not due to my low developer skills!
If I try to give a value to a parameter of an object of jspsych-psychophysics using a function it doesn't work.
height: function() {return 1000;},

Instead this works with the object of "basic" jspsych
post_trial_gap: function(){return 1000;},

Here the example (remember to add the plugin for html-keyboard-response)

Thx!

var rect_object = {
    obj_type: 'rect', // means a rectangle
    startX: 200, // location in the canvas
    startY: 150,
    width: 300, // of the rectangle
    height: function() {return 1000;},
    line_color: '#ffffff',
    fill_color: '#ffffff',
    show_start_time: 0 // from the trial start (ms)
}

var circle_object = {
    obj_type: 'circle',
    startX: 500, // location in the canvas
    startY: 300,
    radius: 100,
    line_color: 'red', // You can use the HTML color name instead of the HEX color.
    fill_color: 'red',
    show_start_time: 1000 // from the trial start (ms)
}
var first = {
  obj_type: 'instruction',
  type: 'html-keyboard-response',
  stimulus: '<p>Welcome to exp1_visivo</p>',
  post_trial_gap: function(){return 1000;},
};
var trial = {
    type: 'psychophysics',
    stimuli: [rect_object, circle_object],
    choices: ['y', 'n'], // The participant can respond to the stimuli using the 'y' or 'n' key.
    canvas_width: 1000,
    canvas_height: 800,
    background_color: '#008000', // The HEX color means green.
}

jsPsych.init({
    timeline: [first,trial],
    on_finish: function(){jsPsych.data.displayData();}
});
</script>

'manual property' does not display on Macintosh desktop. How to fix it?

Hi! I used the manual property to draw the fixation cross and stimuli for my experiment. When I run the experiment on some laptops, the fixation and stimuli appear on the center of the screen. However, when I run the same code in a particular Macintosh desktop, the stimuli and fixation appear elsewhere on the screen. Additionally, I change the contrast level of my stimulus on every trial. The changes occur on all devices expect for the macintosh system. Is there anyway I can fix these issues? Here is the code:

<script>
var fixation = {
        obj_type: 'manual',
        startX: 0, // location of the cross's center in the canvas
        startY: 0,
        origin_center: true,
        show_start_time: 0,
        motion_end_time: 2000,
        line_color: '#000000',// You can use the HTML color name instead of the HEX color.
        drawFunc() {
            context = jsPsych.currentTrial().context;
            context.beginPath();
            context.moveTo(752.5, 380); //horizontal line
            context.lineTo(797.5, 380);
            context.moveTo(775, 355); //vertical line
            context.lineTo(775, 405);
            context.filter = 'contrast(1)';
            context.lineWidth = 5;
            context.stroke();
        }
    }

var stim = {
        gabor: function draw(x1, y1, x2, y2, x, y, con) {  //x1, y1, x2, y2 are the coordinates for the start and end of the gradient.
            context = jsPsych.currentTrial().context; // x, y are the position of the gabor on the screen. Con is the contrast level.
            const gradLength = 100;
            const my_gradient = context.createLinearGradient(x1, y1, x2, y2);
            const bands = 10;
            const colors = ["#000", "#FFF"];
            const stops = bands * colors.length;
            var pos = 0;
            while (pos <= stops) {
                my_gradient.addColorStop(pos / stops, colors[pos % colors.length]);
                pos++;
            }
            context.fillStyle = my_gradient;
            context.filter = 'contrast(' + con + ')'
            context.fillRect(x, y, gradLength, gradLength);
            context.stroke()
        }
    }
    var Left0 = {
        obj_type: 'manual', show_start_time: 0, origin_center: true, motion_end_time: 2000,
        startX: -225, startY: 0, endX: -425, endY: 0,// location in the canvas
        width: 300, height: 200, // of the rectangle
        drawFunc: function () {
            stim.gabor(400, 0, 600, 0, 500, 325, jsPsych.currentTrial().contrast)
        }
    };

timing in frames in different obj_type

Hi!
I am setting the presentation timing of visual stimuli (i.e. obj_type: circle) using show_start_frame and show_end_frame. I also would like to present auditory stimuli (i.e. obj_type: ‘sound’), but in this case it seems that I can set the presentation timing only using show_start_time and show_end_time.
Thus I was wondering if having some stimuli with the timing set in frames and other stimuli with the timing set in ms could negatively influence their synchronization. Which do you think would be the best option to have synchronized visual and auditory stimuli?
Thanks a lot in advanced!
Silvia

How to use origin_center: true with a manual object property?

I would like to set the origin to the center of the screen. But I would like to draw a stimulus using the manual property. However, I am unsure how to set the x,y coordinates of stimulus in the drawFunc so that the image appears at the center of the screen. Should the x,y coordinates of stimulus in the drawFunc be same as before or should they change relative to the new origin at the center of the screen? Because when I do that, the stimulus appears at the top left corner of the screen.

var fixation = {
obj_type: 'manual',
startX: 0, // location of the cross's center in the canvas
startY: 0,
origin_center: true,
show_start_time: 0,
motion_end_time: 2000,
line_color: '#000000',// You can use the HTML color name instead of the HEX color.
drawFunc() {
context = jsPsych.currentTrial().context;
context.beginPath();
context.moveTo(752.5, 380); //horizontal line
context.lineTo(797.5, 380);
context.moveTo(775, 355); //vertical line
context.lineTo(775, 405);
context.filter = 'contrast(1)';
context.lineWidth = 5;
context.stroke();
}
}

Simulation mode for psychophysics

Hi,

Thanks a lot for developing this plugin! Upon examination, it looks like it's quite well-developed and takes advantage of some powerful new tools to allow quite solid precision in timing online experiments. I think it could cast serious concerns for the conclusions regarding timing on some relatively recent (but already dated) online timing experiments (e.g. here or here).

Anyhow, I was wondering if there are any plans in the pipeline to update the plugin with a simulation mode as have other jsPsych plugins - see here. In any case, I need to develop that at least for myself so if you have any comments/suggestions/feedback or are already working/have thought about this, I would genuinely appreciate your feedback.

Thanks in advance!

slider response

Hi!

I've been reading about jsPsych and this plugin reciently. I don't know much about web development and jsPsych yet, but I wonder if this plugin could be extended to support the use of sliders. And maybe to use the slider to dynamically change a stimulus on screen.

Prolem with object 'sound'

Hi,

I'm having trouble with the plug-in. It failed loading audio files with a message saying Try checking the file path.. I have last version of the plugin plus the JsPsych version which come on github. the probelm boils down when the plugin calls : jsPsych.pluginAPI.getAudioBuffer(this.file).

If I use a JsPych plugin as jsPsychAudioKeyboardResponse this function give me something like : Promise { <state>: "fulfilled", <value>: AudioBuffer }
When I use the same audio file in the psychophysics plugin I get : Promise { <state>: "fulfilled", <value>: "tmp" }.

What can be the issue ? I've tried both offline and online (Pavlovia).

Thank you.

"trial_ends_after_audio" parameter

Hi,

Is there a "trial_ends_after_audio" parameter in the "psychophysics" plugin? If not, could you please help me set the trial duration to the duration of the audio stimulus?

Thanks!

Catherine

    var retroaction = {
        type: 'psychophysics',
        stimuli: [
        	{
				obj_type: 'image',
				file: "img/x.png",
				startX:200
			},
			{
				obj_type: 'sound',
				file: jsPsych.timelineVariable('phrase')
			},
			{
				obj_type: 'image',
				file: jsPsych.timelineVariable('bonne_reponse'),
				startX: 625
			},
		],
        background_color: "FFFFFF",
        choices: jsPsych.NO_KEYS,
        trial_duration: 4000, //jsPsych.timelineVariable('phrase').duration
        on_start: function(retroaction) {
            if (jsPsych.data.getLastTrialData().values()[0].accuracy == true) {
                retroaction.stimuli[0].file = "img/crochet.png";
            }
        }
    }

Is there is a way to specify the trial_duration in flips (for a rapid presentation without responses on every presentation)?

Hello, thank you so much for this plugin, it's been amazingly helpful! The examples are very useful.

I am running an experiment where participants view a series of rapidly presented images (RSVP), displayed for 200ms each. They only need to respond when they see a target. I can specify the duration of each image in frames using the 'is_frame' and 'show_end_frame' parameters of the image, but to have the trial end without accepting a response (set 'response_ends_trial' = false) the 'trial_duration' parameter needs a value in milliseconds. This means that the timing is misaligned when the frames don't line up with the millisecond specification and it is not ideal. I have tried only using the 'trial_duration' parameter, but this also leads to inconsistent timing. I am a beginner in javascript, so it's very possible that I'm just missing something or using the wrong combination of variables.

Is there a way to specify the trial_duration in flips in the plugin? Or if not, is there another way to show multiple stimuli rapidly without requiring a response?

For example, here's some of my code for displaying a stream of single images in the periphery, with a fixation cross in the centre:

// a single image shown either side of fixation
    single_presentation = {
      obj_type: 'image',
      origin_center: true,
      startX: function(){
        if (jsPsych.timelineVariable("presentation_side")=='left'){
          return -300;
        } else {
          return 300;
        }
      },
      startY: 0,
      file: jsPsych.timelineVariable('image'),
      scale: 0.5,
    //is_frame: true, 
    //show_end_frame: 12
    }

    // combine single image with fixation cross 
    single_picture_display = {
      type: 'psychophysics',
      response_ends_trial: false,
      trial_duration: 200,
      stimuli: [single_presentation, fixation],
      data: {"display_item": "stimulus", "display_type": "single"}
    }

    // loop over the trial variables to make a rapid stream of images 
      single_trial = {
        timeline: [single_picture_display, isi],
        timeline_variables: tv
      }
      timeline.push(single_trial)

Making text stimuli bold and coloured

Hello, hope you are well.
I just wonder whether we can make some parts of the text bold and colored while leaving other parts of the text. I tried the following code, which did not work out.

image

Screenshot 2023-11-29 081826

Many thanks in advance for your suggestions.

Best,
Keiji

"The experiment failed to load." in twoSoundsWithSOA.html

Hi, thank you for the nice project.

In my environment(macOS Catalina version 10.15.6, Mac Mini(2018), Chrome Version 84.0.4147.105 (Official Build) (64-bit)), the demo of twoSoundsWithSOA.html did not work correctly with the error of "The experiment failed to load."

and this error is fixed when I added

use_webaudio: false,

in jsPsych.init().

Wrong X,Y coordinates for gabor stimuli

Hello and thank you for developing this amazing plugin.
I am using a macbook with google chrome. I noticed a bug when trying to plot a gabor stimulus in the center of the screen.
I haven't figured out why, but it seems that gabor stimuli cannot be plotted at the center of the screen using the usual parameters.

    const gabor1 = {
        obj_type: 'gabor',
        origin_center: true,
        tilt: 0,
        sf: 0,
        phase: 90,
        width: 300,
        sc: 20,
        contrast: 10,
        startX: 0,
        startY: 0,
    }

Instead this code results in the stimulus being plotted at the center of the top-right quadrant (it is as if the real coordinates were halved). I do not encounter this issue with other stimuli (e.g. circles).
This is the only code that fixed it for me

const jsPsych = initJsPsych({
        on_finish: function() {
            jsPsych.data.displayData();
        }
    })

    var w = window.innerWidth;
    var h = window.innerHeight;
    const gabor1 = {
        obj_type: 'gabor',
        origin_center: true,
        tilt: 0,
        sf: 0,
        phase: 90,
        width: 300,
        sc: 20,
        contrast: 10,
        startX: w / 2,
        startY: h / 2,
    }

    const trial = {
        type: jsPsychPsychophysics,
        stimuli: [gabor1],
    }

    jsPsych.run([trial])

It would be nice if this could be fixed in order to work similarly to other type of stimuli (like circles) for which I do not encounter this issue.
Thanks a lot !

trouble importing npm plugin

Hello!

Thank you for the psycho-physics plugin on npm, I have followed the according closed github issue.

I am also using JsPsych Builder and I have tried to install the plugin (via https://www.npmjs.com/package/@kurokida/jspsych-psychophysics?activeTab=code) but I am facing issues with the import. When trying to install it, it only creates a "config" folder in my node-modules folder but there is no jspsych-psychophysics plugin.

I was wondering if anyone has faced and solved a similar issue?

Thanks in advance!

change line angle based on the mouse position

Hello,

I'm new to javascript and have a question regarding the line object.
Is it possible to change the angle of a line depending on the mouse position on the screen? I'd ask my participants to report the stimulus orientation by changing the orientation of the reference bar.

Below is the sample code I've written.

<script> // create timeline var timeline = []; var make_response = { type: 'psychophysics', stimuli: [ { obj_type: 'circle', startX: 'center', startY: 'center', radius: 150, line_color: 'white', line_width: 5, }, // rim { obj_type: 'line', line_length: 300, line_color: 'white', line_width: 5, angle: 135, // ------------- can this be changed based on the mouse position? //origin_center: true, } // reference bar ], response_type: 'mouse', } timeline.push(make_response); /*var get_mouse = function (event){ var x = event.screenX; var y = event.screenY; var mouse_angle = Math.floor((Math.atan2(y, x)*180/Math.PI + 360)%360); // horizontal (rightward) = 0 deg and CW increment }; }; document.addEventListener('mousemove', get_mouse); */ /* start the experiment */ jsPsych.init({ timeline: timeline, on_finish: function(){jsPsych.data.displayData();} }); </script>

I wrote "get_mouse" function (commented-out) but I don't know how to implement this to change the "angle" of the line object (and I'm not even so sure if this function is the right one to use). It'd be very appreciated if you could give me some advice on this.

Thank you.

text positioning

when setting the text position, if I try to move the text vertically the parameter startY:200, only works if I also provide startX:0,
If startX is omitted, then startY:200, doesn't work anymore

Image Padding from Center?

Thank you for your excellent plugin, Kuroki-san.

I'm trying to display two images side by side and centered on the screen. To prevent overlap, I have imagined that I would need to generate the two images at the center of the screen, plus or minus a number of pixels. It seems I could do this by setting startX to the result of a function like the following:

startX: function() {
return jsPsych.currentTrial().centerX - 200
}

However, whenever I try to modify centerX as shown above, the image fails to load entirely. I'm a bit confused, because if I run the following code in my browser console during the image response part of my experiment, I can get the number I expect:

offset = jsPsych.currentTrial().centerX - 100

I'm only a novice in javascript, so it's quite possible I'm making a silly mistake. I would greatly appreciate any advice on how to get the images to display as I am intending.

Laptop and mobile phone compatibility

Hello @kurokida,

Thank you very much for your plugin - it is very useful!

I am using jspsych-psychophysics2.js for an online experiment, and was wondering if there is a way to make it compatible with both laptop and mobile phones? So far I’ve programmed it using keyboard responses, but that doesn’t work on mobile phones. Is it possible to make the experiment work on both a laptop and a mobile phone (e.g. by using keyboard response on a laptop and touch screen response on a mobile phone)? If I use button response, I imagine it would be clicking a button with the mouse on a laptop and touching it on a mobile phone?

I am collecting accuracy and reaction time data.

Thank you very much!

Kind regards,
Jessica

Limit clickable position

Hello,
Thank you for providing such a helpful plugin!

I'm trying to create an experiment that asks participants to click on the line to mark the position.
Is there any way to limit the area of the mouse click to go to the next trial? I'm trying to make participants to click on the line instead of random position on the screen. I used a loop like this.

` var pretrial = {
type: 'psychophysics',
stimuli: [line_main, line_lower, line_upper],
canvas_width: screenwidth,
canvas_height: screenheight,
response_type: 'mouse'
};

var repeat_pretrial = {
    timeline: [pretrial],
    loop_function: function() {
        var last_button_x = jsPsych.data.getLastTrialData().values()[0].click_x;
        var last_button_y = jsPsych.data.getLastTrialData().values()[0].click_y;
        if (last_button_x < button_position_x-linewidth || last_button_x > button_position_x+linewidth 
         || last_button_y < button_position_y-linewidth || last_button_y > button_position_y+linewidth) {
             return true;
         } else {
             return false
         }
    }
};
timeline.push(repeat_pretrial); `

Even though it works, I was wondering if there is a better way to do this.

Define sequence of stimulus and indicate duration in both ms and frames

Hi, I have a scenario in which I need to specify a sequence of stimulus and then finish the trial. It seems to me that psychophysics' stimulus are meant to be independent but maybe there is some way of doing this.

My scenario is analogous to the following timeline:

  • show a cross for 500 ms
  • empty the screen for 3 frames
  • show again a cross for 500 ms
  • then end the trial without waiting for a response from the user

Two timing issues appears when I try to implement this.
On one hand, I don't find a way to specify when the second cross should start to be shown. I would like to define stimulus times using both ms and frames (~ start time = 500 ms + 3 frames) but I have to choose one or the other.
On the other hand, neither do I see how to correctly finish the trial after 1000 ms and 3 frames. I can use response_ends_trial = false to indicate I don't expect a response from the user, but then I have no way of indicating the total time. Doing trial_duration = 1000 ms + 3 frames would be ideal but I'm guessing that could conflict with JSPsych in some way.

In the real case scenario we chose to define times in milliseconds so I'm opening this more out of curiosity than anything else.
Thanks, Francisco.

Screen pixel

Hello!

I'm using Mac Pro 13.3-inch with 2560x1600 and I've set canvas width as 1600px. Even though 1600px smaller than screen resolution, it wouldn't fit into my screen. I've heard somewhere that it is because pixels are too small on Mac (jspsych/jsPsych#1030). I also need to record the position of mouse click. Is there any way I can fit 1600px canvas into a screen using the actual resolution of my screen?

HTML buttons and psychophysics

Hello,
I was wondering if I could also use HTML buttons along with psychophysics within a trial? I'm using the HTML buttons with pictures on them as I'm making a study designed for children. I would like to use your plug-in so that images and sound would play at the same time during a trial (as if someone is reading them a story book) and then children can respond by clicking the buttons.

Any help would be greatly appreciated,
Antoinette Dawn Trott :)

How to call a function to draw a stimulus using the 'manual' property?

I have been trying to use the 'manual' object property to draw grating stimulus. I have written a function to draw the stimulus using drawFunc. However, I want to change one input parameter i.e. level of contrast using context.filter, in every trial. I would like to define the function and input parameters outside the stimulus variable and just call the function that draws the patches by giving the relevant parameters. However, that does not seem to work. I am forced to define the function everytime. Is there anyway to solve this?

// This is what I have to do now. I write the drawFunc on every iteration of defining the left gabor.
var Left0 = {
obj_type: 'manual', // means a manual drawing
startX: 550, // location in the canvas
startY: 325,
endX: 700,
endY: 325,
width: 300, // of the rectangle
height: 200,
horiz_pix_sec: 30,
show_start_time: 0,
motion_start_time: 2000,
drawFunc() {
context = jsPsych.currentTrial().context;
var pos = 0;
const gradLength = 100;
const my_gradient = context.createLinearGradient(400, 0, 600, 0);
const bands = 10;
const colors = ["#000", "#FFF"];
const stops = bands * colors.length;
while (pos <= stops) {
my_gradient.addColorStop(pos / stops, colors[pos % colors.length]);
pos++;
}
context.filter = 'contrast('+ CL1 +')';
context.fillStyle = my_gradient;
context.fillRect(500,325,gradLength,gradLength);
context.stroke();
}
};

//Instead I would like to just define the function once like this.
function drawFunc (x1, y1, x2, y2, CL1, x,y) {
context = jsPsych.currentTrial().context;
var pos = 0;
const gradLength = 100;
const my_gradient = context.createLinearGradient(x1, y1, x2, y2);
const bands = 10;
const colors = ["#000", "#FFF"];
const stops = bands * colors.length;
while (pos <= stops) {
my_gradient.addColorStop(pos / stops, colors[pos % colors.length]);
pos++;
}
context.filter = 'contrast('+ CL1 +')';
context.fillStyle = my_gradient;
context.fillRect(x,y,gradLength,gradLength);
context.stroke();
}

//And then call it later
var Left0 = {
obj_type: 'manual', // means a rectangle
startX: 550, // location in the canvas
startY: 325,
endX: 700,
endY: 325,
width: 300, // of the rectangle
height: 200,
horiz_pix_sec: 30,
show_start_time: 0,
motion_start_time: 2000,
drawFunc: drawFunc(400, 0, 600, 0, 0.5, 500, 325) // calling the gabor function from above and providing input parameters.
};

Please help me resolve this issue.

Change image interactively

Hi Kurokida!
I'm trying to achieve that when you press uparrow or downarrow, the image presented will be changed. For this I'm using the same logic as in keyboard_event.html demo, only replacing the circle_obj with my image object. This part of script looks like this.

    var theImage = {
        obj_type: 'image',
        file: 'stimuli/Front/Fe_Front_45L.png',
        horiz_pix_sec: 0,
        show_start_time: 0,
        startX: 'center',
        startY: 'center',
    }

    const adjust= {
        type: 'psychophysics',
        canvas_height: 500,
        prompt: '<p>Pressing the ArrowUp/ArrowDown key to adjust<br>Press the space key to finish the program.</p>',
        stimuli: [theImage], // These can be referenced using the jsPsych.currentTrial().stimuli array.
        response_type: 'key',
        choices: [' '],
        key_down_func: function(event){ 
            if (event.key === 'ArrowUp'){
                theang = 54;
            } else if (event.key === 'ArrowDown'){
                theang = 36;
            }

            jsPsych.currentTrial().stim_array[0].file = "stimuli/Front/Fe" + "_" + "Front" + "_" + theang + "L" + ".png"
        },
    }

However, this doesn't change the image presented on the screen, although this works well for other properties of other object, e.g. angle of a line object. Also I confirmed that, the .file property of the theImage object did change after I press the key, i.e. if I press Uparrow and then run jsPsych.currentTrial().stim_array[0].file, I will get 'stimuli/Front/Fe_Front_54L.png', rather than the previous 'stimuli/Front/Fe_Front_45L.png'. It's just the .file property didn't update the image presented on the screen.

Do you have idea why this happens? Please let me know if you need more information!
Thanks so much!
Qiu

"trial_ends_after_show_end_time" parameter

I'm looking for a way to end a trial when "show_end_time" is reached.
It's appropriate to use the parameter "trial_duration" (trial_duration=show_end_time)?
Or if the onset of the visual stimulus lags some ms it will be cut off by the end of the trial("trial_duration")?

Meaning of avg_frame_rate

The frame rate for a 60Hz monitor is about 16.6s. What does mean when the avg_frame_rate is about (for example) 20ms?

Sound & Image & Webgazer experiment

Hello,

Thank you for making this plug-in available. It's extremely helpful for sound & image experiments with jsPsych.
I hope to also make use of webgazer for eye-tracking, which has been added as an extension in release 6.3

To make use of the webgazer extension I need to call the jspsych.js file from the main repository. Which then I think means that some jspsych-psychophysics functions become broken. So for instance image display is fine, but audio play is not. I get the error message: "this.audio.play is not a function"

Your demo twoSoundsWithSOA.html still works fine for me, which is why I think it's the change of jspsych.js file which causes the problem. Does that sound right to you? If so, do you think there's something I can do about it?

many thanks in advance, Andrew

Coordinate problem about simultaneously using "key" and "button" response type

Hi Kurokida!
I encounter a problem about precise coordinates when simultaneously using the "key" & "button" response_type. The problem is, although the X&Y positions of my fixation are identical across trials of keyboard and button, the center of my fixation would slightly lift up when the response type was "button", compared with the "key" response type. I don' know why and how to solve the problem (perhaps a bug?). The temporary solution I thought of is creating invisible buttons on fixation trial and all the other trials. But I still want to know how to solve the coordinate problem when using both the "key" and "button" type.

Anyway, jspsych-psychophysics plugin is really a powerful and useful plugin. Thanks for providing such a tool!

Demo "keyboard_event.html" - event.key === 'space' doesn't seem to work

(Thanks in advance)
I'm trying to use the keyboard event handler to record the duration of the keypress of "space".
My idea is very simple (here a explanatory piece of code):

key_down_func: function(event){
  if (event.key === 'g' && one_press){
    var startTime = Date.now();
    jsPsych.data.addProperties({press: startTime});
    one_press=false;
    console.log(keycode);
  }

},
key_up_func: function(event){
  if (event.key === 'g'){
      var endTime = Date.now();
      jsPsych.data.addProperties({release: endTime});
      one_press=true;
  }

The problem is that if I write
event.key==='space'
it doesnt work. And i try a lot of variations.
Here the demo "keyboard_event.html" with the same change (and it doesn't work too)

<!DOCTYPE html>
<html>
    <head>
      <script src="../jspsych.js"></script>
      <script src="../jspsych-psychophysics.js"></script>
      <link href="../css/jspsych.css" rel="stylesheet" type="text/css"></link>
    </head>
    <body></body>
    <script>
      // This file demonstrates how to specify the keyboard-event functions.

      let current_color = 0;

      var circle_obj = {
          obj_type: 'circle',
          startX: 'center',
          startY: 'center',
          radius: 150,
          line_color: 'white',
          fill_color: 'black',
          line_width: 5,
      };

      const trial = {
          type: 'psychophysics',
          canvas_height: 500,
          prompt: '<p>Pressing the space/ArrowDown key, the color of the circle will change. <br>Press the a key to finish the program.</p>',
          stimuli: [circle_obj], // These can be referenced using the jsPsych.currentTrial().stimuli array.
          response_type: 'key',
          choices: ['a'],
          key_down_func: function(event){ // The key_up_func is also available. In that case, the color of the circle changes when you release the key.
            if (event.key === 'ArrowDown'){
              current_color += 10;
              if (current_color > 255) current_color = 255;
            } else if (event.key === 'space'){
              current_color -= 10;
              if (current_color < 0) current_color = 0;
            }

            jsPsych.currentTrial().stim_array[0].fill_color = `rgb(${current_color}, ${current_color}, ${current_color})`;
          },
      }

      /* start the experiment */
      jsPsych.init({
        timeline: [trial],
        on_finish: function(){jsPsych.data.displayData();}
      });
  </script>
</html>

Pre-load stimuli

Hello, I just posted the same enquiry to JsPsych Github page but let me ask the same question here.

I think a normal protocol to load stimuli is to give a path to stimuli which are stored in a local machine. I just wonder if there is any approach to load stimuli which are stored in the website (as if we download packages on Github from command window) or some other local machine using IP address. The problem is that we want to keep our stimuli of image files in some place other than a local PC (which is actually data security system in our institution) and get access to there by some way.
Thanks as always.

Keiji

Change_attr

Hi,

I'm having trouble with the "change_attr" property. I would like to provide feedback, such that a check mark is shown when the answer is correct and an X mark is shown when the answer is incorrect. I also want to provide the correct sound and picture at the same time. Everything is working except that when I get a correct answer, I see an X mark instead of a check mark. I think this line is incorrect but I don't know how to correct it: stim.file = jsPsych.timelineVariable('crochet'). Bellow is the full script for this variable.

Thanks for your help!

Catherine

	var retroaction = {
  		timeline: [
  			{
  				type: 'psychophysics',
				stimuli: [
					{
						obj_type: 'sound',
						file: jsPsych.timelineVariable('phrase')
					},
					{
						obj_type: 'image',
						file: jsPsych.timelineVariable('bonne_reponse'),
						startX: 625
					},
					{
						obj_type: 'image',
						file: jsPsych.timelineVariable('x'),
						startX: 200,
						change_attr: function(stim) {
                			if (jsPsych.data.getLastTrialData().values()[0].accuracy == true) {
								stim.file = jsPsych.timelineVariable('crochet')
							}
						}
					},
				],
 				background_color: "FFFFFF",
 				choices: jsPsych.NO_KEYS,
 				trial_duration: 4000
				
			}
        ]
	}

Multiple and diverse text entries showing at the same time

Hello,
I am using the psychophysics plug in in order to show two texts at the same time but would like to vary the text in each trial, choosing from a list of possibilities. For the moment I tried using the jsPsych.timetableVariable function but the plug in cannot fetch the text.

Cattura

The error message is "you have to specify the content of texts". Is this possible with this plug in?
Thank you, I am really new to this and appreciate any help
Best,
Gaia

npm for the plugin?

I am using jspsych-builder, which I think makes the process of programming experiments with jspsych much more flexible and simple, and I would like to use this plugin in integration with jspsych-builder. The fundamental problem is that, as far as I know, plugins have to be installed via npm. Have you thought about converting this package into a package so that it is possible to use it via npm?

canvas height and jspsych-content mismatch

Hello @kurokida.

I have a problem with the size of the canvas. Apparently, the canvas size is consistently 8 pixels smaller in height than jspsych-content and jspsych-content-wraper. This results in a white strip at the bottom of the screen when doing the experiment in fullscreen, and the scroll bar being activated when not.

I have checked that it has nothing to do with any kind of margin or padding, and when I manually modify the canvas size, that 8 pixels difference is maintained. Any idea what can happen and how to fix it?

I attach an image of the problem

Problem

Thanks and sorry for the inconvenient.

How to record record the simultaneous pressing of two keys as response?

Hello,
first of all, thank you for sharing your wonderful work.
Would it be possible to record a simultaneous pressing of two keys (key combination)?
For example, I would like to have 3 possible answers to a trial:
left arrow, right arrow, both arrows simultaneously. Is there a way?

Concurrent presentation of images and sounds

Thanks for this wonderful toolbox!

I am using jsPsych 6.3.1 alongside jspsychophysics 2.3.4 to present images together with sounds. Particularly, the sound stays on as long as an image (2 seconds) on screen. After that, a mask and a probe image follow.
Everything works well on a local server, but when I push my experiment online on pavlovia I get the following error:

image

It is worth noting that this error occurs randomly, causing the image concurrent to the sound to freeze. Also, this error does not always occur, in some cases the script runs just fine ! This led me to think that may be something on the server side (pavlovia), but I thought I'd ask here as well.

I am not sure I fully understand the nature of this error. On my side I tried several times to change the audio files (thinking that those I was using were somewhat corrupted), to compress them from wav to mp3, and to rename them. But it seems it does not relate to my coding.

Thanks for any help you could provide.

End the visual stimuli by key response, but make the auditory stimuli keep playing

Hi @kurokida! I am trying to create a cross-modal lexical decision task and hosting it on cognition.run. In each trial, the participants will hear a sentence (auditory stimulus). Somewhere in the middle of the sentences (set up to be aligned with the offset of specific target words), a string of letter will pop up on screen for them to make lexical decisions (visual stimulus). It is really nice to use jspsych-psychophysics to control the SOA between the two stimuli.

However, as my title suggested, I wanted to end the visual stimuli when participants make lexical decisions responses by keyboard, but not to terminate the auditory sentences as I wanted them to listen to the rest of the sentences.

For now, when I make a keyboard response, the whole trial will be ended and proceed to the next trial. I've tried to set "response_ends_trial" to false for auditory stimuli and to true for visual stimuli, but it was not working. Wondering if there's any way to set up these things using parameters in jspsych-psychophysics.

Here's my current code:

/* initialize jsPsych */
const jsPsych = initJsPsych({
    default_iti: 1000,
    on_finish: function() {
        jsPsych.data.displayData();
    }
})
console.log(`jsPsych Version ${jsPsych.version()}`)


var timeline = [];

var welcome = {
  type: jsPsychHtmlKeyboardResponse,
  stimulus: "Welcome to the experiment. Press any key to begin."
};
timeline.push(welcome);

const audioStimulus = {
  type: jsPsychAudioKeyboardResponse,
  stimulus: function(){
    return `${jsPsych.timelineVariable('file', true)}`
  },
  choices: "NO_KEYS",
  response_ends_trial: false,
}


const preload = {
    type: jsPsychPreload,
    audio: audioStimulus,
}    


const token = {
    timeline: [
        {
            type: jsPsychPsychophysics,
            response_start_time: function(){
              return `${jsPsych.timelineVariable('offset_time', true)}`
            }, // To prevent participants from responding before the visual target are presented
            trial_duration: function(){
              return `${jsPsych.timelineVariable('file_dur', true) + 2000}` 
            },
            stimuli: [
                {
                    obj_type: 'sound',
                    file: function(){
                      return `${jsPsych.timelineVariable('file', true)}`
                    },
                    show_start_time: 0, // from the trial start (ms),
                    choices: "NO_KEYS",
                    response_ends_trial: false
                },
                {
                    obj_type: 'text',
                    content: function(){
                      return `${jsPsych.timelineVariable('test_word', true)}`
                    },
                    show_start_time: function(){
                      return `${jsPsych.timelineVariable('offset_time', true)}`
                    }, // from the trial start (ms)
                    choices: ['s', 'l'], // The participant can respond to the stimuli using the 'y' or 'n' key.
                    response_ends_trial: true
                },
            ],
            // choices: ['s', 'l'], // The participant can respond to the stimuli using the 'y' or 'n' key.
            prompt: 'Press the s or l key to respond.',
            canvas_height: 500
        },
    ],
    background_color: '#FFFFFF',
    timeline_variables: stimuli_list,
    randomize_order: true
}



timeline.push(token)


/* start the experiment */
jsPsych.run(timeline);

Thank you very much!

Precise timing and different screen refresh rates

Thanks for providing a phenomenal plugin!

I'm using the psychophysics plugin in research and have a few questions about the plugin and paper:

  1. I assume that the monitors you have tested on are 60Hz, in which case a frame should be 16.67ms (as stated in your paper). I would therefore expect display time measurements to come in multiples of 16.67. Is this correct?

  2. From Table 4 in your paper the 20ms condition gives a -13ms deviation from the intended 20ms display time. From the Histograms on OSF for the ProBook Chrome with plugin, we see that the average display time is about 7ms. This could mean that for about half of the trials no frames were displayed. But the histogram shows that almost all measurements were between 5 and 10ms. How can the stimulus be displayed for less than a frame? and what does it mean?

  3. Similarly, it seems that measured display times are not in steps of 16.67ms also for longer intended display times. Why is this?

  4. Monitors with higher refresh rates (e.g. 120Hz and 144Hz) are becoming more common. This makes it tricky to base the stimulus presentation on frames. What is the recommended way to deal with this? (the browser-check plugin for jsPsych does not give accurate refresh rates). I could imagine making a calibration trial that measures the avg_frame_time and calculates the screen refresh rate, and then use show_end_frame instead of show_end_time. Do you have something like this already?

  5. I need precise display times for 50ms (3 frames on 60Hz). Would you advice to set the show_end_time to e.g. 53ms to avoid getting only 2 frames in 60Hz and 4 frames in 144Hz?

  6. Getting the avg_frame_time is very useful. However, would it also be possible to retrieve the exact number of frames that each stimulus object has been displayed for? Then we would have a way to control what our participants have actually seen.

Thanks,
T

compatibility with pavlovia

Having difficulty running my code on Pavlovia (https://pavlovia.org/). Pavlovia currently runs on jsPysch 7.1.2 and will run its respective trials but not the psychophysic trials. Here are the plugins I am using currently as instructed by https://discourse.psychopy.org/t/does-this-platform-support-jspsych-v7/28678.

<script src="https://chancejs.com/chance.min.js"></script>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="jspsych-psychophysics.js"></script>
<script src="lib/vendors/jspsych-7.1.2/jspsych.js"></script>
<script src="lib/vendors/jspsych-7.1.2/plugin-html-button-response.js"></script>
<script src="lib/vendors/jspsych-7.1.2/plugin-survey-multi-choice.js"></script>
<script src="lib/vendors/jspsych-7.1.2/plugin-preload.js"></script>
<link rel="stylesheet" href="lib/vendors/jspsych-7.1.2/jspsych.css">
<script type="text/javascript" src="lib/jspsych-7-pavlovia-2022.1.1.js"></script> 

Please advise, thank you in advance!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.