removing dev folder from master branch. see branch plugin-dev-old for recovery.

This commit is contained in:
Josh de Leeuw 2014-05-15 14:48:40 -04:00
parent ab6c105dd1
commit 3f25eac294
13 changed files with 0 additions and 2339 deletions

View File

@ -1,174 +0,0 @@
(function( $ ) {
jsPsych.active_match = (function(){
var plugin = {};
plugin.create = function(params) {
stims = params["stimuli"];
trials = new Array(stims.length);
for(var i = 0; i < trials.length; i++)
{
trials[i] = {};
trials[i]["type"] = "active_match";
trials[i]["target_idx"] = params["target_idx"][i];
trials[i]["start_idx"] = params["start_idx"][i];
trials[i]["stimuli"] = params["stimuli"][i];
trials[i]["timing"] = params["timing"];
trials[i]["key_dec"] = params["key_dec"];
trials[i]["key_inc"] = params["key_inc"];
if(params["prompt"] != undefined){
trials[i]["prompt"] = params["prompt"];
}
if(params["data"]!=undefined){
trials[i]["data"] = params["data"][i];
}
}
return trials;
}
// data to keep track of
var responses = [];
var last_response_time = 0;
var start_time = 0;
var direction_changes = 0;
var last_response = -1;
plugin.trial = function(display_element, block, trial, part)
{
switch(part){
case 1:
// reset response variables
responses = [];
last_response_time = 0;
start_time = 0;
direction_changes = 0;
last_response = -1;
// starting new trial
start_time = (new Date()).getTime();
last_response_time = start_time;
current_idx = trial.start_idx;
// show target image
display_element.append($('<img>', {
"src": trial.stimuli[trial.target_idx],
"class": '',
"id": 'am_target'
}));
// show manipulate image
display_element.append($('<img>', {
"src": trial.stimuli[trial.start_idx],
"class": '',
"id": 'am_manipulate'
}));
// append a div for showing messages
display_element.append($('<div>', {
"id": 'am_message_box'
}));
if(trial.prompt)
{
display_element.append(trial.prompt);
}
// add function on keypress to control manipulate image
// pressing key_dec will move the index down
// pressing key_inc will move the index up
var resp_func = function(e) {
var change = 0;
var valid_response = false;
if(e.which == trial.key_dec)
{
change = -1;
valid_response = true;
} else if (e.which == trial.key_inc)
{
change = 1;
valid_response = true;
}
if(valid_response){
var resp_time = (new Date()).getTime();
var response = {"key": e.which, "rt": (resp_time-last_response_time)};
responses.push(response);
if(e.which != last_response && last_response != -1)
{
direction_changes++;
}
last_response = e.which;
last_response_time = resp_time;
var next_idx = current_idx + change;
if(next_idx < 0) {
// can't do this
if($('#am_message_box').children().length == 0)
{
$('#am_message_box').append("<p id='prompt'>Minimum value reached. Go the other direction.</p>");
}
next_idx = 0;
} else if(next_idx == trial.stimuli.length) {
// can't do this
if($('#am_message_box').children().length == 0)
{
$('#am_message_box').append("<p id='prompt'>Maximum value reached. Go the other direction.</p>");
}
next_idx = current_idx;
} else {
// update current_idx
current_idx = next_idx;
$("#am_message_box").html('');
// change the image
$("#am_manipulate").attr("src",trial.stimuli[current_idx]);
}
if(current_idx == trial.target_idx)
{
// unbind response function to prevent further change
$(document).unbind('keyup',resp_func);
// match!
plugin.trial(display_element, block, trial, part + 1);
}
}
}
$(document).keyup(resp_func);
break;
case 2:
$("#am_target").addClass('matched');
$("#am_manipulate").addClass('matched');
var key_responses_string = "";
var rt_responses_string = "";
for(var i=0;i<responses.length; i++)
{
key_responses_string = key_responses_string + responses[i].key +",";
rt_responses_string = rt_responses_string + responses[i].rt +",";
}
var trial_data = {"key_responses": key_responses_string, "rt_responses": rt_responses_string, "num_responses": responses.length, "direction_changes": direction_changes, "start_idx":trial.start_idx, "target_idx": trial.target_idx};
block.data[block.trial_idx] = $.extend({},trial_data,trial.data);
setTimeout(function(){plugin.trial(display_element, block, trial, part + 1);}, trial.timing[1]);
break;
case 3:
display_element.html('');
setTimeout(function(){block.next();}, trial.timing[0]);
break;
}
}
return plugin;
})();
})(jQuery);

View File

