Merge pull request #2 from GEJ1/GEJ1/master

Gej1/master
This commit is contained in:
Josh de Leeuw 2021-02-18 10:43:42 -05:00 committed by GitHub
commit e2d66c4de1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 118 additions and 117 deletions

View File

@ -4,11 +4,7 @@
<meta content="text/html;charset=utf-8" http-equiv="Content-Type"> <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding"> <meta content="utf-8" http-equiv="encoding">
<!-- css --> <!-- SVG.js -->
<!--<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link href="css/jquery-ui.css" rel="stylesheet" type="text/css">-->
<!-- SVG.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/svg.js/2.6.3/svg.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/svg.js/2.6.3/svg.min.js"></script>
<!-- JsPsych --> <!-- JsPsych -->

View File

@ -105,7 +105,7 @@ jsPsych.plugins["virtual-chinrest"] = (function () {
}, },
viewing_distance_report: { viewing_distance_report: {
type: jsPsych.plugins.parameterType.STRING, type: jsPsych.plugins.parameterType.STRING,
default: "<p>Based on your responses, you are sitting about <span id='distance-estimate' style='font-weight: bold;'></span> from the screen</p><p>Does that seem about right?</p>", default: "<p>Based on your responses, you are sitting about <span id='distance-estimate' style='font-weight: bold;'></span> from the screen.</p><p>Does that seem about right?</p>",
description: description:
'If "none" is given, viewing distance will not be reported to the participant', 'If "none" is given, viewing distance will not be reported to the participant',
}, },
@ -128,24 +128,18 @@ jsPsych.plugins["virtual-chinrest"] = (function () {
} }
/* some additional parameter configuration */ /* some additional parameter configuration */
var w = window.innerWidth;
var h = window.innerHeight;
const screen_size_px = [w, "x", h];
let trial_data = { let 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 config_data = { let blindspot_config_data = {
ball_pos: [], ball_pos: [],
slider_clck: false, slider_clck: false,
}; };
let aspect_ratio = 1; let aspect_ratio = trial.item_width_mm / trial.item_height_mm;
aspect_ratio = trial.item_width_mm / trial.item_height_mm;
const start_div_height = const start_div_height =
aspect_ratio < 1 aspect_ratio < 1
? trial.item_init_size ? trial.item_init_size
@ -160,7 +154,7 @@ jsPsych.plugins["virtual-chinrest"] = (function () {
let pagesize_content = ` let pagesize_content = `
<div id="page-size"> <div id="page-size">
<div id="item" style="border: none; height: ${start_div_height}px; width: ${start_div_width}px; margin: 5px auto; background-color: none; position: relative; background-image: url(${trial.item_path}); background-size: 100% auto; background-repeat: no-repeat;"> <div id="item" style="border: none; height: ${start_div_height}px; width: ${start_div_width}px; margin: 5px auto; background-color: none; position: relative; 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 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> </div>
${trial.adjustment_prompt} ${trial.adjustment_prompt}
@ -186,7 +180,7 @@ jsPsych.plugins["virtual-chinrest"] = (function () {
${trial.viewing_distance_report} ${trial.viewing_distance_report}
</b> </b>
</div>` : '' </div>` : ''
} }
</div>` </div>`
/* create content for final report screen */ /* create content for final report screen */
@ -200,73 +194,84 @@ jsPsych.plugins["virtual-chinrest"] = (function () {
</div> </div>
` `
display_element.innerHTML = `<div id="content" style="width: 900px; margin: 0 auto;"></div>`
/* show first screen */
display_element.innerHTML = `
<div id="content" style="width: 900px; margin: 0 auto;">
${pagesize_content}
</div>
`
const start_time = performance.now(); const start_time = performance.now();
startResizePhase();
// Event listeners for mouse-based resize function startResizePhase() {
let dragging = false; display_element.querySelector('#content').innerHTML = pagesize_content;
let origin_x, origin_y;
let cx, cy;
const scale_div = display_element.querySelector("#item");
function mouseupevent() { // Event listeners for mouse-based resize
dragging = false; let dragging = false;
}; let origin_x, origin_y;
document.addEventListener("mouseup", mouseupevent); let cx, cy;
const scale_div = display_element.querySelector("#item");
function mousedownevent(e) { function mouseupevent() {
e.preventDefault(); dragging = false;
dragging = true; };
origin_x = e.pageX; document.addEventListener("mouseup", mouseupevent);
origin_y = e.pageY;
cx = parseInt(scale_div.style.width);
cy = parseInt(scale_div.style.height);
};
display_element.querySelector("#jspsych-resize-handle").addEventListener("mousedown", mousedownevent);
function resizeevent(e) { function mousedownevent(e) {
if (dragging) { e.preventDefault();
let dx = e.pageX - origin_x; dragging = true;
let dy = e.pageY - origin_y; origin_x = e.pageX;
origin_y = e.pageY;
cx = parseInt(scale_div.style.width);
cy = parseInt(scale_div.style.height);
};
display_element.querySelector("#jspsych-resize-handle").addEventListener("mousedown", mousedownevent);
if (Math.abs(dx) >= Math.abs(dy)) { function resizeevent(e) {
scale_div.style.width = if (dragging) {
Math.round(Math.max(20, cx + dx * 2)) + "px"; let dx = e.pageX - origin_x;
scale_div.style.height = let dy = e.pageY - origin_y;
Math.round(Math.max(20, cx + dx * 2) / aspect_ratio) + "px";
} else { if (Math.abs(dx) >= Math.abs(dy)) {
scale_div.style.height = scale_div.style.width =
Math.round(Math.max(20, cy + dy * 2)) + "px"; Math.round(Math.max(20, cx + dx * 2)) + "px";
scale_div.style.width = scale_div.style.height =
Math.round(aspect_ratio * Math.max(20, cy + dy * 2)) + "px"; Math.round(Math.max(20, cx + dx * 2) / aspect_ratio) + "px";
} else {
scale_div.style.height =
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.querySelector("#end_resize_phase").addEventListener("click", finishResizePhase);
} }
display_element.addEventListener("mousemove", resizeevent);
display_element.querySelector("#end_resize_phase").addEventListener("click", finishResizePhase); function finishResizePhase() {
// add item width info to data
function finishResizePhase(){ const item_width_px = getScaledItemWidth();
trial_data["item_width_px"] = Math.round(item_width_px);
const px2mm = convertPixelsToMM(item_width_px);
trial_data["px2mm"] = accurateRound(px2mm, 2);
// check what to do next // check what to do next
if (trial.blindspot_reps > 0) { if (trial.blindspot_reps > 0) {
get_item_width(); // modifies trial data startBlindSpotPhase();
configureBlindSpot();
} else { } else {
distanceSetup.px2mm(get_item_width());
endTrial(); endTrial();
} }
} }
function configureBlindSpot() { function startBlindSpotPhase() {
// reset the config data in case we are redoing the measurement
blindspot_config_data = {
ball_pos: [],
slider_clck: false,
};
// add the content to the page
document.querySelector("#content").innerHTML = blindspot_content; document.querySelector("#content").innerHTML = blindspot_content;
// draw the ball and fixation square
drawBall(); drawBall();
// wait for a spacebar to begin the animations
jsPsych.pluginAPI.getKeyboardResponse({ jsPsych.pluginAPI.getKeyboardResponse({
callback_function: startBall, callback_function: startBall,
valid_responses: ['space'], valid_responses: ['space'],
@ -276,8 +281,7 @@ jsPsych.plugins["virtual-chinrest"] = (function () {
}) })
} }
var ball_position_listener = null; function startBall() {
function startBall(){
ball_position_listener = jsPsych.pluginAPI.getKeyboardResponse({ ball_position_listener = jsPsych.pluginAPI.getKeyboardResponse({
callback_function: recordPosition, callback_function: recordPosition,
valid_responses: ['space'], valid_responses: ['space'],
@ -288,7 +292,7 @@ jsPsych.plugins["virtual-chinrest"] = (function () {
animateBall(); animateBall();
} }
function finishBlindSpotPhase(){ function finishBlindSpotPhase() {
ball.stop(); ball.stop();
jsPsych.pluginAPI.cancelAllKeyboardResponses(); jsPsych.pluginAPI.cancelAllKeyboardResponses();
@ -296,20 +300,18 @@ jsPsych.plugins["virtual-chinrest"] = (function () {
showReport(); showReport();
} }
function showReport(){ function showReport() {
// Display data // Display data
display_element.querySelector("#content").innerHTML = report_content; display_element.querySelector("#content").innerHTML = report_content;
display_element.querySelector('#distance-estimate').innerHTML = `${Math.round(trial_data["view_dist_mm"] / 10)} cm` display_element.querySelector('#distance-estimate').innerHTML = `
${Math.round(trial_data["view_dist_mm"] / 10)} cm (${Math.round(trial_data["view_dist_mm"]*0.0393701)} inches)
`
display_element.querySelector("#redo_blindspot").addEventListener('click', configureBlindSpot) display_element.querySelector("#redo_blindspot").addEventListener('click', startBlindSpotPhase)
display_element.querySelector("#proceed").addEventListener('click', endTrial); display_element.querySelector("#proceed").addEventListener('click', endTrial);
} }
function endTrial() { function computeTransformation() {
// finish trial
trial_data.rt = performance.now() - start_time;
display_element.innerHTML = "";
trial_data.item_width_deg = trial_data.item_width_deg =
(2 * (2 *
Math.atan( Math.atan(
@ -357,43 +359,49 @@ jsPsych.plugins["virtual-chinrest"] = (function () {
delete trial_data.px2deg; delete trial_data.px2deg;
delete trial_data.item_width_deg; delete trial_data.item_width_deg;
} }
// NEED TO REMOVE EVENT LISTENERS
jsPsych.finishTrial(trial_data);
jsPsych.pluginAPI.cancelAllKeyboardResponses();
} }
function get_item_width() { function endTrial() {
const item_width_px = parseFloat(
getComputedStyle(document.querySelector("#item"), null).width.replace(
"px",
""
)
);
trial_data["item_width_px"] = distanceSetup.round(item_width_px, 2); // finish trial
return item_width_px; trial_data.rt = performance.now() - start_time;
// remove lingering event listeners, just in case
jsPsych.pluginAPI.cancelAllKeyboardResponses();
// compute final data
computeTransformation();
// clear the display
display_element.innerHTML = "";
// finish the trial
jsPsych.finishTrial(trial_data);
}
function getScaledItemWidth() {
return document.querySelector('#item').getBoundingClientRect().width;
} }
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 = trial_data["item_width_px"]; const rectX = trial_data["px2mm"] * 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); blindspot_config_data["square_pos"] = accurateRound(square.cx(), 2);
config_data["rectX"] = rectX; blindspot_config_data["rectX"] = rectX;
config_data["ballX"] = ballX; blindspot_config_data["ballX"] = ballX;
} }
function animateBall() { function animateBall() {
ball ball
.animate(7000) .animate(7000)
.during(function (pos) { .during(function (pos) {
moveX = -pos * config_data["ballX"]; moveX = -pos * blindspot_config_data["ballX"];
window.moveX = moveX; window.moveX = moveX;
moveY = 0; moveY = 0;
ball.attr({ transform: "translate(" + moveX + "," + moveY + ")" }); //jqueryToVanilla: el.getAttribute(''); ball.attr({ transform: "translate(" + moveX + "," + moveY + ")" }); //jqueryToVanilla: el.getAttribute('');
@ -404,19 +412,19 @@ jsPsych.plugins["virtual-chinrest"] = (function () {
}); });
} }
function recordPosition(info) { function recordPosition() {
// angle: define horizontal blind spot entry point position in degrees. // angle: define horizontal blind spot entry point position in degrees.
const angle = 13.5; const angle = 13.5;
config_data["ball_pos"].push(distanceSetup.round(ball.cx() + moveX, 2)); blindspot_config_data["ball_pos"].push(accurateRound(ball.cx() + moveX, 2));
var sum = config_data["ball_pos"].reduce((a, b) => a + b, 0); var sum = blindspot_config_data["ball_pos"].reduce((a, b) => a + b, 0);
var ballPosLen = config_data["ball_pos"].length; var ballPosLen = blindspot_config_data["ball_pos"].length;
config_data["avg_ball_pos"] = distanceSetup.round(sum / ballPosLen, 2); blindspot_config_data["avg_ball_pos"] = accurateRound(sum / ballPosLen, 2);
var ball_sqr_distance = var ball_sqr_distance =
(config_data["square_pos"] - config_data["avg_ball_pos"]) / (blindspot_config_data["square_pos"] - blindspot_config_data["avg_ball_pos"]) /
trial_data["px2mm"]; trial_data["px2mm"];
var viewDistance = ball_sqr_distance / Math.radians(angle); var viewDistance = ball_sqr_distance / Math.radians(angle);
trial_data["view_dist_mm"] = distanceSetup.round(viewDistance, 2); trial_data["view_dist_mm"] = accurateRound(viewDistance, 2);
//counter and stop //counter and stop
var counter = Number(document.querySelector("#click").textContent); var counter = Number(document.querySelector("#click").textContent);
@ -432,17 +440,14 @@ jsPsych.plugins["virtual-chinrest"] = (function () {
} }
var distanceSetup = { function convertPixelsToMM(item_width_px){
round: function (value, decimals) { const px2mm = item_width_px / trial_data["item_width_mm"];
return Number(Math.round(value + "e" + decimals) + "e-" + decimals); return px2mm;
},
px2mm: function (item_width_px) {
const px2mm = item_width_px / trial_data["item_width_mm"];
trial_data["px2mm"] = distanceSetup.round(px2mm, 2);
return px2mm;
}
} }
function accurateRound(value, decimals){
return Number(Math.round(value+'e'+decimals)+'e-'+decimals);
}
}; };