mirror of
https://github.com/psychopy/psychojs.git
synced 2025-05-10 10:40:54 +00:00
Merge branch 'main' into bf#348--no-moment
This commit is contained in:
commit
6ecb96b561
3
.github/workflows/Automated Test (full).yml
vendored
3
.github/workflows/Automated Test (full).yml
vendored
@ -3,7 +3,8 @@
|
||||
name: Automated Test (full)
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * sat'
|
||||
# Temporarily disabled so the stager test logs aren't cleaned up
|
||||
# - cron: '0 0 * * sat'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
repo:
|
||||
|
149
index.css
149
index.css
@ -1,149 +0,0 @@
|
||||
|
||||
/* project and resource dialogs */
|
||||
label, input, select {
|
||||
display: block;
|
||||
padding-bottom: .5em;
|
||||
}
|
||||
|
||||
input.text, select.text {
|
||||
margin-bottom: 1em;
|
||||
width: 95%;
|
||||
padding: .5em;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
a, a:active, a:focus, a:visited {
|
||||
outline: 0;
|
||||
color: #007EB7;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.progress {
|
||||
padding: .5em 0 .5em 0;
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-width: 100%;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
|
||||
/* don't display close button in the top right corner of the box */
|
||||
.no-close .ui-dialog-titlebar-close {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ui-dialog-content {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
|
||||
/* for mobile phones only */
|
||||
@media only screen and (max-width: 1080px) {
|
||||
|
||||
.ui-widget {
|
||||
-ms-transform: scale(2);
|
||||
-webkit-transform: scale(2);
|
||||
transform: scale(2);
|
||||
}
|
||||
|
||||
.ui-widget .ui-progressbar {
|
||||
-ms-transform: scale(1);
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.ui-dialog .ui-dialog-buttonpane {
|
||||
padding-top: 1em;
|
||||
}
|
||||
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset .ui-button {
|
||||
-ms-transform: scale(1);
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.ui-dialog .ui-dialog-titlebar {
|
||||
padding: 1em 2em;
|
||||
}
|
||||
|
||||
.ui-dialog-titlebar .ui-button {
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
.ui-dialog-titlebar .ui-dialog-titlebar-close {
|
||||
-ms-transform: scale(1);
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1080px) and (orientation:landscape) {
|
||||
|
||||
.ui-widget {
|
||||
-ms-transform: scale(1.5);
|
||||
-webkit-transform: scale(1.5);
|
||||
transform: scale(1.5);
|
||||
}
|
||||
|
||||
.ui-widget .ui-progressbar {
|
||||
-ms-transform: scale(1);
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.ui-dialog .ui-dialog-buttonpane {
|
||||
padding-top: 1em;
|
||||
}
|
||||
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset .ui-button {
|
||||
-ms-transform: scale(1);
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.ui-dialog .ui-dialog-titlebar {
|
||||
padding: 1em 2em;
|
||||
}
|
||||
|
||||
.ui-dialog-titlebar .ui-button {
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
.ui-dialog-titlebar .ui-dialog-titlebar-close {
|
||||
-ms-transform: scale(1);
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Initialisation message (which will disappear behind the canvas) */
|
||||
#root:after {
|
||||
content: "initialising the experiment...";
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
/* Initialisation message for IE11 */
|
||||
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
|
||||
#root:after {
|
||||
content: "initialising the experiment... | Internet Explorer / Edge [beta]";
|
||||
|
||||
color: #A05000;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
5
index.js
5
index.js
@ -1,5 +0,0 @@
|
||||
export * as util from './js/util/index.js';
|
||||
export * as core from './js/core/index.js';
|
||||
export * as data from './js/data/index.js';
|
||||
export * as visual from './js/visual/index.js';
|
||||
export * as sound from './js/sound/index.js';
|
20
package-lock.json
generated
20
package-lock.json
generated
@ -1,18 +1,18 @@
|
||||
{
|
||||
"name": "psychojs",
|
||||
"version": "2021.x",
|
||||
"version": "2021.2.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"version": "2021.x",
|
||||
"name": "psychojs",
|
||||
"version": "2021.2.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"howler": "^2.2.1",
|
||||
"log4javascript": "github:Ritzlgrmft/log4javascript",
|
||||
"pako": "^1.0.10",
|
||||
"pixi.js-legacy": "^6.0.4",
|
||||
"preload-js": "^0.6.3",
|
||||
"seedrandom": "^3.0.5",
|
||||
"tone": "^14.7.77",
|
||||
"xlsx": "^0.17.0"
|
||||
@ -1706,7 +1706,7 @@
|
||||
},
|
||||
"node_modules/log4javascript": {
|
||||
"version": "1.4.16",
|
||||
"resolved": "git+ssh://git@github.com/Ritzlgrmft/log4javascript.git#d27efb927c3c47ce9d747263427905d16ded2f2c"
|
||||
"resolved": "git+https://git@github.com/Ritzlgrmft/log4javascript.git#d27efb927c3c47ce9d747263427905d16ded2f2c"
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "6.0.0",
|
||||
@ -1970,11 +1970,6 @@
|
||||
"url": "https://opencollective.com/pixijs"
|
||||
}
|
||||
},
|
||||
"node_modules/preload-js": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/preload-js/-/preload-js-0.6.3.tgz",
|
||||
"integrity": "sha1-3LS3wOGC27ziZ3rU8s+u4uJbTfc="
|
||||
},
|
||||
"node_modules/prelude-ls": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
||||
@ -3805,7 +3800,7 @@
|
||||
"dev": true
|
||||
},
|
||||
"log4javascript": {
|
||||
"version": "git+ssh://git@github.com/Ritzlgrmft/log4javascript.git#d27efb927c3c47ce9d747263427905d16ded2f2c",
|
||||
"version": "git+https://git@github.com/Ritzlgrmft/log4javascript.git#d27efb927c3c47ce9d747263427905d16ded2f2c",
|
||||
"from": "log4javascript@github:Ritzlgrmft/log4javascript"
|
||||
},
|
||||
"lru-cache": {
|
||||
@ -4022,11 +4017,6 @@
|
||||
"pixi.js": "6.0.4"
|
||||
}
|
||||
},
|
||||
"preload-js": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/preload-js/-/preload-js-0.6.3.tgz",
|
||||
"integrity": "sha1-3LS3wOGC27ziZ3rU8s+u4uJbTfc="
|
||||
},
|
||||
"prelude-ls": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "psychojs",
|
||||
"version": "2021.x",
|
||||
"version": "2021.2.0",
|
||||
"private": true,
|
||||
"description": "Helps run in-browser neuroscience, psychology, and psychophysics experiments",
|
||||
"license": "MIT",
|
||||
@ -30,7 +30,6 @@
|
||||
"log4javascript": "github:Ritzlgrmft/log4javascript",
|
||||
"pako": "^1.0.10",
|
||||
"pixi.js-legacy": "^6.0.4",
|
||||
"preload-js": "^0.6.3",
|
||||
"seedrandom": "^3.0.5",
|
||||
"tone": "^14.7.77",
|
||||
"xlsx": "^0.17.0"
|
||||
|
@ -106,7 +106,7 @@ export class MinimalStim extends PsychObject
|
||||
if (typeof this._pixi === 'undefined')
|
||||
{
|
||||
this.psychoJS.logger.warn('the Pixi.js representation of this stimulus is undefined.');
|
||||
}// throw Object.assign(response, { error: 'the PIXI representation of the stimulus is unavailable'});
|
||||
}
|
||||
else
|
||||
{
|
||||
this.win._rootContainer.addChild(this._pixi);
|
||||
|
@ -743,8 +743,15 @@ export class PsychoJS
|
||||
};
|
||||
window.onunhandledrejection = function (error)
|
||||
{
|
||||
console.error(error.reason);
|
||||
self._gui.dialog({error: error.reason});
|
||||
console.error(error?.reason);
|
||||
if (error?.reason?.stack === undefined) {
|
||||
// No stack? Error thrown by PsychoJS; stringify whole error
|
||||
document.body.setAttribute('data-error', JSON.stringify(error?.reason));
|
||||
} else {
|
||||
// Yes stack? Error thrown by JS; stringify stack
|
||||
document.body.setAttribute('data-error', JSON.stringify(error?.reason?.stack));
|
||||
}
|
||||
self._gui.dialog({error: error?.reason});
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
* @license Distributed under the terms of the MIT License
|
||||
*/
|
||||
|
||||
import createjs from 'preload-js';
|
||||
import { Howl } from 'howler';
|
||||
import {PsychoJS} from './PsychoJS';
|
||||
import {PsychObject} from '../util/PsychObject';
|
||||
@ -1045,7 +1044,7 @@ export class ServerManager extends PsychObject
|
||||
manifest.push(/*new createjs.LoadItem().set(*/{
|
||||
id: name,
|
||||
src: pathStatusData.path,
|
||||
type: createjs.LoadQueue.BINARY, //createjs.Types.BINARY,
|
||||
type: createjs.Types.BINARY,
|
||||
crossOrigin: 'Anonymous'
|
||||
}/*)*/);
|
||||
}
|
||||
|
@ -359,7 +359,8 @@ export class Window extends PsychObject
|
||||
this._renderer.backgroundColor = this._color.int;
|
||||
}
|
||||
|
||||
// we also change the background color of the body since the dialog popup may be longer than the window's height:
|
||||
// we also change the background color of the body since
|
||||
// the dialog popup may be longer than the window's height:
|
||||
document.body.style.backgroundColor = this._color.hex;
|
||||
|
||||
this._needUpdate = false;
|
||||
@ -378,7 +379,8 @@ export class Window extends PsychObject
|
||||
{
|
||||
this._updateIfNeeded();
|
||||
|
||||
// if a stimuli needs to be updated, we remove it from the window container, update it, then put it back
|
||||
// if a stimuli needs to be updated, we remove it from the window container,
|
||||
// update it, then put it back
|
||||
for (const stimulus of this._drawList)
|
||||
{
|
||||
if (stimulus._needUpdate && typeof stimulus._pixi !== 'undefined')
|
||||
|
@ -80,12 +80,11 @@ export class TrialHandler extends PsychObject
|
||||
this._addAttribute('nReps', nReps);
|
||||
this._addAttribute('method', method);
|
||||
this._addAttribute('extraInfo', extraInfo);
|
||||
this._addAttribute('seed', seed);
|
||||
this._addAttribute('name', name);
|
||||
this._addAttribute('autoLog', autoLog);
|
||||
|
||||
this._addAttribute('seed', seed);
|
||||
this._prepareTrialList(trialList);
|
||||
|
||||
|
||||
// number of stimuli
|
||||
this.nStim = this.trialList.length;
|
||||
|
||||
@ -212,6 +211,7 @@ export class TrialHandler extends PsychObject
|
||||
|
||||
/**
|
||||
* @typedef {Object} Snapshot
|
||||
* @property {TrialHandler} handler - the trialHandler
|
||||
* @property {string} name - the trialHandler name
|
||||
* @property {number} nStim - the number of stimuli
|
||||
* @property {number} nTotal - the total number of trials that will be run
|
||||
@ -237,6 +237,7 @@ export class TrialHandler extends PsychObject
|
||||
const currentIndex = this.thisIndex;
|
||||
|
||||
const snapshot = {
|
||||
handler: this,
|
||||
name: this.name,
|
||||
nStim: this.nStim,
|
||||
nTotal: this.nTotal,
|
||||
@ -250,6 +251,8 @@ export class TrialHandler extends PsychObject
|
||||
|
||||
getCurrentTrial: () => this.getTrial(currentIndex),
|
||||
getTrial: (index = 0) => this.getTrial(index),
|
||||
|
||||
addData: (key, value) => this.addData(key, value)
|
||||
};
|
||||
|
||||
this._snapshots.push(snapshot);
|
||||
@ -257,6 +260,63 @@ export class TrialHandler extends PsychObject
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the seed attribute.
|
||||
*
|
||||
* @param {boolean} newSeed - New value for seed
|
||||
*/
|
||||
setSeed(seed, log)
|
||||
{
|
||||
this._setAttribute('seed', seed, log);
|
||||
if (typeof this.seed !== 'undefined')
|
||||
{
|
||||
this._randomNumberGenerator = seedrandom(this.seed);
|
||||
}
|
||||
else
|
||||
{
|
||||
this._randomNumberGenerator = seedrandom();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the internal state of this trial handler from the given snapshot.
|
||||
*
|
||||
* @public
|
||||
* @static
|
||||
* @param {Snapshot} snapshot - the snapshot from which to update the current internal state.
|
||||
*/
|
||||
static fromSnapshot(snapshot)
|
||||
{
|
||||
// if snapshot is undefined, do nothing:
|
||||
if (typeof snapshot === 'undefined')
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
snapshot.handler.nStim = snapshot.nStim;
|
||||
snapshot.handler.nTotal = snapshot.nTotal;
|
||||
snapshot.handler.nRemaining = snapshot.nRemaining;
|
||||
snapshot.handler.thisRepN = snapshot.thisRepN;
|
||||
snapshot.handler.thisTrialN = snapshot.thisTrialN;
|
||||
snapshot.handler.thisN = snapshot.thisN;
|
||||
snapshot.handler.thisIndex = snapshot.thisIndex;
|
||||
snapshot.handler.ran = snapshot.ran;
|
||||
snapshot.handler._finished = snapshot._finished;
|
||||
|
||||
snapshot.handler.thisTrial = snapshot.handler.getCurrentTrial();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Getter for the finished attribute.
|
||||
*
|
||||
* @returns {boolean} whether or not the trial has finished.
|
||||
*/
|
||||
get finished()
|
||||
{
|
||||
return this._finished;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setter for the finished attribute.
|
||||
@ -616,16 +676,6 @@ export class TrialHandler extends PsychObject
|
||||
// get an array of the indices of the elements of trialList :
|
||||
const indices = Array.from(this.trialList.keys());
|
||||
|
||||
// seed the random number generator:
|
||||
if (typeof (this.seed) !== 'undefined')
|
||||
{
|
||||
seedrandom(this.seed);
|
||||
}
|
||||
else
|
||||
{
|
||||
seedrandom();
|
||||
}
|
||||
|
||||
if (this.method === TrialHandler.Method.SEQUENTIAL)
|
||||
{
|
||||
this._trialSequence = Array(this.nReps).fill(indices);
|
||||
@ -638,7 +688,7 @@ export class TrialHandler extends PsychObject
|
||||
this._trialSequence = [];
|
||||
for (let i = 0; i < this.nReps; ++i)
|
||||
{
|
||||
this._trialSequence.push(util.shuffle(indices.slice()));
|
||||
this._trialSequence.push(util.shuffle(indices.slice(), this._randomNumberGenerator));
|
||||
}
|
||||
}
|
||||
|
||||
@ -652,7 +702,7 @@ export class TrialHandler extends PsychObject
|
||||
}
|
||||
|
||||
// shuffle the sequence:
|
||||
util.shuffle(flatSequence);
|
||||
util.shuffle(flatSequence, this._randomNumberGenerator);
|
||||
|
||||
// reshape it into the trialSequence:
|
||||
this._trialSequence = [];
|
||||
|
@ -200,7 +200,18 @@ export class AudioClip extends PsychObject
|
||||
this._psychoJS.logger.debug('speech.googleapis.com response:', JSON.stringify(decodedResponse));
|
||||
|
||||
// TODO deal with more than one results and/or alternatives
|
||||
resolve(decodedResponse.results[0].alternatives[0]);
|
||||
if (('results' in decodedResponse) && (decodedResponse.results.length > 0))
|
||||
{
|
||||
resolve(decodedResponse.results[0].alternatives[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// no transcription available:
|
||||
resolve({
|
||||
transcript: '',
|
||||
confidence: -1
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ import {AudioClip} from "./AudioClip";
|
||||
* @class
|
||||
* @param {Object} options
|
||||
* @param {module:core.PsychoJS} options.psychoJS - the PsychoJS instance
|
||||
* @param {String} options.name - the name used when logging messages
|
||||
* @param @param {module:core.Window} options.win - the associated Window
|
||||
* @param {string} [options.format='audio/webm;codecs=opus'] the format for the audio file
|
||||
* @param {number} [options.sampleRateHz= 48000] - the audio sampling rate, in Hz
|
||||
* @param {Clock} [options.clock= undefined] - an optional clock
|
||||
@ -30,10 +30,11 @@ import {AudioClip} from "./AudioClip";
|
||||
export class Microphone extends PsychObject
|
||||
{
|
||||
|
||||
constructor({psychoJS, name, format, sampleRateHz, clock, autoLog} = {})
|
||||
constructor({win, name, format, sampleRateHz, clock, autoLog} = {})
|
||||
{
|
||||
super(psychoJS);
|
||||
super(win._psychoJS);
|
||||
|
||||
this._addAttribute('win', win, undefined);
|
||||
this._addAttribute('name', name, 'microphone');
|
||||
this._addAttribute('format', format, 'audio/webm;codecs=opus', this._onChange);
|
||||
this._addAttribute('sampleRateHz', sampleRateHz, 48000, this._onChange);
|
||||
|
@ -340,13 +340,17 @@ export function IsPointInsidePolygon(point, vertices)
|
||||
* @function
|
||||
* @public
|
||||
* @param {Object[]} array - the input 1-D array
|
||||
* @param {Function} [randomNumberGenerator = undefined] - A function used to generated random numbers in the interal [0, 1). Defaults to Math.random
|
||||
* @return {Object[]} the shuffled array
|
||||
*/
|
||||
export function shuffle(array)
|
||||
export function shuffle(array, randomNumberGenerator = undefined)
|
||||
{
|
||||
if (randomNumberGenerator === undefined) {
|
||||
randomNumberGenerator = Math.random;
|
||||
}
|
||||
for (let i = array.length - 1; i > 0; i--)
|
||||
{
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
const j = Math.floor(randomNumberGenerator() * (i + 1));
|
||||
[array[i], array[j]] = [array[j], array[i]];
|
||||
}
|
||||
return array;
|
||||
|
@ -923,7 +923,9 @@ export class Form extends util.mix(VisualStim).with(ColorMixin)
|
||||
this._visual.stimuliTotalHeight = stimulusOffset;
|
||||
|
||||
|
||||
// scrollbar:
|
||||
// scrollbar
|
||||
// note: we add this Form as a dependent stimulus such that the Form is redrawn whenever
|
||||
// the slider is updated
|
||||
this._scrollbar = new Slider({
|
||||
win: this._win,
|
||||
name: 'scrollbar',
|
||||
@ -934,6 +936,7 @@ export class Form extends util.mix(VisualStim).with(ColorMixin)
|
||||
size: [this._scrollbarWidth, this._size[1]],
|
||||
style: [Slider.Style.SLIDER],
|
||||
ticks: [0, -this._visual.stimuliTotalHeight / this._size[1]],
|
||||
dependentStims: [this]
|
||||
});
|
||||
this._prevScrollbarMarkerPos = 0;
|
||||
this._scrollbar.setMarkerPos(this._prevScrollbarMarkerPos);
|
||||
@ -968,7 +971,6 @@ export class Form extends util.mix(VisualStim).with(ColorMixin)
|
||||
}
|
||||
this._needUpdate = false;
|
||||
|
||||
|
||||
// calculate the edges of the form and various other sizes, in various units:
|
||||
this._leftEdge = this._pos[0] - this._size[0] / 2.0;
|
||||
this._rightEdge = this._pos[0] + this._size[0] / 2.0;
|
||||
|
@ -59,6 +59,9 @@ import {PsychoJS} from "../core/PsychoJS";
|
||||
* frame flip
|
||||
* @param {boolean} [options.autoLog= false] - whether or not to log
|
||||
*
|
||||
* @param {core.MinimalStim[]} [options.dependentStims = [] ] - the list of dependent stimuli,
|
||||
* which must be updated when this Slider is updated, e.g. a Form.
|
||||
*
|
||||
* @todo check that parameters are valid, e.g. ticks are an array of numbers, etc.
|
||||
* @todo readOnly
|
||||
* @todo complete setters, for instance setTicks should change this._isCategorical
|
||||
@ -66,7 +69,7 @@ import {PsychoJS} from "../core/PsychoJS";
|
||||
*/
|
||||
export class Slider extends util.mix(VisualStim).with(ColorMixin, WindowMixin)
|
||||
{
|
||||
constructor({name, win, pos, size, ori, units, color, markerColor, contrast, opacity, style, ticks, labels, granularity, flip, readOnly, font, bold, italic, fontSize, compact, clipMask, autoDraw, autoLog} = {})
|
||||
constructor({name, win, pos, size, ori, units, color, markerColor, contrast, opacity, style, ticks, labels, granularity, flip, readOnly, font, bold, italic, fontSize, compact, clipMask, autoDraw, autoLog, dependentStims} = {})
|
||||
{
|
||||
super({name, win, units, ori, opacity, pos, size, clipMask, autoDraw, autoLog});
|
||||
|
||||
@ -179,6 +182,14 @@ export class Slider extends util.mix(VisualStim).with(ColorMixin, WindowMixin)
|
||||
this._onChange(true, false)
|
||||
);
|
||||
|
||||
this._addAttribute(
|
||||
'dependentStims',
|
||||
dependentStims,
|
||||
[],
|
||||
this._onChange(false, false)
|
||||
);
|
||||
|
||||
|
||||
|
||||
// slider rating (which might be different from the visible marker rating):
|
||||
this._addAttribute('rating', undefined);
|
||||
@ -380,6 +391,31 @@ export class Slider extends util.mix(VisualStim).with(ColorMixin, WindowMixin)
|
||||
|
||||
|
||||
|
||||
/** Let `fillColor` alias `markerColor` to parallel PsychoPy */
|
||||
set fillColor(color) {
|
||||
this.markerColor = color;
|
||||
}
|
||||
|
||||
|
||||
|
||||
setFillColor(color) {
|
||||
this.setMarkerColor(color);
|
||||
}
|
||||
|
||||
|
||||
|
||||
get fillColor() {
|
||||
return this.markerColor;
|
||||
}
|
||||
|
||||
|
||||
|
||||
getFillColor() {
|
||||
return this.getMarkerColor();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Estimate the bounding box.
|
||||
*
|
||||
@ -607,6 +643,12 @@ export class Slider extends util.mix(VisualStim).with(ColorMixin, WindowMixin)
|
||||
this._pixi.position = this._getPosition_px();
|
||||
|
||||
this._pixi.alpha = this._opacity;
|
||||
|
||||
// make sure that the dependent Stimuli are also updated:
|
||||
for (const dependentStim of this._dependentStims)
|
||||
{
|
||||
dependentStim.draw();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -56,7 +56,7 @@ export class TextInput extends PIXI.Container
|
||||
this._selection = [0, 0];
|
||||
this._restrict_value = '';
|
||||
this._createDOMInput();
|
||||
this.substituteText = true;
|
||||
this.substituteText = false;
|
||||
this._setState('DEFAULT');
|
||||
}
|
||||
|
||||
@ -831,9 +831,9 @@ function DefaultBoxGenerator(styles)
|
||||
if (style.stroke)
|
||||
{
|
||||
box.lineStyle(
|
||||
style.stroke.width || 1,
|
||||
style.stroke.color || 0,
|
||||
style.stroke.alpha || 1
|
||||
style.stroke.width ?? 1,
|
||||
style.stroke.color ?? 0,
|
||||
style.stroke.alpha ?? 1
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user