@ -1,355 +0,0 @@
/* jspsych-adaptive-category-train.js
* Josh de Leeuw, Nov. 2012
*
* Train subjects on a category task adaptively.
* Stimuli are presented in blocks, and after a particular stimulus has been identified correctly in X
* consecutive blocks, it is removed from the training list. Training ends after all stimuli have been
* correctly identified in X consecutive blocks.
*
*/
(function($) {
jsPsych.adaptive_category_train = (function() {
var plugin = {};
plugin.create = function(params) {
trials = []; // everything is a single trial, since it is unknown how many presentations it will take.
trials[0] = {};
trials[0].type = "adaptive_category_train";
trials[0].items = params["items"]; // array of all the stimuli to learn
trials[0].correct_key = params["correct_key"]; // array of all the correct key responses
trials[0].text_answer = params["text_answer"]; // the labels of the category members
trials[0].choices = params["choices"]; // valid key responses
trials[0].correct_text = params["correct_text"]; // feedback text for correct answers.
trials[0].incorrect_text = params["incorrect_text"]; // feedback text for incorrect answers
trials[0].consecutive_correct_min = params["consecutive_correct_min"]; // how many times they have to get the correct answer in a row for a stim.
trials[0].min_percent_correct = params["min_percent_correct"] || 60; // percent correct needed to have adaptive training kick in
trials[0].min_items_per_block = params["min_items_per_block"] || 5; // when remaining items is less than this #, completed items are added back in.
trials[0].stop_training_criteria = params["stop_training_criteria"] || -1; // after this number of rounds below min_percent_correct, stop training. -1 = continue indefinitely.
// timing
trials[0].timing_display_feedback = params["timing_display_feedback"] || 1500; // default 1000ms
trials[0].timing_post_trial = params["timing_post_trial"] || 1000; // default 1000ms between trials.
// display progress ?
trials[0].show_progress = params["show_progress"] || true;
// optional parameters
if(params["data"]!=undefined){
trials[0].data = params["data"];
}
if(params["prompt"]!=undefined){
trials[0].prompt = params["prompt"];
}
return trials;
}
plugin.trial = function(display_element, block, trial, part)
{
// create a tally for each item
var all_items = [];
for(var i=0; i<trial.items.length; i++)
{
all_items.push({
"a_path": trial.items[i],
"consecutive_correct_responses": 0,
"correct_key": trial.correct_key[i],
"text_answer": trial.text_answer[i],
"choices":trial.choices,
"correct_text": trial.correct_text,
"incorrect_text": trial.incorrect_text,
"min_percent_correct": trial.min_percent_correct,
"timing_post_trial": trial.timing_post_trial,
"timing_display_feedback": trial.timing_display_feedback,
"prompt": trial.prompt,
"complete": false
});
};
// create the training controller
var controller = new TrainingControl(all_items, trial.consecutive_correct_min, trial.min_items_per_block,
trial.min_percent_correct, display_element, block, trial.show_progress, trial.timing_post_trial,
trial.stop_training_criteria);
controller.next_round(); // when this finishes, block.next() is called.
}
function TrainingControl(items, min_correct, min_per_block, min_percent_correct, display_element, block, show_progress, timing_post_trial, stop_criteria){
this.total_items = items.length;
this.remaining_items = items;
this.timing_post_trial = timing_post_trial;
this.complete_items = [];
this.curr_block = 0;
this.blocks_under_thresh = 0;
this.next_round = function() {
if(stop_criteria > -1 && this.blocks_under_thresh >=stop_criteria)
{
// end training due to failure to learn
block.next();
} else {
if(this.remaining_items.length > 0)
{
if(this.remaining_items.length < min_per_block)
{
shuffle(this.complete_items);
for( var i = 0; this.remaining_items.length < min_per_block; i++)
{
this.remaining_items.push(this.complete_items[i]);
}
}
// present remaining items in random order
shuffle(this.remaining_items);
var iterator = new TrialIterator(display_element, this.remaining_items, this, block, this.curr_block);
this.curr_block++;
var updated_trials = iterator.next(); // when this finishes, all trials are complete.
// updated_trials will have the updated consecutive correct responses
} else {
// end training
block.next();
}
}
}
this.round_complete = function(trials)
{
// check items for threshold and remove items where consecutive responses has been reached
var cont_trials = [];
this.remaining_items = trials;
var score_denominator = this.remaining_items.length;
var score_numerator = 0;
for(var i=0; i<this.remaining_items.length; i++)
{
if(this.remaining_items[i].consecutive_correct_responses > 0)
{
score_numerator++;
}
}
var percent_correct = Math.round((score_numerator / score_denominator)*100);
if(percent_correct < min_percent_correct){
this.blocks_under_thresh++;
} else {
this.blocks_under_thresh = 0;
}
for(var i=0; i<this.remaining_items.length; i++)
{
if(this.remaining_items[i].complete == false)
{
if(this.remaining_items[i].consecutive_correct_responses < min_correct)
{
cont_trials.push(this.remaining_items[i]);
} else {
if(percent_correct>=min_percent_correct){
// newly completed item
this.remaining_items[i].complete = true;
this.complete_items.push(this.remaining_items[i]);
} else {
cont_trials.push(this.remaining_items[i]);
}
}
}
}
this.remaining_items = cont_trials;
var remaining_objects = this.remaining_items.length;
var completed_objects = this.total_items - remaining_objects;
if(show_progress)
{
this.display_progress(completed_objects, remaining_objects, score_numerator, score_denominator);
} else {
// call next round
this.next_round();
}
}
this.display_progress = function(completed_objects, remaining_objects, score_numerator, score_denominator, blocks_under_criteria)
{
var completed = '';
var percent_correct = Math.round((score_numerator / score_denominator)*100);
if(percent_correct < min_percent_correct)
{
completed = '<p>You need to categorize at least '+min_percent_correct+'% of the items correctly in each round in order to make progress in training.</p>'
if(stop_criteria > -1) {
var remaining_blocks = stop_criteria - this.blocks_under_thresh;
if(remaining_blocks >= 1){
completed += '<p>If you continue to have an accuracy below '+min_percent_correct+'% for '+remaining_blocks+' more round(s) of training, then training will stop and you will not be eligible for the bonus payment.</p>'
} else {
completed += '<p>Training will now stop because your accuracy was below '+min_percent_correct+'% for '+stop_criteria+' consecutive rounds.</p>'
}
}
} else {
if(remaining_objects == 0)
{
completed = '<p>Congratulations! You have completed training.</p>';
}
else if(completed_objects > 0)
{
completed = '<p>You have correctly categorized '+completed_objects+' item(s) in '+min_correct+' consecutive rounds. You need to correctly categorize '+remaining_objects+
' more item(s) in '+min_correct+' consecutive rounds to complete training. Items that you have correctly identified in '+min_correct+' consecutive rounds will not be shown as frequently.</p>';
}
else
{
completed = '<p>Good job! You need to categorize an item correctly in '+min_correct+' consecutive rounds to finish training for that item. Once you have finished training for all items the next part of the experiment will begin.</p>';
}
}
display_element.html(
'<div id="adaptive_category_progress"><p>You correctly categorized '+percent_correct+'% of the items in that round.</p>'+completed+'<p>Press ENTER to continue.</p></div>'
);
var controller = this;
var key_listener = function(e) {
if(e.which=='13')
{
$(document).unbind('keyup',key_listener); // remove the response function, so that it doesn't get triggered again.
display_element.html(''); // clear the display
setTimeout(function(){controller.next_round();}, this.timing_post_trial); // call block.next() to advance the experiment after a delay.
}
}
$(document).keyup(key_listener);
}
}
function TrialIterator(display_element, trials, controller, block, block_idx){
this.trials = trials;
this.curr_trial = 0;
this.curr_block = block_idx;
this.next = function() {
if(this.curr_trial >= this.trials.length)
{
// call function in the controller
controller.round_complete(trials);
} else {
this.do_trial(this.trials[this.curr_trial], this.curr_trial, this.curr_block);
}
}
this.do_trial = function(trial, t_idx, b_idx)
{
// do the trial!
// show the image
display_element.append($('<img>', {
"src": trial.a_path,
"class": 'cf'
}));
display_element.append(trial.prompt);
startTime = (new Date()).getTime();
// get response
var resp_func = function(e) {
var flag = false;
var correct = false;
if(e.which==trial.correct_key) // correct category
{
flag = true;
correct = true;
}
else
{
// check if the key is any of the options, or if it is an accidental keystroke
for(var i=0;i<trial.choices.length;i++)
{
if(e.which==trial.choices[i])
{
flag = true;
correct = false;
}
}
}
if(flag)
{
// get response time
endTime = (new Date()).getTime();
rt = (endTime-startTime);
// update the consecutive correct responses
if(correct){
trial.consecutive_correct_responses++;
} else {
trial.consecutive_correct_responses = 0;
}
// store data
var trial_data = {"block": b_idx, "trial_idx": t_idx, "rt": rt, "correct": correct, "a_path": trial.a_path, "key_press": e.which, "trial_type":"adaptive_train"}
if(trial.data!="undefined"){
block.data.push($.extend({},trial_data,trial.data));
} else {
block.data.push(trial_data);
}
$(document).unbind('keyup',resp_func);
display_element.html('');
show_feedback(correct, e.data.iterator_object);
}
}
$(document).keyup({"iterator_object":this},resp_func);
// provide feedback
function show_feedback(is_correct, iterator_object){
display_element.append($('<img>', {
"src": trial.a_path,
"class": 'cf'
}));
// give feedback
var atext = "";
if(is_correct)
{
atext = trial.correct_text.replace("&ANS&", trial.text_answer);
} else {
atext = trial.incorrect_text.replace("&ANS&", trial.text_answer);
}
display_element.append(atext);
setTimeout(function(){finish_trial(iterator_object);}, trial.timing_display_feedback);
}
function finish_trial(iterator_object){
display_element.html('');
setTimeout(function(){
iterator_object.curr_trial++;
iterator_object.next();
}, trial.timing_post_trial);
}
}
}
function shuffle(array) {
var tmp, current, top = array.length;
if(top) while(--top) {
current = Math.floor(Math.random() * (top + 1));
tmp = array[current];
array[current] = array[top];
array[top] = tmp;
}
return array;
}
return plugin;
})();
})(jQuery);

View File

