mirror of
https://github.com/jspsych/jsPsych.git
synced 2025-05-10 11:10:54 +00:00
remove svg dependency, update plugin behavior
This commit is contained in:
parent
5b1a967be3
commit
99bf2924be
10
.changeset/funny-beans-talk.md
Normal file
10
.changeset/funny-beans-talk.md
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
"@jspsych/plugin-virtual-chinrest": major
|
||||
---
|
||||
|
||||
Several changes to this plugin:
|
||||
|
||||
* Removed dependency on svg.js
|
||||
* Added a reset between each blind spot measurement for clarity
|
||||
* Moved starting location of square and dot to right edge of screen for maximum compatibility with large viewing distances
|
||||
* Refactored code
|
@ -11,14 +11,6 @@ The plugin works in two phases.
|
||||
|
||||
**Phase 2**. To measure the participant's viewing distance from their screen we use a [blind spot](<https://en.wikipedia.org/wiki/Blind_spot_(vision)>) task. Participants are asked to focus on a black square on the screen with their right eye closed, while a red dot repeatedly sweeps from right to left. They press the spacebar on their keyboard whenever they perceive that the red dot has disappeared. This part allows the plugin to use the distance between the black square and the red dot when it disappears from eyesight to estimate how far the participant is from the monitor. This estimation assumes that the blind spot is located at 13.5° temporally.
|
||||
|
||||
## Dependency
|
||||
|
||||
This plugin requires the SVG.js library, available at [https://svgjs.com](https://svgjs.com/docs/3.0/) or via the CDN link below. You must include the library in the `<head>` section of your experiment page.
|
||||
|
||||
```html
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/svg.js/2.6.3/svg.min.js"></script>
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
Parameters can be left unspecified if the default value is acceptable.
|
||||
|
@ -45,7 +45,7 @@
|
||||
// note: pixels_per_unit will be ignored
|
||||
let no_resize = {
|
||||
type: jsPsychVirtualChinrest,
|
||||
blindspot_reps: 1,
|
||||
blindspot_reps: 3,
|
||||
resize_units: "none",
|
||||
pixels_per_unit: 50
|
||||
};
|
||||
@ -65,7 +65,7 @@
|
||||
prompt: '<p>The stimulus above should be 4cm x 4cm if resizing worked properly.</p>'
|
||||
};
|
||||
|
||||
jsPsych.run([no_resize, validation_trial]); // deg_resize, no_resize, error_trial
|
||||
jsPsych.run([cm_resize, validation_trial]); // deg_resize, no_resize, error_trial
|
||||
|
||||
</script>
|
||||
</html>
|
||||
|
290
package-lock.json
generated
290
package-lock.json
generated
@ -15,7 +15,7 @@
|
||||
"lint-staged": "^12.3.5",
|
||||
"prettier": "^2.5.1",
|
||||
"prettier-plugin-import-sort": "^0.0.7",
|
||||
"turbo": "^1.1.6"
|
||||
"turbo": "^1.1.10"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0",
|
||||
@ -14115,40 +14115,185 @@
|
||||
}
|
||||
},
|
||||
"node_modules/turbo": {
|
||||
"version": "1.1.6",
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo/-/turbo-1.1.10.tgz",
|
||||
"integrity": "sha512-y8vx8uIyBRFI3aFjZ3PeGaOvYtNk6t7xNLzRsPY+xtnknTeqdBad56ElS8z+j0RyVwKCvI+wgvTHGkEle4VnJA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MPL-2.0",
|
||||
"bin": {
|
||||
"turbo": "bin/turbo"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"turbo-darwin-64": "1.1.6",
|
||||
"turbo-darwin-arm64": "1.1.6",
|
||||
"turbo-freebsd-64": "1.1.6",
|
||||
"turbo-freebsd-arm64": "1.1.6",
|
||||
"turbo-linux-32": "1.1.6",
|
||||
"turbo-linux-64": "1.1.6",
|
||||
"turbo-linux-arm": "1.1.6",
|
||||
"turbo-linux-arm64": "1.1.6",
|
||||
"turbo-linux-mips64le": "1.1.6",
|
||||
"turbo-linux-ppc64le": "1.1.6",
|
||||
"turbo-windows-32": "1.1.6",
|
||||
"turbo-windows-64": "1.1.6"
|
||||
"turbo-darwin-64": "1.1.10",
|
||||
"turbo-darwin-arm64": "1.1.10",
|
||||
"turbo-freebsd-64": "1.1.10",
|
||||
"turbo-freebsd-arm64": "1.1.10",
|
||||
"turbo-linux-32": "1.1.10",
|
||||
"turbo-linux-64": "1.1.10",
|
||||
"turbo-linux-arm": "1.1.10",
|
||||
"turbo-linux-arm64": "1.1.10",
|
||||
"turbo-linux-mips64le": "1.1.10",
|
||||
"turbo-linux-ppc64le": "1.1.10",
|
||||
"turbo-windows-32": "1.1.10",
|
||||
"turbo-windows-64": "1.1.10"
|
||||
}
|
||||
},
|
||||
"node_modules/turbo-linux-64": {
|
||||
"version": "1.1.6",
|
||||
"node_modules/turbo-darwin-64": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo-darwin-64/-/turbo-darwin-64-1.1.10.tgz",
|
||||
"integrity": "sha512-MY/1mHg+tS/GaZKG805e5JSGNS8A4j/M2GzLwCbNL+lwGMfneNASri1vAd80ss3T2MgMsfsFMVyIQJljqpDBvA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
"node_modules/turbo-darwin-arm64": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo-darwin-arm64/-/turbo-darwin-arm64-1.1.10.tgz",
|
||||
"integrity": "sha512-gMPLseYqGKwdy6UHVWKMLA433ZTfQRV5FlYz5n4XVtx30cF6ajOqq12ykeCUUX/lZkH4Uq5zT0tNEYpUhUw7mA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
"node_modules/turbo-freebsd-64": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo-freebsd-64/-/turbo-freebsd-64-1.1.10.tgz",
|
||||
"integrity": "sha512-wra27mvakr5ZFceQnCCSR8gHQtKV8Q0EhtzO/wEdyhEssw0wVaNtMHUOOdvFN0HLmjQmmLZgmfZbURc83UDuZQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
]
|
||||
},
|
||||
"node_modules/turbo-freebsd-arm64": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo-freebsd-arm64/-/turbo-freebsd-arm64-1.1.10.tgz",
|
||||
"integrity": "sha512-J2I76pTwtrEVjHt1+zWY/s/Y0YIGdWHBIWOjhCXi1E8dav98oGw+WUaiFwzAkcksAblOhNpDL3qhnrnm7kHqrg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
]
|
||||
},
|
||||
"node_modules/turbo-linux-32": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo-linux-32/-/turbo-linux-32-1.1.10.tgz",
|
||||
"integrity": "sha512-d1ILhEv2B/lOtpH4niFUKGb8YMU6G7gNCQCY6wG+SXARWJtDti+KiNWESechD5DycCIMgtE40XNy/c1US+LI5g==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/turbo-linux-64": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo-linux-64/-/turbo-linux-64-1.1.10.tgz",
|
||||
"integrity": "sha512-8VEOiNJFNfUMZOyrN32wOcdT1Ik1nlIuTwkO4UeonAJhuWjTvdDLPCQkz0SECTu60q90l6nXCnNYtoZA6LrZzA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/turbo-linux-arm": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo-linux-arm/-/turbo-linux-arm-1.1.10.tgz",
|
||||
"integrity": "sha512-qJ50K/s5MjpHjam+UdnK3GniEIv5XOBCZOGslgMMyz8V/q43vhB9BU9HQODclM89uQgsKxhs8Fue6ytOY4vIpg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/turbo-linux-arm64": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo-linux-arm64/-/turbo-linux-arm64-1.1.10.tgz",
|
||||
"integrity": "sha512-ng3dEEL4SbBudF/UZzsOrfyJh8DLtTHawTepeS30FdtvYuVBXdCPc5BAhbawGoau/2AV4vrN3qzh9e3LCqD6Qg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/turbo-linux-mips64le": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo-linux-mips64le/-/turbo-linux-mips64le-1.1.10.tgz",
|
||||
"integrity": "sha512-Jd4yH7ZEXCo0xmdJWZ6YsyqcNLyL5vRU3j5ZT+1W97YJCT+g+1on3/nd3rBVPzVz52lb8JIqgGtrBrnOO0AWJg==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/turbo-linux-ppc64le": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo-linux-ppc64le/-/turbo-linux-ppc64le-1.1.10.tgz",
|
||||
"integrity": "sha512-YF8+Oi53glqY29O1A7KJsHZxBzeVBobYFnPEXMt8vm+ouuo8kkbxXxShOP4h+33YGEkesTw/CTXtfDC1Xj1hDw==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/turbo-windows-32": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo-windows-32/-/turbo-windows-32-1.1.10.tgz",
|
||||
"integrity": "sha512-IO92tVTCtWVPPgcCjf8J7AmBEcwnjv1zPq7t9GFdqZ/6QA06atgPJNzQ/QvyzbzJgUsJUN2ByzwT04o4QUbrBQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/turbo-windows-64": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo-windows-64/-/turbo-windows-64-1.1.10.tgz",
|
||||
"integrity": "sha512-g/RIXaVDaOgliHEJuOsuB6Tefwue9fXBH1/iIH9dmT3Z7lL0banGh+C10RW6Jd6PBPMoPBWir9PLYuzxoPcCNQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/type": {
|
||||
"version": "1.2.0",
|
||||
"license": "ISC"
|
||||
@ -25552,25 +25697,106 @@
|
||||
}
|
||||
},
|
||||
"turbo": {
|
||||
"version": "1.1.6",
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo/-/turbo-1.1.10.tgz",
|
||||
"integrity": "sha512-y8vx8uIyBRFI3aFjZ3PeGaOvYtNk6t7xNLzRsPY+xtnknTeqdBad56ElS8z+j0RyVwKCvI+wgvTHGkEle4VnJA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"turbo-darwin-64": "1.1.6",
|
||||
"turbo-darwin-arm64": "1.1.6",
|
||||
"turbo-freebsd-64": "1.1.6",
|
||||
"turbo-freebsd-arm64": "1.1.6",
|
||||
"turbo-linux-32": "1.1.6",
|
||||
"turbo-linux-64": "1.1.6",
|
||||
"turbo-linux-arm": "1.1.6",
|
||||
"turbo-linux-arm64": "1.1.6",
|
||||
"turbo-linux-mips64le": "1.1.6",
|
||||
"turbo-linux-ppc64le": "1.1.6",
|
||||
"turbo-windows-32": "1.1.6",
|
||||
"turbo-windows-64": "1.1.6"
|
||||
"turbo-darwin-64": "1.1.10",
|
||||
"turbo-darwin-arm64": "1.1.10",
|
||||
"turbo-freebsd-64": "1.1.10",
|
||||
"turbo-freebsd-arm64": "1.1.10",
|
||||
"turbo-linux-32": "1.1.10",
|
||||
"turbo-linux-64": "1.1.10",
|
||||
"turbo-linux-arm": "1.1.10",
|
||||
"turbo-linux-arm64": "1.1.10",
|
||||
"turbo-linux-mips64le": "1.1.10",
|
||||
"turbo-linux-ppc64le": "1.1.10",
|
||||
"turbo-windows-32": "1.1.10",
|
||||
"turbo-windows-64": "1.1.10"
|
||||
}
|
||||
},
|
||||
"turbo-darwin-64": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo-darwin-64/-/turbo-darwin-64-1.1.10.tgz",
|
||||
"integrity": "sha512-MY/1mHg+tS/GaZKG805e5JSGNS8A4j/M2GzLwCbNL+lwGMfneNASri1vAd80ss3T2MgMsfsFMVyIQJljqpDBvA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"turbo-darwin-arm64": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo-darwin-arm64/-/turbo-darwin-arm64-1.1.10.tgz",
|
||||
"integrity": "sha512-gMPLseYqGKwdy6UHVWKMLA433ZTfQRV5FlYz5n4XVtx30cF6ajOqq12ykeCUUX/lZkH4Uq5zT0tNEYpUhUw7mA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"turbo-freebsd-64": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo-freebsd-64/-/turbo-freebsd-64-1.1.10.tgz",
|
||||
"integrity": "sha512-wra27mvakr5ZFceQnCCSR8gHQtKV8Q0EhtzO/wEdyhEssw0wVaNtMHUOOdvFN0HLmjQmmLZgmfZbURc83UDuZQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"turbo-freebsd-arm64": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo-freebsd-arm64/-/turbo-freebsd-arm64-1.1.10.tgz",
|
||||
"integrity": "sha512-J2I76pTwtrEVjHt1+zWY/s/Y0YIGdWHBIWOjhCXi1E8dav98oGw+WUaiFwzAkcksAblOhNpDL3qhnrnm7kHqrg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"turbo-linux-32": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo-linux-32/-/turbo-linux-32-1.1.10.tgz",
|
||||
"integrity": "sha512-d1ILhEv2B/lOtpH4niFUKGb8YMU6G7gNCQCY6wG+SXARWJtDti+KiNWESechD5DycCIMgtE40XNy/c1US+LI5g==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"turbo-linux-64": {
|
||||
"version": "1.1.6",
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo-linux-64/-/turbo-linux-64-1.1.10.tgz",
|
||||
"integrity": "sha512-8VEOiNJFNfUMZOyrN32wOcdT1Ik1nlIuTwkO4UeonAJhuWjTvdDLPCQkz0SECTu60q90l6nXCnNYtoZA6LrZzA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"turbo-linux-arm": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo-linux-arm/-/turbo-linux-arm-1.1.10.tgz",
|
||||
"integrity": "sha512-qJ50K/s5MjpHjam+UdnK3GniEIv5XOBCZOGslgMMyz8V/q43vhB9BU9HQODclM89uQgsKxhs8Fue6ytOY4vIpg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"turbo-linux-arm64": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo-linux-arm64/-/turbo-linux-arm64-1.1.10.tgz",
|
||||
"integrity": "sha512-ng3dEEL4SbBudF/UZzsOrfyJh8DLtTHawTepeS30FdtvYuVBXdCPc5BAhbawGoau/2AV4vrN3qzh9e3LCqD6Qg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"turbo-linux-mips64le": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo-linux-mips64le/-/turbo-linux-mips64le-1.1.10.tgz",
|
||||
"integrity": "sha512-Jd4yH7ZEXCo0xmdJWZ6YsyqcNLyL5vRU3j5ZT+1W97YJCT+g+1on3/nd3rBVPzVz52lb8JIqgGtrBrnOO0AWJg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"turbo-linux-ppc64le": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo-linux-ppc64le/-/turbo-linux-ppc64le-1.1.10.tgz",
|
||||
"integrity": "sha512-YF8+Oi53glqY29O1A7KJsHZxBzeVBobYFnPEXMt8vm+ouuo8kkbxXxShOP4h+33YGEkesTw/CTXtfDC1Xj1hDw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"turbo-windows-32": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo-windows-32/-/turbo-windows-32-1.1.10.tgz",
|
||||
"integrity": "sha512-IO92tVTCtWVPPgcCjf8J7AmBEcwnjv1zPq7t9GFdqZ/6QA06atgPJNzQ/QvyzbzJgUsJUN2ByzwT04o4QUbrBQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"turbo-windows-64": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/turbo-windows-64/-/turbo-windows-64-1.1.10.tgz",
|
||||
"integrity": "sha512-g/RIXaVDaOgliHEJuOsuB6Tefwue9fXBH1/iIH9dmT3Z7lL0banGh+C10RW6Jd6PBPMoPBWir9PLYuzxoPcCNQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
|
@ -29,7 +29,7 @@
|
||||
"lint-staged": "^12.3.5",
|
||||
"prettier": "^2.5.1",
|
||||
"prettier-plugin-import-sort": "^0.0.7",
|
||||
"turbo": "^1.1.6"
|
||||
"turbo": "^1.1.10"
|
||||
},
|
||||
"prettier": {
|
||||
"printWidth": 100
|
||||
|
@ -147,6 +147,12 @@ declare global {
|
||||
class VirtualChinrestPlugin implements JsPsychPlugin<Info> {
|
||||
static info = info;
|
||||
|
||||
private ball_size: number = 30;
|
||||
private ball: HTMLElement = null;
|
||||
private container: HTMLElement = null;
|
||||
private reps_remaining = 0;
|
||||
private ball_animation_frame_id = null;
|
||||
|
||||
constructor(private jsPsych: JsPsych) {}
|
||||
|
||||
trial(display_element: HTMLElement, trial: TrialType<Info>) {
|
||||
@ -161,6 +167,8 @@ class VirtualChinrestPlugin implements JsPsychPlugin<Info> {
|
||||
return;
|
||||
}
|
||||
|
||||
this.reps_remaining = trial.blindspot_reps;
|
||||
|
||||
/** some additional parameter configuration */
|
||||
let trial_data = <any>{
|
||||
item_width_mm: trial.item_width_mm,
|
||||
@ -198,7 +206,7 @@ class VirtualChinrestPlugin implements JsPsychPlugin<Info> {
|
||||
let blindspot_content = `
|
||||
<div id="blind-spot">
|
||||
${trial.blindspot_prompt}
|
||||
<div id="svgDiv" style="width:1000px;height:200px;"></div>
|
||||
<div id="svgDiv" style="height:100px; position:relative;"></div>
|
||||
<button class="btn btn-primary" id="proceed" style="display:none;"> +
|
||||
${trial.blindspot_done_prompt} +
|
||||
</button>
|
||||
@ -220,6 +228,7 @@ class VirtualChinrestPlugin implements JsPsychPlugin<Info> {
|
||||
display_element.innerHTML = `<div id="content" style="width: 900px; margin: 0 auto;"></div>`;
|
||||
|
||||
const start_time = performance.now();
|
||||
|
||||
startResizePhase();
|
||||
|
||||
function startResizePhase() {
|
||||
@ -271,7 +280,7 @@ class VirtualChinrestPlugin implements JsPsychPlugin<Info> {
|
||||
|
||||
function finishResizePhase() {
|
||||
// add item width info to data
|
||||
const item_width_px = getScaledItemWidth();
|
||||
const item_width_px = document.querySelector("#item").getBoundingClientRect().width;
|
||||
trial_data["item_width_px"] = Math.round(item_width_px);
|
||||
const px2mm = convertPixelsToMM(item_width_px);
|
||||
trial_data["px2mm"] = accurateRound(px2mm, 2);
|
||||
@ -290,9 +299,21 @@ class VirtualChinrestPlugin implements JsPsychPlugin<Info> {
|
||||
slider_clck: false,
|
||||
};
|
||||
// add the content to the page
|
||||
document.querySelector("#content").innerHTML = blindspot_content;
|
||||
display_element.querySelector("#content").innerHTML = blindspot_content;
|
||||
this.container = display_element.querySelector("#svgDiv");
|
||||
|
||||
// draw the ball and fixation square
|
||||
drawBall();
|
||||
|
||||
resetAndWaitForBallStart();
|
||||
};
|
||||
|
||||
const resetAndWaitForBallStart = () => {
|
||||
const rectX = this.container.getBoundingClientRect().width - this.ball_size;
|
||||
const ballX = rectX * 0.85; // define where the ball is
|
||||
|
||||
this.ball.style.left = `${ballX}px`;
|
||||
|
||||
// wait for a spacebar to begin the animations
|
||||
this.jsPsych.pluginAPI.getKeyboardResponse({
|
||||
callback_function: startBall,
|
||||
@ -304,20 +325,33 @@ class VirtualChinrestPlugin implements JsPsychPlugin<Info> {
|
||||
};
|
||||
|
||||
const startBall = () => {
|
||||
const ball_position_listener = this.jsPsych.pluginAPI.getKeyboardResponse({
|
||||
this.jsPsych.pluginAPI.getKeyboardResponse({
|
||||
callback_function: recordPosition,
|
||||
valid_responses: [" "],
|
||||
rt_method: "performance",
|
||||
allow_held_key: false,
|
||||
persist: true,
|
||||
persist: false,
|
||||
});
|
||||
animateBall();
|
||||
|
||||
this.ball_animation_frame_id = requestAnimationFrame(animateBall);
|
||||
};
|
||||
|
||||
const finishBlindSpotPhase = () => {
|
||||
window.ball.stop();
|
||||
const angle = 13.5;
|
||||
|
||||
this.jsPsych.pluginAPI.cancelAllKeyboardResponses();
|
||||
// calculate average ball position
|
||||
const sum = blindspot_config_data["ball_pos"].reduce((a, b) => a + b, 0);
|
||||
const ballPosLen = blindspot_config_data["ball_pos"].length;
|
||||
blindspot_config_data["avg_ball_pos"] = accurateRound(sum / ballPosLen, 2);
|
||||
|
||||
// calculate distance between avg ball position and square
|
||||
const ball_sqr_distance =
|
||||
(blindspot_config_data["square_pos"] - blindspot_config_data["avg_ball_pos"]) /
|
||||
trial_data["px2mm"];
|
||||
|
||||
// calculate viewing distance in mm
|
||||
const viewDistance = ball_sqr_distance / Math.tan(deg_to_radians(angle));
|
||||
trial_data["view_dist_mm"] = accurateRound(viewDistance, 2);
|
||||
|
||||
if (trial.viewing_distance_report == "none") {
|
||||
endTrial();
|
||||
@ -400,68 +434,53 @@ class VirtualChinrestPlugin implements JsPsychPlugin<Info> {
|
||||
this.jsPsych.finishTrial(trial_data);
|
||||
};
|
||||
|
||||
function getScaledItemWidth() {
|
||||
return document.querySelector("#item").getBoundingClientRect().width;
|
||||
}
|
||||
const drawBall = () => {
|
||||
this.container.innerHTML = `
|
||||
<div id="virtual-chinrest-circle" style="position: absolute; background-color: #f00; width: ${this.ball_size}px; height: ${this.ball_size}px; border-radius:${this.ball_size}px;"></div>
|
||||
<div id="virtual-chinrest-square" style="position: absolute; background-color: #000; width: ${this.ball_size}px; height: ${this.ball_size}px;"></div>
|
||||
`;
|
||||
|
||||
function drawBall(pos = 180) {
|
||||
// pos: define where the fixation square should be.
|
||||
// @ts-expect-error
|
||||
var mySVG = SVG("svgDiv");
|
||||
const rectX = trial_data["px2mm"] * pos;
|
||||
const ballX = rectX * 0.6; // define where the ball is
|
||||
var ball = mySVG.circle(30).move(ballX, 50).fill("#f00");
|
||||
window.ball = ball;
|
||||
var square = mySVG.rect(30, 30).move(Math.min(rectX - 50, 950), 50); //square position
|
||||
blindspot_config_data["square_pos"] = accurateRound(square.cx(), 2);
|
||||
blindspot_config_data["rectX"] = rectX;
|
||||
blindspot_config_data["ballX"] = ballX;
|
||||
}
|
||||
const ball: HTMLElement = this.container.querySelector("#virtual-chinrest-circle");
|
||||
const square: HTMLElement = this.container.querySelector("#virtual-chinrest-square");
|
||||
|
||||
function animateBall() {
|
||||
window.ball
|
||||
.animate(7000)
|
||||
.during((pos) => {
|
||||
let moveX = -pos * blindspot_config_data["ballX"];
|
||||
window.moveX = moveX;
|
||||
let moveY = 0;
|
||||
window.ball.attr({ transform: "translate(" + moveX + "," + moveY + ")" }); //jqueryToVanilla: el.getAttribute('');
|
||||
})
|
||||
.loop(true, false)
|
||||
.after(() => {
|
||||
animateBall();
|
||||
});
|
||||
}
|
||||
const rectX = this.container.getBoundingClientRect().width - this.ball_size;
|
||||
const ballX = rectX * 0.85; // define where the ball is
|
||||
|
||||
function recordPosition() {
|
||||
// angle: define horizontal blind spot entry point position in degrees.
|
||||
const angle = 13.5;
|
||||
ball.style.left = `${ballX}px`;
|
||||
square.style.left = `${rectX}px`;
|
||||
|
||||
blindspot_config_data["ball_pos"].push(accurateRound(window.ball.cx() + window.moveX, 2));
|
||||
var sum = blindspot_config_data["ball_pos"].reduce((a, b) => a + b, 0);
|
||||
var ballPosLen = blindspot_config_data["ball_pos"].length;
|
||||
blindspot_config_data["avg_ball_pos"] = accurateRound(sum / ballPosLen, 2);
|
||||
var ball_sqr_distance =
|
||||
(blindspot_config_data["square_pos"] - blindspot_config_data["avg_ball_pos"]) /
|
||||
trial_data["px2mm"];
|
||||
var viewDistance = ball_sqr_distance / Math.tan(deg_to_radians(angle));
|
||||
trial_data["view_dist_mm"] = accurateRound(viewDistance, 2);
|
||||
this.ball = ball;
|
||||
|
||||
blindspot_config_data["square_pos"] = accurateRound(getElementCenter(square).x, 2);
|
||||
};
|
||||
|
||||
const animateBall = () => {
|
||||
const dx = -2;
|
||||
const x = parseInt(this.ball.style.left);
|
||||
this.ball.style.left = `${x + dx}px`;
|
||||
|
||||
this.ball_animation_frame_id = requestAnimationFrame(animateBall);
|
||||
};
|
||||
|
||||
const recordPosition = () => {
|
||||
cancelAnimationFrame(this.ball_animation_frame_id);
|
||||
|
||||
blindspot_config_data["ball_pos"].push(accurateRound(getElementCenter(this.ball).x, 2));
|
||||
|
||||
//counter and stop
|
||||
var counter = Number(document.querySelector("#click").textContent);
|
||||
counter = counter - 1;
|
||||
this.reps_remaining--;
|
||||
|
||||
(document.querySelector("#click") as HTMLDivElement).textContent = Math.max(
|
||||
counter,
|
||||
this.reps_remaining,
|
||||
0
|
||||
).toString();
|
||||
if (counter <= 0) {
|
||||
|
||||
if (this.reps_remaining <= 0) {
|
||||
finishBlindSpotPhase();
|
||||
return;
|
||||
} else {
|
||||
window.ball.stop();
|
||||
animateBall();
|
||||
}
|
||||
resetAndWaitForBallStart();
|
||||
}
|
||||
};
|
||||
|
||||
function convertPixelsToMM(item_width_px) {
|
||||
const px2mm = item_width_px / trial_data["item_width_mm"];
|
||||
@ -472,6 +491,14 @@ class VirtualChinrestPlugin implements JsPsychPlugin<Info> {
|
||||
return Number(Math.round(Number(value + "e" + decimals)) + "e-" + decimals);
|
||||
}
|
||||
|
||||
function getElementCenter(el: HTMLElement) {
|
||||
const box = el.getBoundingClientRect();
|
||||
return {
|
||||
x: box.left + box.width / 2,
|
||||
y: box.top + box.height / 2,
|
||||
};
|
||||
}
|
||||
|
||||
//helper function for radians
|
||||
// Converts from degrees to radians.
|
||||
const deg_to_radians = (degrees: number) => {
|
||||
|
Loading…
Reference in New Issue
Block a user