mirror of
https://github.com/jspsych/jsPsych.git
synced 2025-05-10 11:10:54 +00:00
add resize plugin #352
This commit is contained in:
parent
f339d6d558
commit
84de9aed7e
30
docs/markdown_docs/plugins/jspsych-resize.md
Normal file
30
docs/markdown_docs/plugins/jspsych-resize.md
Normal file
@ -0,0 +1,30 @@
|
||||
# jspsych-resize
|
||||
|
||||
This plugin displays a resizable div container that allows the user to drag until the container is the same size as the item being measured. Once the user measures the item as close as possible, clicking the button sets a scaling factor for the div containing jsPsych content. This causes the stimuli that follow to have a known size, independent of monitor resolution.
|
||||
|
||||
## Parameters
|
||||
|
||||
This table lists the parameters associated with this plugin. Parameters with a default value of *undefined* must be specified. Other parameters can be left unspecified if the default value is acceptable.
|
||||
|
||||
Parameter | Type | Default Value | Description
|
||||
----------|------|---------------|------------
|
||||
item_height | numeric | 1 | The height of the item to be measured. Any units can be used as long as you are consistent with using the same units for all parameters.
|
||||
item_width | numeric | 1 | The width of the item to be measured.
|
||||
pixels_per_unit | numeric | 100 | After the scaling factor is applied, this many pixels will equal one unit of measurement.
|
||||
prompt | string | `''` | HTML content to display below the resizable box, and above the button.
|
||||
button_text | string | `'Done'` | Label to display on the button to complete calibration.
|
||||
starting_size | numeric | 100 | The initial size of the box, in pixels, along the largest dimension. The aspect ratio will be set automatically to match the item width and height.
|
||||
|
||||
## Examples
|
||||
|
||||
#### Measuring a credit card and resizing the display to have 150 pixels equal an inch.
|
||||
|
||||
```javascript
|
||||
var inputs = {
|
||||
type: 'resize',
|
||||
item_width: 3 + 3/8,
|
||||
item_height: 2 + 1/8,
|
||||
prompt: "<p>Click and drag the lower right corner of the box until the box is the same size as a credit card held up to the screen.</p>",
|
||||
pixels_per_unit: 150
|
||||
};
|
||||
```
|
@ -75,7 +75,8 @@ This table is a description of all plugins that are currently bundled with jsPsy
|
||||
[jspsych‑instructions](jspsych-instructions) | For displaying instructions to the subject.
|
||||
[jspsych‑multi‑stim‑multi‑response](jspsych-multi-stim-multi-response) | A more generalized version of the single-stim plugin. Can display multiple stimuli in a single trial, and collect multiple responses in a single trial.
|
||||
[jspsych‑palmer](jspsych-palmer) | Shows grid-like stimuli inspired by Stephen Palmer's work. The stimuli are editable: subjects can add and subtract parts interactively. Also contains a method for generating the HTML code to render the stimuli, allowing them to be used in other plugins.
|
||||
[jspsych‑reconstruction](jspsych-reconstruction) | The subject interacts with a stimulus by modifying a parameter of the stimulus and observing the change in the stimulus in real-time.
|
||||
[jspsych‑reconstruction](jspsych-reconstruction) | The subject interacts with a stimulus by modifying a parameter of the stimulus and observing the change in the stimulus in real-time.
|
||||
[jspsych‑resize](jspsych-resize) | Calibrate the display so that materials display with a known physical size.
|
||||
[jspsych‑same‑different](jspsych-same-different) | A same-different judgment task. A stimulus is shown, followed by a brief gap, and then another stimulus is shown. The subject indicates whether the stimuli are the same or different.
|
||||
[jspsych‑similarity](jspsych-similarity) | Two stimuli are shown sequentially, and the subject indicates how similar they are by dragging a slider object.
|
||||
[jspsych‑single‑audio](jspsych-single-audio) | A basic plugin for playing an audio stimulus and getting a keyboard response.
|
||||
|
@ -46,6 +46,7 @@ pages:
|
||||
- 'jspsych-multi-stim-multi-response': 'plugins/jspsych-multi-stim-multi-response.md'
|
||||
- 'jspsych-palmer': 'plugins/jspsych-palmer.md'
|
||||
- 'jspsych-reconstruction': 'plugins/jspsych-reconstruction.md'
|
||||
- 'jspsych-resize': 'plugins/jspsych-resize.md'
|
||||
- 'jspsych-same-different': 'plugins/jspsych-same-different.md'
|
||||
- 'jspsych-similarity': 'plugins/jspsych-similarity.md'
|
||||
- 'jspsych-single-audio': 'plugins/jspsych-single-audio.md'
|
||||
|
34
examples/jspsych-resize.html
Normal file
34
examples/jspsych-resize.html
Normal file
@ -0,0 +1,34 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../jspsych.js"></script>
|
||||
<script src="../plugins/jspsych-resize.js"></script>
|
||||
<script src="../plugins/jspsych-single-stim.js"></script>
|
||||
<link rel="stylesheet" href="../css/jspsych.css"></link>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
<script>
|
||||
|
||||
var inputs = {
|
||||
type: 'resize',
|
||||
item_width: 3 + 3/8,
|
||||
item_height: 2 + 1/8,
|
||||
prompt: "<p>Click and drag the lower right corner of the box until the box is the same size as a credit card held up to the screen.</p>",
|
||||
pixels_per_unit: 642/4
|
||||
};
|
||||
|
||||
var image_display = {
|
||||
type: 'single-stim',
|
||||
stimulus: 'img/happy_face_4.jpg',
|
||||
prompt: '<p>If scaling worked, then the image above should be 4 inches wide.</p>',
|
||||
}
|
||||
|
||||
jsPsych.init({
|
||||
timeline: [inputs, image_display],
|
||||
on_finish: function() {
|
||||
jsPsych.data.displayData();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</html>
|
135
plugins/jspsych-resize.js
Normal file
135
plugins/jspsych-resize.js
Normal file
@ -0,0 +1,135 @@
|
||||
/**
|
||||
* jspsych-resize
|
||||
* Steve Chao
|
||||
*
|
||||
* plugin for controlling the real world size of the display
|
||||
*
|
||||
* documentation: docs.jspsych.org
|
||||
*
|
||||
**/
|
||||
|
||||
jsPsych.plugins["resize"] = (function() {
|
||||
|
||||
var plugin = {};
|
||||
|
||||
plugin.trial = function(display_element, trial) {
|
||||
|
||||
// if any trial variables are functions
|
||||
// this evaluates the function and replaces
|
||||
// it with the output of the function
|
||||
trial = jsPsych.pluginAPI.evaluateFunctionParameters(trial);
|
||||
|
||||
// default trial paramters
|
||||
trial.item_height = trial.item_height || 1;
|
||||
trial.item_width = trial.item_width || 1;
|
||||
trial.prompt = trial.prompt || ' ';
|
||||
trial.pixels_per_unit = trial.pixels_per_unit || 100;
|
||||
trial.starting_size = trial.starting_size || 100;
|
||||
trial.button_text = trial.button_text || "Done";
|
||||
|
||||
var aspect_ratio = trial.item_width / trial.item_height;
|
||||
|
||||
// variables to determine div size
|
||||
if(trial.item_width >= trial.item_height){
|
||||
var start_div_width = trial.starting_size;
|
||||
var start_div_height = Math.round(trial.starting_size / aspect_ratio);
|
||||
} else {
|
||||
var start_div_height = trial.starting_size;
|
||||
var start_div_width = Math.round(trial.starting_size * aspect_ratio);
|
||||
}
|
||||
|
||||
// create html for display
|
||||
var html ='<div id="jspsych-resize-div" style="border: 2px solid steelblue; height: '+start_div_height+'px; width:'+start_div_width+'px; margin: 7px auto; background-color: lightsteelblue; position: relative;">';
|
||||
html += '<div id="jspsych-resize-handle" style="cursor: nwse-resize; background-color: steelblue; width: 10px; height: 10px; border: 2px solid lightsteelblue; position: absolute; bottom: 0; right: 0;"></div>';
|
||||
html += '</div>';
|
||||
html += trial.prompt;
|
||||
html += '<a class="jspsych-btn" id="jspsych-resize-btn">'+trial.button_text+'</a>';
|
||||
|
||||
// render
|
||||
display_element.innerHTML = html;
|
||||
|
||||
// listens for the click
|
||||
document.getElementById("jspsych-resize-btn").addEventListener('click', function() {
|
||||
scale();
|
||||
end_trial();
|
||||
});
|
||||
|
||||
var dragging = false;
|
||||
var origin_x, origin_y;
|
||||
var cx, cy;
|
||||
|
||||
var mousedownevent = function(e){
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
dragging = true;
|
||||
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);
|
||||
|
||||
var mouseupevent = function(e){
|
||||
dragging = false;
|
||||
}
|
||||
|
||||
document.addEventListener('mouseup', mouseupevent);
|
||||
|
||||
var scale_div = display_element.querySelector('#jspsych-resize-div');
|
||||
|
||||
var resizeevent = function(e){
|
||||
if(dragging){
|
||||
var dx = (e.pageX - origin_x)*2;
|
||||
var dy = (e.pageY - origin_y)*2;
|
||||
|
||||
if(dx >= dy){
|
||||
scale_div.style.width = Math.max(10, cx+dx) + "px";
|
||||
scale_div.style.height = Math.round(Math.max(10, cx+dx) / aspect_ratio ) + "px";
|
||||
} else {
|
||||
scale_div.style.height = Math.max(10, cy+dy) + "px";
|
||||
scale_div.style.width = Math.round(aspect_ratio * Math.max(10, cy+dy)) + "px";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('mousemove', resizeevent);
|
||||
|
||||
// scales the stimulus
|
||||
var scale_factor;
|
||||
var final_height_px, final_width_px;
|
||||
function scale() {
|
||||
final_width_px = scale_div.offsetWidth;
|
||||
final_height_px = scale_div.offsetHeight;
|
||||
|
||||
var pixels_unit_screen = final_width_px / trial.item_width;
|
||||
|
||||
scale_factor = pixels_unit_screen / trial.pixels_per_unit;
|
||||
document.getElementById("jspsych-content").style.transform = "scale(" + scale_factor + ")";
|
||||
};
|
||||
|
||||
|
||||
// function to end trial
|
||||
function end_trial() {
|
||||
|
||||
// clear document event listeners
|
||||
document.removeEventListener('mousemove', resizeevent);
|
||||
document.removeEventListener('mouseup', mouseupevent);
|
||||
|
||||
// clear the screen
|
||||
display_element.innerHTML = '';
|
||||
|
||||
// finishes trial
|
||||
|
||||
var trial_data = {
|
||||
'final_height_px': final_height_px,
|
||||
'final_width_px': final_width_px,
|
||||
'scale_factor': scale_factor
|
||||
}
|
||||
|
||||
jsPsych.finishTrial(trial_data);
|
||||
}
|
||||
};
|
||||
|
||||
return plugin;
|
||||
})();
|
Loading…
Reference in New Issue
Block a user