@ -1,223 +0,0 @@
(function( $ ) {
jsPsych.ballistic_match = (function(){
var plugin = {};
plugin.create = function(params) {
stims = params["stimuli"];
trials = new Array(stims.length);
for(var i = 0; i < trials.length; i++)
{
trials[i] = {};
trials[i]["type"] = "ballistic_match";
trials[i]["target_idx"] = params["target_idx"][i];
trials[i]["start_idx"] = params["start_idx"][i];
trials[i]["stimuli"] = params["stimuli"][i];
trials[i]["timing"] = params["timing"];
trials[i]["key_dec"] = params["key_dec"];
trials[i]["key_inc"] = params["key_inc"];
trials[i]["animate_frame_time"] = params["animate_frame_time"] || 100;
if(params["prompt"] != undefined){
trials[i]["prompt"] = params["prompt"];
}
if(params["data"]!=undefined){
trials[i]["data"] = params["data"][i];
}
}
return trials;
}
var change = 0; // which direction they indicated the stim should move.
var start_time;
var end_time;
plugin.trial = function(display_element, block, trial, part)
{
switch(part){
case 1:
// starting new trial
start_time = (new Date()).getTime();
change = 0;
// show manipulate image
display_element.append($('<img>', {
"src": trial.stimuli[trial.start_idx],
"class": 'bm_img',
"id": 'bm_manipulate'
}));
// show target image
display_element.append($('<img>', {
"src": trial.stimuli[trial.target_idx],
"class": 'bm_img',
"id": 'bm_target'
}));
if(trial.prompt)
{
display_element.append(trial.prompt);
}
// categorize the image.
var resp_func = function(e) {
var valid_response = false;
if(e.which == trial.key_dec)
{
change = -1;
valid_response = true;
} else if (e.which == trial.key_inc)
{
change = 1;
valid_response = true;
}
if(valid_response){
end_time = (new Date()).getTime();
plugin.trial(display_element,block,trial,part+1);
$(document).unbind('keyup', resp_func);
}
}
$(document).keyup(resp_func);
break;
case 2:
// clear everything
display_element.html('');
setTimeout(function(){plugin.trial(display_element, block, trial, part + 1);}, trial.timing[1]);
break;
case 3:
// draw trajectory
draw_trajectory(display_element,
trial.stimuli[trial.target_idx],
trial.stimuli[trial.start_idx],
trial.target_idx/(trial.stimuli.length-1),
trial.start_idx/(trial.stimuli.length-1));
display_element.append($('<div>',{
"id":"bm_feedback",
}));
if(change>0) {
$("#bm_feedback").html('<p>You said increase.</p>');
} else {
$("#bm_feedback").html('<p>You said decrease.</p>');
}
setTimeout(function(){plugin.trial(display_element, block, trial, part + 1);}, trial.timing[1]*3);
break;
case 4:
var curr_loc = trial.start_idx
animate_interval = setInterval(function(){
// clear everything
display_element.html('');
// draw trajectory
draw_trajectory(display_element,
trial.stimuli[trial.target_idx],
trial.stimuli[curr_loc],
trial.target_idx/(trial.stimuli.length-1),
curr_loc/(trial.stimuli.length-1));
curr_loc += change;
if(curr_loc - change == trial.target_idx || curr_loc < 0 || curr_loc == trial.stimuli.length)
{
clearInterval(animate_interval);
var correct = false;
if(change > 0 && trial.start_idx < trial.target_idx) { correct = true; }
if(change < 0 && trial.start_idx > trial.target_idx) { correct = true; }
display_element.append($('<div>',{
"id":"bm_feedback",
}));
if(correct){
$("#bm_feedback").html('<p>Correct!</p>');
} else {
$("#bm_feedback").html('<p>Wrong.</p>');
}
setTimeout(function(){plugin.trial(display_element, block, trial, part + 1);}, trial.timing[1]*3);
}
}, trial.animate_frame_time);
break;
case 5:
display_element.html('');
var correct = false;
if(change > 0 && trial.start_idx < trial.target_idx) { correct = true; }
if(change < 0 && trial.start_idx > trial.target_idx) { correct = true; }
var trial_data = {"start_idx":trial.start_idx, "target_idx": trial.target_idx, "correct": correct, "rt": (end_time-start_time)};
block.data[block.trial_idx] = $.extend({},trial_data,trial.data);
setTimeout(function(){block.next();}, trial.timing[0]);
break;
}
}
function draw_trajectory(display_element,target_img, moving_img, target_loc_percent, marker_loc_percent)
{
// display the image as it morphs
display_element.append($('<img>',{
"src": moving_img,
"id": "moving_image"
}));
// show the linear trajectory below
display_element.append($('<div>', {
"id": "trajectory"}));
$("#trajectory").append($('<div>', {
"id": "line"}));
// display the images on the trajectory
$("#trajectory").append($('<div>', {
"id": "target_flag"}));
$("#target_flag").append($('<div>', {
"id": "target_dot"}));
$("#target_flag").append($('<div>', {
"id": "target_words"}));
$("#target_words").html("<p>Target Cell</p>");
$("#trajectory").append($('<div>', {
"id": "marker_flag"}));
$("#marker_flag").append($('<div>', {
"id": "marker_dot"}));
$("#marker_flag").append($('<div>', {
"id": "marker_words"}));
$("#marker_words").html("<p>Above Cell</p>");
// label the trajectory line
$("#trajectory").append($('<span>', {
"id": "left_label"}));
$("#trajectory").append($('<span>', {
"id": "right_label"}));
$("#left_label").html("Less Chemical X");
$("#right_label").html("More Chemical X");
// set the location of the flags on the line
var dot_width = parseInt($("#marker_dot").css('width'));
var line_width = parseInt($("#line").css('width'));
var target_flag_left = (line_width- dot_width) * target_loc_percent;
var marker_flag_left = (line_width- dot_width) * marker_loc_percent;
$("#marker_flag").css('left', marker_flag_left);
$("#target_flag").css('left', target_flag_left);
}
return plugin;
})();
})(jQuery);

View File

