mirror of
https://github.com/jspsych/jsPsych.git
synced 2025-05-12 08:38:11 +00:00
Comments with jqueryToVanilla lines of code, but without change it
This commit is contained in:
parent
e2244eecb6
commit
99925639e0
@ -6,433 +6,502 @@
|
|||||||
Contributions from Peter J. Kohler: https://github.com/pjkohler
|
Contributions from Peter J. Kohler: https://github.com/pjkohler
|
||||||
*/
|
*/
|
||||||
|
|
||||||
jsPsych.plugins['virtual-chinrest'] = (function() {
|
jsPsych.plugins["virtual-chinrest"] = (function () {
|
||||||
|
|
||||||
var plugin = {};
|
var plugin = {};
|
||||||
|
|
||||||
plugin.info = {
|
plugin.info = {
|
||||||
name: "virtual-chinrest",
|
name: "virtual-chinrest",
|
||||||
parameters: {
|
parameters: {
|
||||||
resize_units: {
|
resize_units: {
|
||||||
type: jsPsych.plugins.parameterType.STRING,
|
type: jsPsych.plugins.parameterType.STRING,
|
||||||
default: "none",
|
default: "none",
|
||||||
description: 'What units to resize to? ["none"/"cm"/"inch"/"deg"]. If "none", no resize will be done.'
|
description:
|
||||||
|
'What units to resize to? ["none"/"cm"/"inch"/"deg"]. If "none", no resize will be done.',
|
||||||
},
|
},
|
||||||
pixels_per_unit: {
|
pixels_per_unit: {
|
||||||
type: jsPsych.plugins.parameterType.INT,
|
type: jsPsych.plugins.parameterType.INT,
|
||||||
pretty_name: 'Pixels per unit',
|
pretty_name: "Pixels per unit",
|
||||||
default: 100,
|
default: 100,
|
||||||
description: 'After the scaling factor is applied, this many pixels will equal one unit of measurement.'
|
description:
|
||||||
|
"After the scaling factor is applied, this many pixels will equal one unit of measurement.",
|
||||||
},
|
},
|
||||||
mouse_adjustment: {
|
mouse_adjustment: {
|
||||||
type: jsPsych.plugins.parameterType.BOOL,
|
type: jsPsych.plugins.parameterType.BOOL,
|
||||||
pretty_name: 'Adjust Using Mouse?',
|
pretty_name: "Adjust Using Mouse?",
|
||||||
default: true
|
default: true,
|
||||||
},
|
},
|
||||||
adjustment_prompt: {
|
adjustment_prompt: {
|
||||||
type: jsPsych.plugins.parameterType.STRING,
|
type: jsPsych.plugins.parameterType.STRING,
|
||||||
default: '<b> Let’s find out how big your monitor is! </b>'+
|
default:
|
||||||
'<p>Please use any credit card that you have available.<br>' +
|
"<b> Let’s find out how big your monitor is! </b>" +
|
||||||
'It can also be a grocery store membership card,<br>'+
|
"<p>Please use any credit card that you have available.<br>" +
|
||||||
'your drivers license or anything else of the same format.<br>'+
|
"It can also be a grocery store membership card,<br>" +
|
||||||
'<b>Place your card flat onto the screen, and adjust the slider below to match its size.</b></p>'+
|
"your drivers license or anything else of the same format.<br>" +
|
||||||
'<p>If you do not have access to a real card <br>'+
|
"<b>Place your card flat onto the screen, and adjust the slider below to match its size.</b></p>" +
|
||||||
'you can use a ruler to measure the image width to 3.37 inches or 85.6 mm.<br>',
|
"<p>If you do not have access to a real card <br>" +
|
||||||
description: ' Any content here will be displayed above the card stimulus.'
|
"you can use a ruler to measure the image width to 3.37 inches or 85.6 mm.<br>",
|
||||||
|
description:
|
||||||
|
" Any content here will be displayed above the card stimulus.",
|
||||||
},
|
},
|
||||||
adjustment_button_prompt: {
|
adjustment_button_prompt: {
|
||||||
type: jsPsych.plugins.parameterType.STRING,
|
type: jsPsych.plugins.parameterType.STRING,
|
||||||
default: 'Click here when the card has the right size!',
|
default: "Click here when the card has the right size!",
|
||||||
description: ' Content of the button displayed below the card stimulus.'
|
description:
|
||||||
|
" Content of the button displayed below the card stimulus.",
|
||||||
},
|
},
|
||||||
item_path: {
|
item_path: {
|
||||||
type: jsPsych.plugins.parameterType.STRING,
|
type: jsPsych.plugins.parameterType.STRING,
|
||||||
default: "img/card.png"
|
default: "img/card.png",
|
||||||
},
|
},
|
||||||
item_height_mm: {
|
item_height_mm: {
|
||||||
type: jsPsych.plugins.parameterType.INT,
|
type: jsPsych.plugins.parameterType.INT,
|
||||||
pretty_name: 'Item height',
|
pretty_name: "Item height",
|
||||||
default: 53.98,
|
default: 53.98,
|
||||||
description: 'The height of the item to be measured.'
|
description: "The height of the item to be measured.",
|
||||||
},
|
},
|
||||||
item_width_mm: {
|
item_width_mm: {
|
||||||
type: jsPsych.plugins.parameterType.INT,
|
type: jsPsych.plugins.parameterType.INT,
|
||||||
pretty_name: 'Item width',
|
pretty_name: "Item width",
|
||||||
default: 85.60,
|
default: 85.6,
|
||||||
description: 'The width of the item to be measured.'
|
description: "The width of the item to be measured.",
|
||||||
},
|
},
|
||||||
item_init_size: {
|
item_init_size: {
|
||||||
type: jsPsych.plugins.parameterType.INT,
|
type: jsPsych.plugins.parameterType.INT,
|
||||||
pretty_name: 'Initial Size',
|
pretty_name: "Initial Size",
|
||||||
default: 250,
|
default: 250,
|
||||||
description: 'The initial size of the card, in pixels, along the largest dimension.'
|
description:
|
||||||
|
"The initial size of the card, in pixels, along the largest dimension.",
|
||||||
},
|
},
|
||||||
blindspot_reps: {
|
blindspot_reps: {
|
||||||
type: jsPsych.plugins.parameterType.INT,
|
type: jsPsych.plugins.parameterType.INT,
|
||||||
pretty_name: 'Blindspot measurement repetitions',
|
pretty_name: "Blindspot measurement repetitions",
|
||||||
default: 5,
|
default: 5,
|
||||||
description: 'How many times to measure the blindspot location? If 0, blindspot will not detected and viewing distance not computed.'
|
description:
|
||||||
|
"How many times to measure the blindspot location? If 0, blindspot will not detected and viewing distance not computed.",
|
||||||
},
|
},
|
||||||
blindspot_prompt: {
|
blindspot_prompt: {
|
||||||
type: jsPsych.plugins.parameterType.STRING,
|
type: jsPsych.plugins.parameterType.STRING,
|
||||||
default: '<b>Now, let’s quickly test how far away you are sitting.</b>'+
|
default:
|
||||||
'<p>You might know that vision tests at a doctor’s practice often involve chinrests.<br>'+
|
"<b>Now, let’s quickly test how far away you are sitting.</b>" +
|
||||||
'The doctor basically asks you to sit away from a screen in a specific distance.<br>'+
|
"<p>You might know that vision tests at a doctor’s practice often involve chinrests.<br>" +
|
||||||
'We do this here with a “virtual chinrest”.</p><br>'+
|
"The doctor basically asks you to sit away from a screen in a specific distance.<br>" +
|
||||||
'<b>Instructions</b>'+
|
"We do this here with a “virtual chinrest”.</p><br>" +
|
||||||
'<div style="text-align: left">'+
|
"<b>Instructions</b>" +
|
||||||
'<ol><li>Put your finger on <b>space bar</b> on the keyboard.</li>'+
|
'<div style="text-align: left">' +
|
||||||
'<li>Close your right eye. <em>(Tips: it might be easier to cover your right eye by hand!)</em></li>'+
|
"<ol><li>Put your finger on <b>space bar</b> on the keyboard.</li>" +
|
||||||
'<li>Using your left eye, focus on the black square.</li>'+
|
"<li>Close your right eye. <em>(Tips: it might be easier to cover your right eye by hand!)</em></li>" +
|
||||||
'<li>Click the button below to start the animation of the red ball. The <b style="color: red">red ball </b>'+
|
"<li>Using your left eye, focus on the black square.</li>" +
|
||||||
'will disappear as it moves from right to left. Press the “Space” key as soon as the ball disappears from your eye sight.</li>'+
|
'<li>Click the button below to start the animation of the red ball. The <b style="color: red">red ball </b>' +
|
||||||
'</div><br> Keep your right eye closed and hit the “Space” key fast!</p><br>'
|
"will disappear as it moves from right to left. Press the “Space” key as soon as the ball disappears from your eye sight.</li>" +
|
||||||
|
"</div><br> Keep your right eye closed and hit the “Space” key fast!</p><br>",
|
||||||
},
|
},
|
||||||
blindspot_start_prompt: {
|
blindspot_start_prompt: {
|
||||||
type: jsPsych.plugins.parameterType.STRING,
|
type: jsPsych.plugins.parameterType.STRING,
|
||||||
default: 'Start',
|
default: "Start",
|
||||||
description: 'Content of the start button for the blindspot tasks.'
|
description: "Content of the start button for the blindspot tasks.",
|
||||||
},
|
},
|
||||||
blindspot_done_prompt: {
|
blindspot_done_prompt: {
|
||||||
type: jsPsych.plugins.parameterType.STRING,
|
type: jsPsych.plugins.parameterType.STRING,
|
||||||
default: 'Done',
|
default: "Done",
|
||||||
description: 'Content of the done button for the blindspot tasks.'
|
description: "Content of the done button for the blindspot tasks.",
|
||||||
},
|
},
|
||||||
blindspot_measurements_prompt: {
|
blindspot_measurements_prompt: {
|
||||||
type: jsPsych.plugins.parameterType.STRING,
|
type: jsPsych.plugins.parameterType.STRING,
|
||||||
default: 'Remaining measurements: ',
|
default: "Remaining measurements: ",
|
||||||
description: 'Text accompanying the remaining measures counter'
|
description: "Text accompanying the remaining measures counter",
|
||||||
|
|
||||||
},
|
},
|
||||||
viewing_distance_report: {
|
viewing_distance_report: {
|
||||||
type: jsPsych.plugins.parameterType.STRING,
|
type: jsPsych.plugins.parameterType.STRING,
|
||||||
default: 'Estimated viewing distance (cm):',
|
default: "Estimated viewing distance (cm):",
|
||||||
description: 'If "none" is given, viewing distance will not be reported to the participant'
|
description:
|
||||||
}
|
'If "none" is given, viewing distance will not be reported to the participant',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
|
};
|
||||||
|
|
||||||
// Get screen size
|
// Get screen size
|
||||||
var w = window.innerWidth;
|
var w = window.innerWidth;
|
||||||
var h = window.innerHeight;
|
var h = window.innerHeight;
|
||||||
|
|
||||||
const screen_size_px = []
|
const screen_size_px = [];
|
||||||
screen_size_px.push(w)
|
screen_size_px.push(w);
|
||||||
screen_size_px.push('x')
|
screen_size_px.push("x");
|
||||||
screen_size_px.push(h)
|
screen_size_px.push(h);
|
||||||
|
|
||||||
let trial_data = {} // declare trial data as empty so we have access to it across functions
|
let trial_data = {}; // declare trial data as empty so we have access to it across functions
|
||||||
|
|
||||||
let config_data = {
|
let config_data = {
|
||||||
"ball_pos": [],
|
ball_pos: [],
|
||||||
"slider_clck": false
|
slider_clck: false,
|
||||||
}
|
};
|
||||||
|
|
||||||
plugin.trial = function(display_element, trial) {
|
plugin.trial = function (display_element, trial) {
|
||||||
try {
|
try {
|
||||||
if ( !( trial.blindspot_reps > 0 ) && ( (trial.resize_units == "deg" ) || (trial.resize_units == "degrees" ) ) ) {
|
if (
|
||||||
throw Error("Blindspot repetitions set to 0, so resizing to degrees of visual angle is not possible!")
|
!(trial.blindspot_reps > 0) &&
|
||||||
|
(trial.resize_units == "deg" || trial.resize_units == "degrees")
|
||||||
|
) {
|
||||||
|
throw Error(
|
||||||
|
"Blindspot repetitions set to 0, so resizing to degrees of visual angle is not possible!"
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
const start_time = performance.now();
|
const start_time = performance.now();
|
||||||
|
|
||||||
trial_data = {
|
trial_data = {
|
||||||
"item_width_mm": trial.item_width_mm,
|
item_width_mm: trial.item_width_mm,
|
||||||
"item_height_mm": trial.item_height_mm //card dimension: 85.60 × 53.98 mm (3.370 × 2.125 in)
|
item_height_mm: trial.item_height_mm, //card dimension: 85.60 × 53.98 mm (3.370 × 2.125 in)
|
||||||
};
|
};
|
||||||
|
|
||||||
let button_str = '<button id=blind_spot class="btn btn-primary">'
|
let button_str = '<button id=blind_spot class="btn btn-primary">';
|
||||||
if (!( trial.blindspot_reps > 0 )) {
|
if (!(trial.blindspot_reps > 0)) {
|
||||||
button_str = '<button id=proceed class="btn btn-primary">'
|
button_str = '<button id=proceed class="btn btn-primary">';
|
||||||
}
|
}
|
||||||
|
|
||||||
let report_str = ''
|
let report_str = "";
|
||||||
if ( !(trial.viewing_distance_report == "none" ) ) {
|
if (!(trial.viewing_distance_report == "none")) {
|
||||||
report_str = '<div id="info" style="visibility:hidden">'+
|
report_str =
|
||||||
'<b id="info-h">' + trial.viewing_distance_report + ' </b>'+
|
'<div id="info" style="visibility:hidden">' +
|
||||||
'</div>'
|
'<b id="info-h">' +
|
||||||
|
trial.viewing_distance_report +
|
||||||
|
" </b>" +
|
||||||
|
"</div>";
|
||||||
}
|
}
|
||||||
|
|
||||||
let pagesize_content = '<div id="page-size"><br><br>' + trial.adjustment_prompt
|
let pagesize_content =
|
||||||
|
'<div id="page-size"><br><br>' + trial.adjustment_prompt;
|
||||||
|
|
||||||
// variables to determine div size
|
// variables to determine div size
|
||||||
let aspect_ratio = 1
|
let aspect_ratio = 1;
|
||||||
|
|
||||||
if ( trial.mouse_adjustment ) {
|
if (trial.mouse_adjustment) {
|
||||||
aspect_ratio = trial.item_width_mm / trial.item_height_mm
|
aspect_ratio = trial.item_width_mm / trial.item_height_mm;
|
||||||
const start_div_height = ((aspect_ratio < 1 ) ? trial.item_init_size : Math.round(trial.item_init_size / aspect_ratio));
|
const start_div_height =
|
||||||
const start_div_width = ((aspect_ratio < 1 ) ? Math.round(trial.item_init_size * aspect_ratio) : trial.item_init_size );
|
aspect_ratio < 1
|
||||||
const adjust_size = Math.round(start_div_width*.1)
|
? trial.item_init_size
|
||||||
|
: Math.round(trial.item_init_size / aspect_ratio);
|
||||||
|
const start_div_width =
|
||||||
|
aspect_ratio < 1
|
||||||
|
? Math.round(trial.item_init_size * aspect_ratio)
|
||||||
|
: trial.item_init_size;
|
||||||
|
const adjust_size = Math.round(start_div_width * 0.1);
|
||||||
pagesize_content +=
|
pagesize_content +=
|
||||||
'<br>' + button_str + trial.adjustment_button_prompt + '</button><br>' +
|
"<br>" +
|
||||||
'<div id="item" style="border: none; '+
|
button_str +
|
||||||
'height: '+ start_div_height+'px; width:'+start_div_width+'px; '+
|
trial.adjustment_button_prompt +
|
||||||
'margin: 5px auto; background-color: none; position: relative; '+
|
"</button><br>" +
|
||||||
'background-image: url(' + trial.item_path + '); '+
|
'<div id="item" style="border: none; ' +
|
||||||
'background-size: 100% auto; background-repeat: no-repeat">'+
|
"height: " +
|
||||||
'<div id="jspsych-resize-handle" style="cursor: nwse-resize; '+
|
start_div_height +
|
||||||
'background-color: none; width: ' + adjust_size + 'px; height: ' + adjust_size + 'px; '+
|
"px; width:" +
|
||||||
'border: 5px solid red; border-left: 0; border-top: 0; position: absolute; bottom: 0; right: 0;">'+
|
start_div_width +
|
||||||
'</div>'+
|
"px; " +
|
||||||
'</div>'+
|
"margin: 5px auto; background-color: none; position: relative; " +
|
||||||
'</div>'
|
"background-image: url(" +
|
||||||
|
trial.item_path +
|
||||||
|
"); " +
|
||||||
|
'background-size: 100% auto; background-repeat: no-repeat">' +
|
||||||
|
'<div id="jspsych-resize-handle" style="cursor: nwse-resize; ' +
|
||||||
|
"background-color: none; width: " +
|
||||||
|
adjust_size +
|
||||||
|
"px; height: " +
|
||||||
|
adjust_size +
|
||||||
|
"px; " +
|
||||||
|
'border: 5px solid red; border-left: 0; border-top: 0; position: absolute; bottom: 0; right: 0;">' +
|
||||||
|
"</div>" +
|
||||||
|
"</div>" +
|
||||||
|
"</div>";
|
||||||
} else {
|
} else {
|
||||||
pagesize_content +=
|
pagesize_content +=
|
||||||
'<div id="container">'+
|
'<div id="container">' +
|
||||||
'<div id="slider"></div><br>'+
|
'<div id="slider"></div><br>' +
|
||||||
button_str + trial.adjustment_button_prompt + '</button><br><br>'+
|
button_str +
|
||||||
'<img id="item" src="' + trial.item_path + '" style="width: 50%">'+
|
trial.adjustment_button_prompt +
|
||||||
'</div>'+
|
"</button><br><br>" +
|
||||||
'</div>'
|
'<img id="item" src="' +
|
||||||
|
trial.item_path +
|
||||||
|
'" style="width: 50%">' +
|
||||||
|
"</div>" +
|
||||||
|
"</div>";
|
||||||
}
|
}
|
||||||
|
|
||||||
const blindspot_content =
|
const blindspot_content =
|
||||||
'<div id="blind-spot" style="visibility: hidden">' +
|
'<div id="blind-spot" style="visibility: hidden">' +
|
||||||
trial.blindspot_prompt +
|
trial.blindspot_prompt +
|
||||||
'<div id="svgDiv" style="width:1000px;height:200px;"></div>'+
|
'<div id="svgDiv" style="width:1000px;height:200px;"></div>' +
|
||||||
'<button class="btn btn-primary" id="start_ball">' + trial.blindspot_start_prompt + '</button>'+
|
'<button class="btn btn-primary" id="start_ball">' +
|
||||||
'<button class="btn btn-primary" id="proceed" style="display:none">' + trial.blindspot_done_prompt + '</button><br>'+
|
trial.blindspot_start_prompt +
|
||||||
`<b> ${trial.blindspot_measurements_prompt} <div id="click" style="display:inline; color: red"> ${trial.blindspot_reps} </div> <b><br>` +
|
"</button>" +
|
||||||
report_str+
|
'<button class="btn btn-primary" id="proceed" style="display:none">' +
|
||||||
'</div>'
|
trial.blindspot_done_prompt +
|
||||||
|
"</button><br>" +
|
||||||
display_element.innerHTML =
|
`<b> ${trial.blindspot_measurements_prompt} <div id="click" style="display:inline; color: red"> ${trial.blindspot_reps} </div> <b><br>` +
|
||||||
'<div id="content" style="width: 900px; margin: 0 auto;">'+
|
report_str +
|
||||||
pagesize_content +
|
"</div>";
|
||||||
blindspot_content +
|
|
||||||
'</div>'
|
display_element.innerHTML =
|
||||||
|
'<div id="content" style="width: 900px; margin: 0 auto;">' +
|
||||||
|
pagesize_content +
|
||||||
|
blindspot_content +
|
||||||
|
"</div>";
|
||||||
|
|
||||||
// Event listeners for mouse-based resize
|
// Event listeners for mouse-based resize
|
||||||
if ( trial.mouse_adjustment ) {
|
if (trial.mouse_adjustment) {
|
||||||
let dragging = false;
|
let dragging = false;
|
||||||
let origin_x, origin_y;
|
let origin_x, origin_y;
|
||||||
let cx, cy;
|
let cx, cy;
|
||||||
|
|
||||||
const mouseupevent = function(e){
|
|
||||||
dragging = false;
|
|
||||||
}
|
|
||||||
display_element.addEventListener('mouseup', mouseupevent);
|
|
||||||
|
|
||||||
const mousedownevent = function(e){
|
const mouseupevent = function (e) {
|
||||||
|
dragging = false;
|
||||||
|
};
|
||||||
|
display_element.addEventListener("mouseup", mouseupevent);
|
||||||
|
|
||||||
|
const mousedownevent = function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
dragging = true;
|
dragging = true;
|
||||||
origin_x = e.pageX;
|
origin_x = e.pageX;
|
||||||
origin_y = e.pageY;
|
origin_y = e.pageY;
|
||||||
cx = parseInt(scale_div.style.width);
|
cx = parseInt(scale_div.style.width);
|
||||||
cy = parseInt(scale_div.style.height);
|
cy = parseInt(scale_div.style.height);
|
||||||
}
|
};
|
||||||
display_element.querySelector('#jspsych-resize-handle').addEventListener('mousedown', mousedownevent);
|
display_element
|
||||||
|
.querySelector("#jspsych-resize-handle")
|
||||||
|
.addEventListener("mousedown", mousedownevent);
|
||||||
|
|
||||||
const scale_div = display_element.querySelector('#item');
|
const scale_div = display_element.querySelector("#item");
|
||||||
|
|
||||||
function resizeevent(e){
|
function resizeevent(e) {
|
||||||
if(dragging){
|
if (dragging) {
|
||||||
let dx = (e.pageX - origin_x);
|
let dx = e.pageX - origin_x;
|
||||||
let dy = (e.pageY - origin_y);
|
let dy = e.pageY - origin_y;
|
||||||
|
|
||||||
if(Math.abs(dx) >= Math.abs(dy)){
|
if (Math.abs(dx) >= Math.abs(dy)) {
|
||||||
scale_div.style.width = Math.round(Math.max(20, cx+dx*2)) + "px";
|
scale_div.style.width =
|
||||||
scale_div.style.height = Math.round(Math.max(20, cx+dx*2) / aspect_ratio ) + "px";
|
Math.round(Math.max(20, cx + dx * 2)) + "px";
|
||||||
|
scale_div.style.height =
|
||||||
|
Math.round(Math.max(20, cx + dx * 2) / aspect_ratio) + "px";
|
||||||
} else {
|
} else {
|
||||||
scale_div.style.height = Math.round(Math.max(20, cy+dy*2)) + "px";
|
scale_div.style.height =
|
||||||
scale_div.style.width = Math.round(aspect_ratio * Math.max(20, cy+dy*2)) + "px";
|
Math.round(Math.max(20, cy + dy * 2)) + "px";
|
||||||
|
scale_div.style.width =
|
||||||
|
Math.round(aspect_ratio * Math.max(20, cy + dy * 2)) + "px";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
display_element.addEventListener('mousemove', resizeevent)
|
display_element.addEventListener("mousemove", resizeevent);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Event listeners for buttons
|
//Event listeners for buttons
|
||||||
if ( trial.blindspot_reps > 0 ) {
|
if (trial.blindspot_reps > 0) {
|
||||||
display_element.querySelector('#blind_spot').addEventListener('click', function(){
|
display_element
|
||||||
configureBlindSpot()
|
.querySelector("#blind_spot")
|
||||||
})
|
.addEventListener("click", function () {
|
||||||
display_element.querySelector('#start_ball').addEventListener('click', function(){
|
configureBlindSpot();
|
||||||
animateBall()
|
});
|
||||||
})
|
display_element
|
||||||
|
.querySelector("#start_ball")
|
||||||
|
.addEventListener("click", function () {
|
||||||
|
animateBall();
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
// run the two relevant functions to get item_width_mm and px2mm
|
// run the two relevant functions to get item_width_mm and px2mm
|
||||||
distanceSetup.px2mm(get_item_width())
|
distanceSetup.px2mm(get_item_width());
|
||||||
}
|
}
|
||||||
|
|
||||||
display_element.querySelector('#proceed').addEventListener('click', function(){
|
display_element
|
||||||
|
.querySelector("#proceed")
|
||||||
|
.addEventListener("click", function () {
|
||||||
|
// finish trial
|
||||||
|
trial_data.rt = performance.now() - start_time;
|
||||||
|
display_element.innerHTML = "";
|
||||||
|
|
||||||
// finish trial
|
trial_data.item_width_deg =
|
||||||
trial_data.rt = performance.now() - start_time;
|
(2 *
|
||||||
display_element.innerHTML = '';
|
Math.atan(
|
||||||
|
trial_data["item_width_mm"] / 2 / trial_data["view_dist_mm"]
|
||||||
|
) *
|
||||||
|
180) /
|
||||||
|
Math.PI;
|
||||||
|
trial_data.px2deg =
|
||||||
|
trial_data["item_width_px"] / trial_data.item_width_deg; // size of item in pixels divided by size of item in degrees of visual angle
|
||||||
|
|
||||||
trial_data.item_width_deg = 2*(Math.atan((trial_data["item_width_mm"]/2)/trial_data["view_dist_mm"])) * 180/Math.PI
|
let px2unit_scr = 0;
|
||||||
trial_data.px2deg = trial_data["item_width_px"] / trial_data.item_width_deg // size of item in pixels divided by size of item in degrees of visual angle
|
switch (trial.resize_units) {
|
||||||
|
case "cm":
|
||||||
|
case "centimeters":
|
||||||
|
px2unit_scr = trial_data["px2mm"] * 10; // pixels per centimeter
|
||||||
|
break;
|
||||||
|
case "inch":
|
||||||
|
case "inches":
|
||||||
|
px2unit_scr = trial_data["px2mm"] * 25.4; // pixels per inch
|
||||||
|
break;
|
||||||
|
case "deg":
|
||||||
|
case "degrees":
|
||||||
|
px2unit_scr = trial_data["px2deg"]; // pixels per degree of visual angle
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (px2unit_scr > 0) {
|
||||||
|
// scale the window
|
||||||
|
scale_factor = px2unit_scr / trial.pixels_per_unit;
|
||||||
|
document.getElementById("jspsych-content").style.transform =
|
||||||
|
"scale(" + scale_factor + ")";
|
||||||
|
// pixels have been scaled, so pixels per degree, pixels per mm and pixels per item_width needs to be updated
|
||||||
|
trial_data.px2deg = trial_data.px2deg / scale_factor;
|
||||||
|
trial_data.px2mm = trial_data.px2mm / scale_factor;
|
||||||
|
trial_data.item_width_px =
|
||||||
|
trial_data.item_width_px / scale_factor;
|
||||||
|
trial_data.scale_factor = scale_factor;
|
||||||
|
}
|
||||||
|
|
||||||
let px2unit_scr = 0
|
if (trial.blindspot_reps > 0) {
|
||||||
switch (trial.resize_units) {
|
trial_data.win_width_deg = window.innerWidth / trial_data.px2deg;
|
||||||
case "cm":
|
trial_data.win_height_deg =
|
||||||
case "centimeters":
|
window.innerHeight / trial_data.px2deg;
|
||||||
px2unit_scr = trial_data["px2mm"]*10 // pixels per centimeter
|
} else {
|
||||||
break;
|
// delete degree related properties
|
||||||
case "inch":
|
delete trial_data.px2deg;
|
||||||
case "inches":
|
delete trial_data.item_width_deg;
|
||||||
px2unit_scr = trial_data["px2mm"]*25.4 // pixels per inch
|
}
|
||||||
break;
|
jsPsych.finishTrial(trial_data);
|
||||||
case "deg":
|
jsPsych.pluginAPI.cancelAllKeyboardResponses();
|
||||||
case "degrees":
|
});
|
||||||
px2unit_scr = trial_data["px2deg"] // pixels per degree of visual angle
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (px2unit_scr > 0) {
|
|
||||||
// scale the window
|
|
||||||
scale_factor = px2unit_scr / trial.pixels_per_unit;
|
|
||||||
document.getElementById("jspsych-content").style.transform = "scale(" + scale_factor + ")";
|
|
||||||
// pixels have been scaled, so pixels per degree, pixels per mm and pixels per item_width needs to be updated
|
|
||||||
trial_data.px2deg = trial_data.px2deg / scale_factor
|
|
||||||
trial_data.px2mm = trial_data.px2mm / scale_factor
|
|
||||||
trial_data.item_width_px = trial_data.item_width_px / scale_factor
|
|
||||||
trial_data.scale_factor = scale_factor
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( trial.blindspot_reps > 0 ) {
|
|
||||||
trial_data.win_width_deg = window.innerWidth/trial_data.px2deg
|
|
||||||
trial_data.win_height_deg = window.innerHeight/trial_data.px2deg
|
|
||||||
} else {
|
|
||||||
// delete degree related properties
|
|
||||||
delete trial_data.px2deg
|
|
||||||
delete trial_data.item_width_deg
|
|
||||||
}
|
|
||||||
jsPsych.finishTrial(trial_data);
|
|
||||||
jsPsych.pluginAPI.cancelAllKeyboardResponses();
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
(function ( distanceSetup, $ ) { // jQuery short-hand for $(document).ready(function() { ... });
|
(function (distanceSetup, $) {
|
||||||
|
// jQuery short-hand for $(document).ready(function() { ... });
|
||||||
|
|
||||||
distanceSetup.round = function(value, decimals) {
|
distanceSetup.round = function (value, decimals) {
|
||||||
return Number(Math.round(value+'e'+decimals)+'e-'+decimals);
|
return Number(Math.round(value + "e" + decimals) + "e-" + decimals);
|
||||||
};
|
};
|
||||||
|
|
||||||
distanceSetup.px2mm = function(item_width_px) {
|
distanceSetup.px2mm = function (item_width_px) {
|
||||||
const px2mm = item_width_px/trial_data["item_width_mm"];
|
const px2mm = item_width_px / trial_data["item_width_mm"];
|
||||||
trial_data["px2mm"] = distanceSetup.round(px2mm, 2);
|
trial_data["px2mm"] = distanceSetup.round(px2mm, 2);
|
||||||
return px2mm;
|
return px2mm;
|
||||||
};
|
};
|
||||||
|
})((window.distanceSetup = window.distanceSetup || {}), jQuery);
|
||||||
}( window.distanceSetup = window.distanceSetup || {}, jQuery))
|
|
||||||
|
|
||||||
function get_item_width() {
|
function get_item_width() {
|
||||||
const item_width_px = $('#item').width();
|
const item_width_px = $("#item").width();
|
||||||
trial_data["item_width_px"] = distanceSetup.round(item_width_px,2);
|
trial_data["item_width_px"] = distanceSetup.round(item_width_px, 2);
|
||||||
return item_width_px
|
return item_width_px;
|
||||||
}
|
}
|
||||||
|
|
||||||
function configureBlindSpot() {
|
function configureBlindSpot() {
|
||||||
drawBall();
|
drawBall();
|
||||||
$('#page-size').remove();
|
$("#page-size").remove(); // jqueryToVanilla: el.parentNode.removeChild(el);
|
||||||
$('#blind-spot').css({'visibility':'visible'});
|
$("#blind-spot").css({ visibility: "visible" }); // jqueryToVanilla: document.getElementById("myP").style.visibility = "hidden";
|
||||||
// $(document).on('keydown', recordPosition);
|
// $(document).on('keydown', recordPosition);
|
||||||
$(document).on('keydown', recordPosition);
|
$(document).on("keydown", recordPosition); // jqueryToVanilla: document.addEventListener("keydown", (e) => { /* ... */ });
|
||||||
}
|
}
|
||||||
|
|
||||||
$( function() {
|
$(function () {
|
||||||
$( "#slider" ).slider({value:"50"});
|
$("#slider").slider({ value: "50" }); // jqueryToVanilla:
|
||||||
} );
|
});
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function () {
|
||||||
$( "#slider" ).on("slide", function (event, ui) {
|
// jqueryToVanilla: https://stackoverflow.com/questions/799981/document-ready-equivalent-without-jquery
|
||||||
const item_width = ui.value + "%";
|
$("#slider").on("slide", function (event, ui) {
|
||||||
$("#item").css({"width":item_width});
|
const item_width = ui.value + "%";
|
||||||
});
|
$("#item").css({ width: item_width });
|
||||||
|
});
|
||||||
$('#slider').on('slidechange', function(event, ui){
|
|
||||||
config_data["slider_clck"] = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
$("#slider").on("slidechange", function (event, ui) {
|
||||||
|
// jqueryToVanilla: document.addEventListener("keydown", (e) => { /* ... */ });
|
||||||
|
config_data["slider_clck"] = true;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
//=============================
|
//=============================
|
||||||
//Ball Animation
|
//Ball Animation
|
||||||
|
|
||||||
function drawBall(pos=180){
|
function drawBall(pos = 180) {
|
||||||
// pos: define where the fixation square should be.
|
// pos: define where the fixation square should be.
|
||||||
var mySVG = SVG("svgDiv");
|
var mySVG = SVG("svgDiv");
|
||||||
const item_width_px = get_item_width()
|
const item_width_px = get_item_width();
|
||||||
const rectX = distanceSetup.px2mm(item_width_px)*pos;
|
const rectX = distanceSetup.px2mm(item_width_px) * pos;
|
||||||
const ballX = rectX*0.6 // define where the ball is
|
const ballX = rectX * 0.6; // define where the ball is
|
||||||
var ball = mySVG.circle(30).move(ballX, 50).fill("#f00");
|
var ball = mySVG.circle(30).move(ballX, 50).fill("#f00");
|
||||||
window.ball = ball;
|
window.ball = ball;
|
||||||
var square = mySVG.rect(30, 30).move(Math.min(rectX - 50, 950), 50); //square position
|
var square = mySVG.rect(30, 30).move(Math.min(rectX - 50, 950), 50); //square position
|
||||||
config_data["square_pos"] = distanceSetup.round(square.cx(),2);
|
config_data["square_pos"] = distanceSetup.round(square.cx(), 2);
|
||||||
config_data['rectX'] = rectX
|
config_data["rectX"] = rectX;
|
||||||
config_data['ballX'] = ballX
|
config_data["ballX"] = ballX;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
function animateBall() {
|
||||||
function animateBall(){
|
ball
|
||||||
ball.animate(7000).during(
|
.animate(7000)
|
||||||
function(pos){
|
.during(function (pos) {
|
||||||
moveX = - pos*config_data['ballX'];
|
moveX = -pos * config_data["ballX"];
|
||||||
window.moveX = moveX;
|
window.moveX = moveX;
|
||||||
moveY = 0;
|
moveY = 0;
|
||||||
ball.attr({transform:"translate("+moveX+","+moveY+")"});
|
ball.attr({ transform: "translate(" + moveX + "," + moveY + ")" }); //jqueryToVanilla: el.getAttribute('');
|
||||||
|
})
|
||||||
}
|
.loop(true, false)
|
||||||
).loop(true, false).
|
.after(function () {
|
||||||
after(function(){
|
animateBall();
|
||||||
animateBall();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//disable the button after clicked once.
|
//disable the button after clicked once.
|
||||||
$("#start_ball").attr("disabled", true);
|
$("#start_ball").attr("disabled", true); // el.getAttribute('');
|
||||||
$('#start_ball').css("display", "none");
|
$("#start_ball").css("display", "none"); // document.querySelector('#start_ball').style.display = 'none';
|
||||||
};
|
}
|
||||||
|
|
||||||
function recordPosition(event, angle=13.5) {
|
function recordPosition(event, angle = 13.5) {
|
||||||
// angle: define horizontal blind spot entry point position in degrees.
|
// angle: define horizontal blind spot entry point position in degrees.
|
||||||
if (event.keyCode == '32') { //Press "Space"
|
if (event.keyCode == "32") {
|
||||||
|
//Press "Space"
|
||||||
|
|
||||||
config_data["ball_pos"].push(distanceSetup.round((ball.cx() + moveX),2));
|
config_data["ball_pos"].push(distanceSetup.round(ball.cx() + moveX, 2));
|
||||||
var sum = config_data["ball_pos"].reduce((a, b) => a + b, 0);
|
var sum = config_data["ball_pos"].reduce((a, b) => a + b, 0);
|
||||||
var ballPosLen = config_data["ball_pos"].length;
|
var ballPosLen = config_data["ball_pos"].length;
|
||||||
config_data["avg_ball_pos"] = distanceSetup.round(sum/ballPosLen, 2);
|
config_data["avg_ball_pos"] = distanceSetup.round(sum / ballPosLen, 2);
|
||||||
var ball_sqr_distance = (config_data["square_pos"]-config_data["avg_ball_pos"])/trial_data["px2mm"];
|
var ball_sqr_distance =
|
||||||
var viewDistance = ball_sqr_distance/Math.radians(angle)
|
(config_data["square_pos"] - config_data["avg_ball_pos"]) /
|
||||||
trial_data["view_dist_mm"] = distanceSetup.round(viewDistance, 2);
|
trial_data["px2mm"];
|
||||||
|
var viewDistance = ball_sqr_distance / Math.radians(angle);
|
||||||
|
trial_data["view_dist_mm"] = distanceSetup.round(viewDistance, 2);
|
||||||
|
|
||||||
//counter and stop
|
//counter and stop
|
||||||
var counter = Number($('#click').text());
|
var counter = Number($("#click").text());
|
||||||
counter = counter - 1;
|
counter = counter - 1;
|
||||||
$('#click').text(Math.max(counter, 0));
|
$("#click").text(Math.max(counter, 0)); // jqueryToVanilla: document.querySelector("#click").textContent = Math.max(counter, 0);
|
||||||
if (counter <= 0) {
|
if (counter <= 0) {
|
||||||
ball.stop();
|
ball.stop();
|
||||||
|
|
||||||
// Disable space key
|
// Disable space key
|
||||||
$('html').bind('keydown', function(e)
|
$("html").bind("keydown", function (e) {
|
||||||
{
|
// jqueryToVanilla
|
||||||
if (e.keyCode == 32) {return false;}
|
if (e.keyCode == 32) {
|
||||||
});
|
return false;
|
||||||
|
|
||||||
// Display data
|
|
||||||
$('#info').css("visibility", "visible");
|
|
||||||
$('#info-h').append(trial_data["view_dist_mm"]/10)
|
|
||||||
|
|
||||||
$('#proceed').css("display", "inline");
|
|
||||||
|
|
||||||
return //trial_data.viewing_distance_cm;
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
ball.stop();
|
// Display data
|
||||||
animateBall();
|
$("#info").css("visibility", "visible"); // jqueryToVanilla: document.querySelector('#info').style.visibility = 'visible';
|
||||||
|
$("#info-h").append(trial_data["view_dist_mm"] / 10); // jqueryToVanilla(2 lines of code): var element = document.createElement("div");
|
||||||
|
// document.querySelector(".container").appendChild(element);
|
||||||
|
|
||||||
|
$("#proceed").css("display", "inline"); // jqueryToVanilla: document.querySelector('#info').style.display = 'inline';
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
ball.stop();
|
||||||
|
animateBall();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//helper function for radians
|
//helper function for radians
|
||||||
// Converts from degrees to radians.
|
// Converts from degrees to radians.
|
||||||
Math.radians = function(degrees) {
|
Math.radians = function (degrees) {
|
||||||
return degrees * Math.PI / 180;
|
return (degrees * Math.PI) / 180;
|
||||||
};
|
};
|
||||||
|
|
||||||
return plugin;
|
|
||||||
|
|
||||||
|
return plugin;
|
||||||
})();
|
})();
|
||||||
|
Loading…
Reference in New Issue
Block a user