@ -1,227 +0,0 @@
(function( $ ) {
jsPsych.ballistic_match = (function(){
var plugin = {};
plugin.create = function(params) {
stims = params["stimuli"];
trials = new Array(stims.length);
for(var i = 0; i < trials.length; i++)
{
trials[i] = {};
trials[i]["type"] = "ballistic_match";
trials[i]["target_idx"] = params["target_idx"][i];
trials[i]["start_idx"] = params["start_idx"][i];
trials[i]["stimuli"] = params["stimuli"][i];
trials[i]["timing"] = params["timing"];
trials[i]["key_dec"] = params["key_dec"];
trials[i]["key_inc"] = params["key_inc"];
trials[i]["animate_frame_time"] = params["animate_frame_time"] || 100;
if(params["prompt"] != undefined){
trials[i]["prompt"] = params["prompt"];
}
if(params["data"]!=undefined){
trials[i]["data"] = params["data"][i];
}
}
return trials;
}
var change = 0; // which direction they indicated the stim should move.
var start_time;
var end_time;
plugin.trial = function(display_element, block, trial, part)
{
switch(part){
case 1:
// starting new trial
start_time = (new Date()).getTime();
change = 0;
// show manipulate image
display_element.append($('<img>', {
"src": trial.stimuli[trial.start_idx],
"class": 'bm_img',
"id": 'bm_manipulate'
}));
// show target image
display_element.append($('<img>', {
"src": trial.stimuli[trial.target_idx],
"class": 'bm_img',
"id": 'bm_target'
}));
if(trial.prompt)
{
display_element.append(trial.prompt);
}
// categorize the image.
var resp_func = function(e) {
var valid_response = false;
if(e.which == trial.key_dec)
{
change = -1;
valid_response = true;
} else if (e.which == trial.key_inc)
{
change = 1;
valid_response = true;
}
if(valid_response){
end_time = (new Date()).getTime();
plugin.trial(display_element,block,trial,part+1);
$(document).unbind('keyup', resp_func);
}
}
$(document).keyup(resp_func);
break;
case 2:
// clear everything
display_element.html('');
setTimeout(function(){plugin.trial(display_element, block, trial, part + 1);}, trial.timing[1]);
break;
case 3:
// draw trajectory
draw_trajectory(display_element,
trial.stimuli[trial.target_idx],
trial.stimuli[trial.start_idx],
trial.target_idx/(trial.stimuli.length-1),
trial.start_idx/(trial.stimuli.length-1));
display_element.append($('<div>',{
"id":"bm_feedback",
}));
if(change>0) {
$("#bm_feedback").html('<p>You said increase.</p>');
} else {
$("#bm_feedback").html('<p>You said decrease.</p>');
}
setTimeout(function(){plugin.trial(display_element, block, trial, part + 1);}, trial.timing[1]*3);
break;
case 4:
var curr_loc = trial.start_idx
animate_interval = setInterval(function(){
// clear everything
display_element.html('');
// draw trajectory
draw_trajectory(display_element,
trial.stimuli[trial.target_idx],
trial.stimuli[curr_loc],
trial.target_idx/(trial.stimuli.length-1),
curr_loc/(trial.stimuli.length-1));
curr_loc += change;
if(curr_loc - change == trial.target_idx || curr_loc < 0 || curr_loc == trial.stimuli.length)
{
clearInterval(animate_interval);
var correct = false;
if(change > 0 && trial.start_idx < trial.target_idx) { correct = true; }
if(change < 0 && trial.start_idx > trial.target_idx) { correct = true; }
display_element.append($('<div>',{
"id":"bm_feedback",
}));
if(correct){
$("#bm_feedback").html('<p>Correct!</p>');
} else {
$("#bm_feedback").html('<p>Wrong.</p>');
}
setTimeout(function(){plugin.trial(display_element, block, trial, part + 1);}, trial.timing[1]*3);
}
}, trial.animate_frame_time);
break;
case 5:
display_element.html('');
var correct = false;
if(change > 0 && trial.start_idx < trial.target_idx) { correct = true; }
if(change < 0 && trial.start_idx > trial.target_idx) { correct = true; }
var trial_data = {"start_idx":trial.start_idx, "target_idx": trial.target_idx, "correct": correct, "rt": (end_time-start_time)};
block.data[block.trial_idx] = $.extend({},trial_data,trial.data);
setTimeout(function(){block.next();}, trial.timing[0]);
break;
}
}
function draw_trajectory(display_element,target_img, moving_img, target_loc_percent, moving_loc_percent)
{
display_element.append($('<div>', {
"id": "message_holder"}));
$("#message_holder").append($('<p id="left">Less Chemical X</p>'));
$("#message_holder").append($('<p id="right">More Chemical X</p>'));
$("#message_holder").append($('<img>',{
"src":"img/400arrow.gif",
"id":"arrow"
}));
// display the images on the trajectory
display_element.append($('<div>',{
"id": "bm_trajectory",
"css": {
"position":"relative"
}
}));
$("#bm_trajectory").append($('<img>',{
"src":target_img,
"id": "bm_target",
"css": {
"position":"absolute",
}
}));
var image_width = parseInt($("#bm_target").css('width'));
var image_height = parseInt($("#bm_target").css('height'));
var container_width = parseInt($("#bm_trajectory").css('width'));
var target_left = (container_width - image_width) * target_loc_percent;
var moving_left = (container_width - image_width) * moving_loc_percent;
$("#bm_target").css('left', target_left);
$("#bm_target").css('top', image_height);
$("#bm_trajectory").append($('<img>',{
"src":moving_img,
"id": "bm_moving",
"css": {
"position":"absolute",
"left": moving_left,
"top": 0
}
}));
$("#bm_trajectory").append($(
'<div>',
{
"id": "target_flag",
"css": {
"position":"absolute",
"left": target_left+(image_width/2)-40,
"bottom": "-10px",
"background-color": "#cccccc",
"border": "1px solid #999999",
"width": 80,
"height": 20
}
}
));
$("#target_flag").html('<p>TARGET</p>');
}
return plugin;
})();
})(jQuery);

View File

@ -1,182 +0,0 @@
// timing parameters: [length to show feedback, intertrial gap, optional length to display target]
// if optional length to display target is missing, then target is displayed until subject responds.
//TODO
// option to keep stim on screen during feedback
// way to provide corrective feedback
(function( $ ) {
jsPsych.categorize_multi = (function(){
var plugin = {};
plugin.create = function(params) {
cf_stims = params["stimuli"];
trials = new Array(cf_stims.length);
for(var i = 0; i < trials.length; i++)
{
trials[i] = {};
trials[i]["type"] = "categorize_multi";
trials[i]["a_path"] = cf_stims[i];
trials[i]["choices"] = params["choices"];
trials[i]["answer_idx"] = params["answer_idx"][i];
trials[i]["text_answer"] = params["text_answer"][i];
trials[i]["correct_text"] = params["correct_text"];
trials[i]["incorrect_text"] = params["incorrect_text"];
trials[i]["show_stim_feedback"] = params["show_stim_feedback"] || true;
// timing params
trials[i]["timing_length_of_feedback"] = params["timing_length_of_feedback"] || 2000;
// opt params
if(params["prompt"] != undefined){
trials[i]["prompt"] = params["prompt"];
}
if(params["data"]!=undefined){
trials[i]["data"] = params["data"][i];
}
}
return trials;
}
// to save correct_answers between iterations of trial method...
var correct_answers = [];
plugin.trial = function(display_element, block, trial, part)
{
switch(part){
case 1:
// show image
display_element.append($('<img>', {
"src": trial.a_path,
"class": 'cm'
}));
// hide image if the timing param is set.
if(trial.timing_show_image > 0)
{
setTimeout(function(){
$('.cm').css('visibility', 'hidden');
}, trial.timing_show_image);
}
// show prompt
display_element.append(trial.prompt);
// start recording for RT
startTime = (new Date()).getTime();
// display button choices
// for each SET of choices
for(var i = 0; i<trial.choices.length; i++)
{
// add a DIV
display_element.append($('<div>', {
"id": "cm_"+i
}));
// for each INDIVIDUAL choice
for(var j = 0; j < trial.choices[i].length; j++)
{
// add a RADIO button
$('#cm_'+i).append($('<input>', {
"type": "radio",
"name": "category_"+i,
"value": trial.choices[i][j],
"id": "cat_"+i+"_"+j
}));
$('#cm_'+i).append('<label>'+trial.choices[i][j]+'</label>');
}
}
// add a button to hit when done.
display_element.append($('<button>', {
"type": "button",
"value": "done",
"name": "Next",
"id": "nextBtn",
"html": "Submit Answer"
}));
// add response function to the button.
$('#nextBtn').click(function(){
var correct_overall = true;
var string_answers = "";
correct_answers = [];
for(var i=0; i<trial.answer_idx.length; i++)
{
var corr_choice = trial.answer_idx[i];
if($('#cat_'+i+'_'+corr_choice).is(':checked'))
{
correct_answers.push(true);
string_answers = string_answers + "1";
} else {
correct_answers.push(false);
correct_overall = false;
string_answers = string_answers + "0";
}
}
// measure RT
endTime = (new Date()).getTime();
rt = (endTime-startTime);
// save data
var trial_data = {"rt": rt, "correct": correct_overall, "a_path": trial.a_path, "cat_answers": string_answers}
block.data[block.trial_idx] = $.extend({},trial_data,trial.data);
// clear everything
display_element.html('');
plugin.trial(display_element, block, trial, part + 1);
});
break;
case 2:
// show image
display_element.append($('<img>', {
"src": trial.a_path,
"class": 'cm'
}));
// show prompt
display_element.append(trial.prompt);
// give feedback
var atext = "";
for(var i=0; i<correct_answers.length; i++)
{
// add a DIV
display_element.append($('<div>', {
"id": "cm_"+i
}));
var text_to_add = "";
if(correct_answers[i])
{
text_to_add = trial.correct_text.replace("&ANS&", trial.text_answer[i]);
$('#cm_'+i).addClass('correct');
} else {
text_to_add = trial.incorrect_text.replace("&ANS&", trial.text_answer[i]);
$('#cm_'+i).addClass('incorrect');
}
$('#cm_'+i).append(text_to_add);
}
setTimeout(function(){plugin.trial(display_element, block, trial, part + 1);}, trial.timing_length_of_feedback); // fix timing?
break;
case 3:
display_element.html('');
setTimeout(function(){block.next()},1000);
break;
}
}
return plugin;
})();
})(jQuery);

View File

@ -1,186 +0,0 @@
(function( $ ) {
jsPsych.paint = (function(){
var plugin = {};
// private functions
function colorPixel(ctx, x, y, fresh)
{
ctx.globalCompositeOperation = "destination-out";
ctx.fillStyle = "rgba(0,0,0, 1.0)";
//ctx.fillRect(x,y,10,10);
//ctx.arc(x,y,10,0,Math.Pi*2,true);
//ctx.fill();
ctx.lineWidth = 30;
ctx.lineCap = ctx.lineJoin = 'round';
ctx.strokeStyle = "rgba(0,0,0,1.0)";
if(fresh){
ctx.beginPath();
ctx.moveTo(x+0.01,y);
}
ctx.lineTo(x,y);
ctx.stroke();
}
plugin.create = function(params) {
stims = params["stimuli"];
trials = new Array(stims.length);
for(var i = 0; i < trials.length; i++)
{
trials[i] = {};
trials[i]["type"] = "paint";
trials[i]["a_path"] = stims[i];
trials[i]["height"] = params["height"];
trials[i]["width"] = params["width"];
trials[i]["timing"] = params["timing"];
if(params["data"]!=undefined){
trials[i]["data"] = params["data"][i];
}
if(params["prompt"]!=undefined){
trials[i]["prompt"] = params["prompt"];
}
}
return trials;
}
plugin.trial = function(display_element, block, trial, part)
{
switch(part){
case 1:
p1_time = (new Date()).getTime();
display_element.append($('<div>', {
"id": 'paintbox',
"class": 'paint'}));
$('#paintbox').css({
'position': 'relative',
'width': trial.width,
'height': trial.height});
$('#paintbox').append($('<img>', {
"src": trial.a_path,
"class": 'paint',
"css": {
'width':trial.width,
'height':trial.height,
'position': 'absolute',
'top': '0',
'left': '0',
'z-index': '0'
}
}));
$('#paintbox').append($('<canvas>', {
"id": "paintcanvas",
"class": "paint",
"css": {
'position': 'absolute',
'top': '0',
'left': '0',
'z-index': '1',
'cursor': 'crosshair'
}
}));
$('#paintcanvas').attr('width',trial.width);
$('#paintcanvas').attr('height',trial.height);
var canvas = document.getElementById('paintcanvas');
var ctx = canvas.getContext('2d');
ctx.fillStyle = "rgba(0,0,0,0.8)";
ctx.fillRect(0,0,trial.width,trial.height);
var paint = false;
document.onselectstart = function(){
return false;
}
$('#paintcanvas').mousedown(function(e){
var mouseX = e.pageX - $('#paintbox').offset().left;
var mouseY = e.pageY - $('#paintbox').offset().top;
paint = true;
colorPixel(ctx, mouseX, mouseY, true);
});
$('#paintcanvas').mousemove(function(e){
var mouseX = e.pageX - $('#paintbox').offset().left;
var mouseY = e.pageY - $('#paintbox').offset().top;
if(paint){
colorPixel(ctx, mouseX, mouseY, false);
}
});
$(document).mouseup(function(e){
paint = false;
});
display_element.append($('<button>',{
'id':'done',
'class':'paint'}));
$('#done').html('Done');
$('#done').click(function(){
plugin.trial(display_element,block,trial,part+1);
});
display_element.append($('<button>',{
'id':'reset',
'class':'paint'}));
$('#reset').html('Reset');
$('#reset').click(function(){
ctx.clearRect(0,0,trial.width,trial.height);
ctx.globalCompositeOperation = "source-over";
ctx.fillStyle = "rgba(0,0,0,0.8)";
ctx.fillRect(0,0,trial.width,trial.height);
});
if(trial.prompt){
display_element.append(trial.prompt);
}
break;
case 2:
var canvas = document.getElementById('paintcanvas');
var ctx = canvas.getContext('2d');
var img = ctx.getImageData(0,0,trial.width,trial.height);
var pix = img.data;
var tdata = new Array(trial.width*trial.height);
var data_string = "";
//tdata[0] = new Array();
for(var i=0, j=0, n=pix.length; i<n; i+=4, j++)
{
tdata[j] = (pix[i+3] == 0)
if(pix[i+3] == 0)
{
data_string = data_string+"1";
} else {
data_string = data_string+"0";
}
}
block.data[block.trial_idx] = $.extend({},{"a_path": trial.a_path,"pixels": data_string},trial.data);
display_element.html('');
setTimeout(function(){block.next();}, trial.timing[0]);
break;
}
}
return plugin;
})();
})(jQuery);

View File

@ -1,144 +0,0 @@
// Josh de Leeuw
// Nov. 2012
(function( $ ) {
jsPsych.samedifferentloc = (function(){
var plugin = {};
plugin.create = function(params) {
var stims = params["stimuli"];
trials = new Array(stims.length);
for(var i = 0; i < trials.length; i++)
{
trials[i] = {};
trials[i]["type"] = "samedifferentloc";
trials[i]["a_path"] = sd_stims[i][0];
trials[i]["b_path"] = sd_stims[i][1];
trials[i]["mask_path"] = params["mask_path"];
trials[i]["a_x_offset"] = params["a_x_offset"][i];
trials[i]["a_y_offset"] = params["a_y_offset"][i];
trials[i]["b_x_offset"] = params["b_x_offset"][i];
trials[i]["b_y_offset"] = params["b_y_offset"][i];
trials[i]["answer"] = params["answer"][i];
trials[i]["same_key"] = params["same_key"] || 80;
trials[i]["different_key"] = params["different_key"] || 81;
// timing parameters
trials[i]["timing_first_img"] = params["timing_first_img"] || 1500;
trials[i]["timing_mask"] = params["timing_mask"] || 500;
trials[i]["timing_second_img"] = params["timing_second_img"] || 1000;
trials[i]["timing_fixation"] = params["timing_fixation"] || 3000;
// optional parameters
if(params["prompt"] != undefined){
trials[i]["prompt"] = params["prompt"];
}
if(params["data"]!=undefined){
trials[i]["data"] = params["data"][i];
}
}
return trials;
}
plugin.trial = function(display_element, block, trial, part)
{
switch(part){
case 1:
display_element.append($('<div>', {
"id": 'sdl_img_container',
"css": {
"position": 'relative'
}
}));
$("#sdl_img_container").append($('<img>', {
"src": trial.a_path,
"class": 'sdl',
"css": {
"position": 'absolute',
"top": trial.a_y_offset,
"left": trial.a_x_offset
}
}));
setTimeout(function(){plugin.trial(display_element, block, trial, part + 1);}, trial.timing_first_img);
break;
case 2:
$('.sd1').remove();
$("#sdl_img_container").append($('<img>', {
"src": trial.mask_path,
"class": 'sdl'
}));
setTimeout(function(){plugin.trial(display_element, block, trial, part + 1);}, trial.timing_mask);
break;
case 3:
$('.sd1').remove();
$("#sdl_img_container").append($('<img>', {
"src": trial.b_path,
"class": 'sdl',
"css": {
"position": 'absolute',
"top": trial.b_y_offset,
"left": trial.b_x_offset
}
}));
setTimeout(function(){plugin.trial(display_element, block, trial, part + 1);}, trial.timing_second_img);
break;
case 4:
$('.sd1').remove();
$("#sdl_img_container").append($('<img>', {
"src": trial.fixation_path,
"class": 'sdl'
}));
startTime = (new Date()).getTime();
var correct = false;
var response = false;
var resp_func = function(e) {
var flag = false;
if(e.which==trial.same_key)
{
flag = true;
if(trial.answer == "same") { correct = true; }
} else if(e.which==trial.different_key)
{
flag = true;
if(trial.answer == "different"){ correct = true; }
}
if(flag)
{
endTime = (new Date()).getTime();
rt = (endTime-startTime);
$(document).unbind('keyup',resp_func);
response = true;
}
}
$(document).keyup(resp_func);
var finish_func = function() {
if(!response)
{
rt = -1;
}
var trial_data = {"rt": rt, "correct": correct, "a_path": trial.a_path, "b_path": trial.b_path, "key_press": e.which,
"a_x_loc": trial.a_x_offset,"a_y_loc": trial.a_y_offset,"b_x_loc": trial.b_x_offset, "b_y_loc": trial.b_y_offset };
block.data[block.trial_idx] = $.extend({},trial_data,trial.data);
display_element.html('');
block.next();
}
setTimeout(finish_func, trial.timing_fixation);
break;
}
}
return plugin;
})();
}) (jQuery);

View File

@ -1,248 +0,0 @@
/* jspsych-staircase-categorize.js
* Josh de Leeuw, Sep. 2013
*
*
*
*/
(function($) {
jsPsych.staircase_categorize = (function() {
var plugin = {};
plugin.create = function(params) {
var trials = []; // everything is a single trial, since it is unknown how many presentations it will take.
trials[0] = {};
trials[0].type = "staircase_categorize";
// items structure is four nested arrays. top level array is separate staircases that should be interleaved.
// second level array is difficulty. third arrays are sets of options. inner most array are stimuli of equivalent
// difficulty and category.
trials[0].items = params.items;
// two level nested array. top level is separate staircases.
// second (inner) level is list of key responses in order that stimuli are ordered for third level of items array.
trials[0].choices = params.choices;
trials[0].n_up = params.n_up || 1;
trials[0].n_down = params.n_down || 1;
trials[0].n_turns = params.n_turns || 10;
trials[0].n_turns_average = params.n_turns_average || 6;
// timing
trials[0].timing_post_trial = params.timing_post_trial || 1000; // default 1000ms between trials.
trials[0].timing_item = params.timing_item || 1000;
// optional parameters
if (params.data !== undefined) {
trials[0].data = params.data;
}
if (params.prompt !== undefined) {
trials[0].prompt = params.prompt;
}
return trials;
};
plugin.trial = function(display_element, block, trial, part) {
var interleaver = new StaircaseInterleaver(display_element, trial, block);
interleaver.start();
};
function StaircaseInterleaver(display_element, trial, block) {
this.staircases = [];
for(var i=0; i<trial.items.length; i++)
{
var s_trial = $.extend(true, {}, trial);
s_trial.items = s_trial.items[i];
s_trial.choices = s_trial.choices[i];
var staircase = new StaircaseController(display_element, s_trial, this, block);
this.staircases.push(staircase);
}
this.start = function() {
this.next_trial();
};
this.next_trial = function() {
var eligible_staircases = [];
for (var i = 0; i < this.staircases.length; i++) {
if (this.staircases[i].is_complete === false) {
eligible_staircases.push(this.staircases[i]);
}
}
if (eligible_staircases.length === 0) {
this.finish();
}
else {
var which_staircase = Math.floor(Math.random() * eligible_staircases.length);
eligible_staircases[which_staircase].next_trial();
}
};
this.finish = function()
{
// end the whole staircase process
block.next();
}
}
function StaircaseController(display_element, trial, interleaver, block) {
this.current_item = 0;
this.total_turns = 0;
this.current_direction = 1;
this.turns = [];
this.consecutive_correct = 0;
this.consecutive_incorrect = 0;
this.items = trial.items;
this.is_complete = false;
this.interleaver = interleaver;
this.next_trial = function() {
var item_set = this.items[this.current_item];
// pick which category to show randomly
var which_category = Math.floor(Math.random()*item_set.length);
// pick which exemplar to show randomly
var which_exemplar = Math.floor(Math.random()*item_set[which_category].length);
var this_trial = {
a_path: item_set[which_category][which_exemplar],
choices: trial.choices,
correct_response: trial.choices[which_category]
};
this.do_trial(this_trial);
};
this.finish_trial = function(correct) {
// change the counters
if (correct) {
this.consecutive_incorrect = 0;
this.consecutive_correct++;
}
else {
this.consecutive_incorrect++;
this.consecutive_correct = 0;
}
var new_direction;
if (correct) {
if (this.consecutive_correct >= trial.n_up) {
new_direction = 1; // make it harder
this.consecutive_correct = 0; // reset this because we changed difficulty.
}
else {
// do the same
new_direction = 0;
}
}
else {
if (this.consecutive_incorrect >= trial.n_down) {
// make it easier
new_direction = -1;
this.consecutive_incorrect = 0; // reset because we changed difficulty
}
else {
// do the same
new_direction = 0;
}
}
// if there is a turn, add it.
if (new_direction !== 0) {
if (this.current_direction != new_direction) {
this.turns.push(this.current_item);
}
this.current_direction = new_direction;
}
// check if we are done
if (this.turns.length >= trial.n_turns ){
this.is_complete = true;
}
// now figure out what the next item is
this.current_item = this.current_item + new_direction;
if (this.current_item < 0) {
this.current_item = 0;
}
if (this.current_item >= trial.items.length) {
this.current_item = trial.items.length - 1;
}
// tell the interleaver that we are done
this.interleaver.next_trial();
};
this.do_trial = function(this_trial) {
var trial_complete = false;
// show image
display_element.append($('<img>', {
"src": this_trial.a_path,
"class": 'staircase-categorize'
}));
if (trial.prompt) {
display_element.append(trial.prompt);
}
var startTime = (new Date()).getTime();
// set timer to remove image
if (trial.timing_item > 0) {
setTimeout(function() {
if (!trial_complete) {
$('.staircase-categorize').css('visibility', 'hidden');
}
}, trial.timing_item);
}
var resp_func = function(e) {
var flag = false;
var correct = false;
if ($.inArray(e.which, this_trial.choices) > -1) {
flag = true;
correct = (e.which == this_trial.correct_response);
}
if (flag) {
var endTime = (new Date()).getTime();
var rt = (endTime - startTime);
var t_idx = block.data.length;
var trial_data = {
"trial_type": "staircase-categorize",
"trial_index": t_idx,
"rt": rt,
"correct": correct,
"a_path": this_trial.a_path,
"staircase_index": e.data.iterator_object.current_item,
"staircase_direction": e.data.iterator_object.current_direction,
"key_press": e.which
};
block.data.push($.extend({},trial_data,trial.data));
$(document).unbind('keyup', resp_func);
display_element.html(''); // remove all
trial_complete = true;
setTimeout(function() {
e.data.iterator_object.finish_trial(correct);
}, trial.timing_post_trial);
}
}
$(document).keyup({iterator_object: this}, resp_func);
}
}
return plugin;
})();
})(jQuery);

View File

@ -1,223 +0,0 @@
/* jspsych-staircase.js
* Josh de Leeuw, Sep. 2013
*
*
*
*/
(function($) {
jsPsych.staircase_xab = (function() {
var plugin = {};
plugin.create = function(params) {
var trials = []; // everything is a single trial, since it is unknown how many presentations it will take.
trials[0] = {};
trials[0].type = "staircase_xab";
trials[0].items = params.items;
trials[0].foils = params.foils;
trials[0].left_key = params.left_key || 81; // array of all the correct key responses
trials[0].right_key = params.right_key || 80; // valid key responses
trials[0].n_up = params.n_up || 1;
trials[0].n_down = params.n_down || 1;
trials[0].n_turns = params.n_turns || 10;
trials[0].n_turns_average = params.n_turns_average || 6;
// timing
trials[0].timing_post_trial = params.timing_post_trial || 1000; // default 1000ms between trials.
trials[0].timing_x = params.timing_x || 1000;
trials[0].timing_xab_gap = params.timing_xab_gap || 1000;
trials[0].timing_ab = params.timing_ab || -1; // default is indefinitely.
// optional parameters
if (params.data !== undefined) {
trials[0].data = params.data;
}
if (params.prompt !== undefined) {
trials[0].prompt = params.prompt;
}
return trials;
};
plugin.trial = function(display_element, block, trial, part) {
var current_item = 0; // start with the easiest item
var total_turns = 0; // counter for keeping track of how many turns
var current_direction = 1; // which way are we currently moving in item set; +1 = harder; -1 = easier
var turns = []; // store the items where we turned
var consecutive_correct = 0;
var consecutive_incorrect = 0;
// do a trial, check if we've hit total_turns, if yes then end, if not do another trial.
var staircase_xab_trial_complete = false;
function next_trial() {
if (total_turns < trial.n_turns) {
// do trial
var this_trial = { };
do_trial(display_element, block, this )
}
else {
// end run
}
}
function finish_trial(correct) {
// change the counters
if (correct) {
consecutive_incorrect = 0;
consecutive_correct++;
}
else {
consecutive_incorrect++;
consecutive_correct = 0;
}
var new_direction;
if (correct) {
if (consecutive_correct >= trial.n_up) {
new_direction = 1; // make it harder
consecutive_correct = 0; // reset this because we changed difficulty.
}
else {
// do the same
new_direction = 0;
}
}
else {
if (consecutive_incorrect >= trial.n_down) {
// make it easier
new_direction = -1;
consecutive_incorrect = 0; // reset because we changed difficulty
}
else {
// do the same
new_direction = 0;
}
}
// if there is a turn, add it.
if (new_direction !== 0) {
if (current_direction != new_direction) {
turns.push(current_item);
}
current_direction = new_direction;
}
// now figure out what the next item is
current_item = current_item + new_direction;
if (current_item < 0) {
current_item = 0;
}
if (current_item >= trial.items.length) {
current_item = trial.items.length - 1;
}
}
function do_trial(display_element, block, trial, part) {
switch (part) {
case 1:
staircase_xab_trial_complete = false;
display_element.append($('<img>', {
"src": trial.a_path,
"class": 'staircase-xab'
}));
setTimeout(function() {
do_trial(display_element, block, trial, part + 1)
}, trial.timing_x);
break;
case 2:
$('.staircase-xab').remove();
setTimeout(function() {
do_trial(display_element, block, trial, part + 1)
}, trial.timing_xab_gap);
break;
case 3:
var startTime = (new Date()).getTime();
var images = [trial.a_path, trial.b_path];
var target_left = (Math.floor(Math.random() * 2) == 0); // 50% chance target is on left.
if (!target_left) {
images = [trial.b_path, trial.a_path];
}
// show the images
display_element.append($('<img>', {
"src": images[0],
"class": 'staircase-xab'
}));
display_element.append($('<img>', {
"src": images[1],
"class": 'staircase-xab'
}));
if (trial.prompt) {
display_element.append(trial.prompt);
}
if (trial.timing_ab > 0) {
setTimeout(function() {
if (!staircase_xab_trial_complete) {
$('.staircase-xab').css('visibility', 'hidden');
}
}, trial.timing_ab);
}
var resp_func = function(e) {
var flag = false;
var correct = false;
if (e.which == trial.left_key) {
flag = true;
if (target_left) {
correct = true;
}
}
else if (e.which == trial.right_key) {
flag = true;
if (!target_left) {
correct = true;
}
}
if (flag) {
var endTime = (new Date()).getTime();
var rt = (endTime - startTime);
var trial_data = {
"trial_type": "staircase-xab",
"trial_index": block.trial_idx,
"rt": rt,
"correct": correct,
"x_path": trial.x_path,
"a_path": trial.a_path,
"b_path": trial.b_path,
"key_press": e.which
}
//block.data[block.trial_idx] = $.extend({},trial_data,trial.data);
$(document).unbind('keyup', resp_func);
display_element.html(''); // remove all
staircase_xab_trial_complete = true;
setTimeout(function() {
block.next();
}, trial.timing_post_trial);
}
}
$(document).keyup(resp_func);
break;
}
}
}
return plugin;
})();
})(jQuery);

View File

@ -1,82 +0,0 @@
(function( $ ) {
jsPsych.storybook = (function(){
var plugin = {};
plugin.create = function(params) {
stims = params["stimuli"];
trials = new Array(stims.length);
for(var i = 0; i < trials.length; i++)
{
trials[i] = {};
trials[i]["type"] = "storybook";
trials[i]["a_path"] = stims[i];
trials[i]["click_num"] = params["click_num"];
trials[i]["timing"] = params["timing"];
if(params["data"]!=undefined){
trials[i]["data"] = params["data"][i];
}
}
return trials;
}
plugin.trial = function(display_element, block, trial, part)
{
switch(part){
case 1:
p1_time = (new Date()).getTime();
display_element.append($('<img>', {
"src": trial.a_path,
"class": 'storybook'
}));
var click_count = 0;
var click_locations = [];
var click_times = [];
var touchfunction = function(e) {
e.originalEvent.preventDefault();
var rt = (new Date()).getTime() - p1_time;
var x = e.originalEvent.touches[0].pageX;
var y = e.originalEvent.touches[0].pageY;
click_count = click_count + 1;
console.log("click event "+x+" "+y+". click count "+click_count+". click num "+trial.click_num);
//save location
click_locations.push([x,y]);
click_times.push(rt);
//save response time
if(click_count == trial.click_num)
{
var click_loc_data = {"click_locations": click_locations};
var click_time_data = {"click_times": click_times};
var img = {"img": trial.a_path };
// save data
block.data[block.trial_idx] = $.extend({}, img, click_loc_data, click_time_data, trial.data);
plugin.trial(display_element, block, trial, part + 1);
}
};
$('.storybook').click(function(){ void(0); })
//$('.storybook').mousedown(function(e){ touchfunction(e);});
$('.storybook').bind("touchstart", function(e){touchfunction(e);});
break;
case 2:
$('.storybook').remove();
setTimeout(function(){block.next();}, trial.timing[0]);
break;
}
}
return plugin;
})();
})(jQuery);

View File

@ -1,89 +0,0 @@
(function( $ ) {
jsPsych.touch_freepick = (function(){
var plugin = {};
plugin.create = function(params) {
stims = params["stims"];
trials = new Array(stims.length);
for(var i = 0; i < trials.length; i++)
{
trials[i] = {};
trials[i]["type"] = "touch_freepick";
trials[i]["stims"] = stims[i];
trials[i]["answer_text"] = params["answer_text"][i] || "";
trials[i]["timing"] = params["timing"];
trials[i]["force_correct_pick"] = params["force_correct_pick"] || false;
if(params["data"]!=undefined){
trials[i]["data"] = params["data"][i];
}
}
return trials;
}
plugin.trial = function(display_element, block, trial, part)
{
switch(part){
case 1:
p1_time = (new Date()).getTime();
var order = [];
for(var i=0;i<trial.stims.length;i++)
{
order.push(i);
}
order = shuffle(order);
// add images
for(var i=0;i<trial.stims.length;i++){
display_element.append($('<img>', {
"src": trial.stims[order[i]],
"class": 'freepick',
"id":'fp'+order[i]
}));
}
// need to pick the right one!
if(trial.force_correct_pick) {
$("#fp0").click(
function(){
// clear everything
display_element.html('');
// add only target
display_element.append($('<img>', {
"src": trial.stims[0],
"class": 'freepick',
"id":'fp_answer'
}));
display_element.append($('<p class="answer">'+trial.answer_text+'</p>'));
setTimeout(function(){plugin.trial(display_element,block,trial,part+1)}, trial.timing[0]);
}
);
}
break;
case 2:
display_element.html('');
setTimeout(function(){block.next();}, trial.timing[1]);
break;
}
}
function shuffle(array) {
var tmp, current, top = array.length;
if(top) while(--top) {
current = Math.floor(Math.random() * (top + 1));
tmp = array[current];
array[current] = array[top];
array[top] = tmp;
}
return array;
}
return plugin;
})();
})(jQuery);

View File

@ -1,110 +0,0 @@
// Josh de Leeuw
// Nov. 2012
// This plugin is for presenting two images in sequence and collecting a key response.
(function( $ ) {
jsPsych.twoimage_keyresponse = (function(){
var plugin = {};
plugin.create = function(params) {
var stims = params["stimuli"];
trials = new Array(stims.length);
for(var i = 0; i < trials.length; i++)
{
trials[i] = {};
trials[i]["type"] = "twoimage_keyresponse";
trials[i]["a_path"] = stims[i][0];
trials[i]["b_path"] = stims[i][1];
trials[i]["choices"] = params["choices"];
// timing parameters
trials[i]["timing_first_stim"] = params["timing_first_stim"] || 1000;
trials[i]["timing_gap"] = params["timing_gap"] || 500;
trials[i]["timing_second_stim"] = params["timing_second_stim"]; // if undefined, then show indefinitely
trials[i]["timing_post_trial"] = params["timing_post_trial"] || 1000;
// optional parameters
if(params["prompt"] != undefined){
trials[i]["prompt"] = params["prompt"];
}
if(params["data"]!=undefined){
trials[i]["data"] = params["data"][i];
}
}
return trials;
}
var tikr_trial_complete = false;
plugin.trial = function(display_element, block, trial, part)
{
switch(part){
case 1:
tikr_trial_complete = false;
display_element.append($('<img>', {
"src": trial.a_path,
"id": 'tikr_a_img'
}));
setTimeout(function(){plugin.trial(display_element, block, trial, part + 1)}, trial.timing_first_stim);
break;
case 2:
$('#tikr_a_img').remove();
setTimeout(function(){plugin.trial(display_element, block, trial, part + 1)}, trial.timing_gap);
break;
case 3:
startTime = (new Date()).getTime();
display_element.append($('<img>', {
"src": trial.b_path,
"id": 'tikr_b_img'
}));
//show prompt here
if(trial.prompt != undefined){
display_element.append(trial.prompt);
}
// hide image if timing is set
if(trial.timing_second_stim != undefined){
setTimeout(function(){
if(!tikr_trial_complete){
$('#tikr_b_img').css('visibility','hidden');
}
}, trial.timing_second_stim);
}
var resp_func = function(e) {
var flag = false;
// check if the key is any of the options, or if it is an accidental keystroke
for(var i=0;i<trial.choices.length;i++)
{
if(e.which==trial.choices[i])
{
flag = true;
}
}
if(flag)
{
endTime = (new Date()).getTime();
rt = (endTime-startTime);
var trial_data = {"trial_type":"twoimage_keyresponse", "rt": rt, "a_path": trial.a_path, "b_path": trial.b_path, "key_press": e.which}
block.data[block.trial_idx] = $.extend({},trial_data,trial.data);
$(document).unbind('keyup',resp_func);
display_element.html('');
tikr_trial_complete = true;
setTimeout(function(){block.next();}, trial.timing_post_trial);
}
}
$(document).keyup(resp_func);
break;
}
}
return plugin;
})();
})(jQuery);

View File

@ -1,96 +0,0 @@
(function( $ ) {
jsPsych.xab_touch = (function(){
var plugin = {};
plugin.create = function(params) {
//xab_stims = shuffle(xab_stims);
xab_stims = params["stimuli"];
trials = new Array(xab_stims.length);
for(var i = 0; i < trials.length; i++)
{
trials[i] = {};
trials[i]["type"] = "xab_touch";
trials[i]["a_path"] = xab_stims[i][0];
trials[i]["b_path"] = xab_stims[i][1];
trials[i]["timing"] = params["timing"];
if(params["data"]!=undefined){
trials[i]["data"] = params["data"][i];
}
}
return trials;
}
plugin.trial = function(display_element, block, trial, part)
{
switch(part){
case 1:
p1_time = (new Date()).getTime();
display_element.append($('<img>', {
"src": trial.a_path,
"class": 'xab_touch'
}));
setTimeout(function(){plugin.trial(display_element, block, trial, part + 1);}, trial.timing[0]);
break;
case 2:
p2_time = (new Date()).getTime();
$('.xab_touch').remove();
setTimeout(function(){plugin.trial(display_element, block, trial, part + 1);}, trial.timing[1]);
break;
case 3:
p3_time = (new Date()).getTime();
startTime = (new Date()).getTime();
var images = [trial.a_path, trial.b_path];
var target_left = (Math.floor(Math.random()*2)==0); // binary true/false choice
if(!target_left){
images = [trial.b_path, trial.a_path];
}
//$.fn.jsPsych.showImages(display_element, images, 'xab');
var correct=false;
display_element.append($('<img>', {
"src": images[0],
"class": 'xab_touch',
"id": "left_img"
}));
$("#left_img").click(function() {
if(target_left) { correct = true; }
endTime = (new Date()).getTime();
rt = (endTime-startTime);
stim1_time = (p2_time-p1_time);
isi_time = (p3_time-p2_time);
var trial_data = {"rt": rt, "correct": correct, "a_path": trial.a_path, "b_path": trial.b_path, "stim1_time": stim1_time, "isi_time":isi_time}
block.data[block.trial_idx] = $.extend({},trial_data,trial.data);
$('.xab_touch').remove();
setTimeout(function(){block.next();}, trial.timing[2]);
});
display_element.append($('<img>', {
"src": images[1],
"class": 'xab_touch',
"id": "right_img"
}));
$("#right_img").click(function() {
if(!target_left) { correct = true; }
endTime = (new Date()).getTime();
rt = (endTime-startTime);
stim1_time = (p2_time-p1_time);
isi_time = (p3_time-p2_time);
var trial_data = {"rt": rt, "correct": correct, "a_path": trial.a_path, "b_path": trial.b_path, "stim1_time": stim1_time, "isi_time":isi_time}
block.data[block.trial_idx] = $.extend({},trial_data,trial.data);
$('.xab_touch').remove();
setTimeout(function(){block.next();}, trial.timing[2]);
});
//TODO: CHECK IF IMAGE SHOULD DISAPPEAR
//based on timings
break;
}
}
return plugin;
})();
})(jQuery);