mirror of
https://github.com/psychopy/psychojs.git
synced 2025-05-10 10:40:54 +00:00
_
This commit is contained in:
commit
0f2e805f22
@ -26,6 +26,7 @@ import gaussShader from "./shaders/gaussShader.frag";
|
||||
import crossShader from "./shaders/crossShader.frag";
|
||||
import radRampShader from "./shaders/radRampShader.frag";
|
||||
import raisedCosShader from "./shaders/raisedCosShader.frag";
|
||||
import radialStim from "./shaders/radialShader.frag";
|
||||
|
||||
/**
|
||||
* Grating Stimulus.
|
||||
@ -240,6 +241,15 @@ export class GratingStim extends VisualStim
|
||||
uColor: [1., 1., 1.],
|
||||
uAlpha: 1.0
|
||||
}
|
||||
},
|
||||
radialStim: {
|
||||
shader: radialStim,
|
||||
uniforms: {
|
||||
uFreq: 20.0,
|
||||
uPhase: 0.0,
|
||||
uColor: [1., 1., 1.],
|
||||
uAlpha: 1.0
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -717,7 +727,8 @@ export class GratingStim extends VisualStim
|
||||
const maskMesh = this._getPixiMeshFromPredefinedShaders(this._mask);
|
||||
const rt = PIXI.RenderTexture.create({
|
||||
width: this._size_px[0],
|
||||
height: this._size_px[1]
|
||||
height: this._size_px[1],
|
||||
scaleMode: this._interpolate ? PIXI.SCALE_MODES.LINEAR : PIXI.SCALE_MODES.NEAREST
|
||||
});
|
||||
this.win._renderer.render(maskMesh, {
|
||||
renderTexture: rt
|
||||
|
@ -818,15 +818,17 @@ export class Slider extends util.mix(VisualStim).with(ColorMixin, WindowMixin)
|
||||
* @protected
|
||||
*/
|
||||
_handlePointerDown (e) {
|
||||
if (e.data.button === 0)
|
||||
if (e.data.pointerType === "mouse" && e.data.button !== 0)
|
||||
{
|
||||
this._markerDragging = true;
|
||||
if (!this._frozenMarker)
|
||||
{
|
||||
const mouseLocalPos_px = e.data.getLocalPosition(this._pixi);
|
||||
const rating = this._posToRating([mouseLocalPos_px.x, mouseLocalPos_px.y]);
|
||||
this.setMarkerPos(rating);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this._markerDragging = true;
|
||||
if (!this._frozenMarker)
|
||||
{
|
||||
const mouseLocalPos_px = e.data.getLocalPosition(this._pixi);
|
||||
const rating = this._posToRating([mouseLocalPos_px.x, mouseLocalPos_px.y]);
|
||||
this.setMarkerPos(rating);
|
||||
}
|
||||
|
||||
e.stopPropagation();
|
||||
@ -1314,6 +1316,7 @@ export class Slider extends util.mix(VisualStim).with(ColorMixin, WindowMixin)
|
||||
{
|
||||
this._barLineWidth_px = 0;
|
||||
this._tickType = Slider.Shape.DISC;
|
||||
this.granularity = 1.0;
|
||||
|
||||
if (!this._skin.MARKER_SIZE)
|
||||
{
|
||||
|
@ -146,7 +146,7 @@ export class TextBox extends util.mix(VisualStim).with(ColorMixin)
|
||||
this._addAttribute(
|
||||
"alignment",
|
||||
alignment,
|
||||
"left"
|
||||
"center"
|
||||
);
|
||||
this._addAttribute(
|
||||
"languageStyle",
|
||||
@ -237,11 +237,16 @@ export class TextBox extends util.mix(VisualStim).with(ColorMixin)
|
||||
* @param {boolean} alignment - alignment of the text
|
||||
* @param {boolean} [log= false] - whether or not to log
|
||||
*/
|
||||
setAlignment(alignment = "left", log = false)
|
||||
setAlignment(alignment = "center", log = false)
|
||||
{
|
||||
this._setAttribute("alignment", alignment, log);
|
||||
if (this._pixi !== undefined) {
|
||||
this._pixi.setInputStyle("textAlign", alignment);
|
||||
let alignmentStyles = TextBox._alignmentToFlexboxMap.get(alignment);
|
||||
if (!alignmentStyles) {
|
||||
alignmentStyles = ["center", "center"];
|
||||
}
|
||||
this._pixi.setInputStyle("justifyContent", alignmentStyles[0]);
|
||||
this._pixi.setInputStyle("textAlign", alignmentStyles[1]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -491,18 +496,24 @@ export class TextBox extends util.mix(VisualStim).with(ColorMixin)
|
||||
const borderWidth_px = Math.round(this._getLengthPix(this._borderWidth));
|
||||
const width_px = Math.abs(Math.round(this._getLengthPix(this._size[0])));
|
||||
const height_px = Math.abs(Math.round(this._getLengthPix(this._size[1])));
|
||||
let alignmentStyles = TextBox._alignmentToFlexboxMap.get(this._alignment);
|
||||
if (!alignmentStyles) {
|
||||
alignmentStyles = ["center", "center"];
|
||||
}
|
||||
|
||||
return {
|
||||
// input style properties eventually become CSS, so same syntax applies
|
||||
input: {
|
||||
display: "inline-block",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
fontFamily: this._font,
|
||||
fontSize: `${letterHeight_px}px`,
|
||||
color: this._color === undefined || this._color === null ? 'transparent' : new Color(this._color).hex,
|
||||
fontWeight: (this._bold) ? "bold" : "normal",
|
||||
fontStyle: (this._italic) ? "italic" : "normal",
|
||||
direction: util.TEXT_DIRECTION[this._languageStyle],
|
||||
textAlign: this._alignment,
|
||||
justifyContent: alignmentStyles[0],
|
||||
textAlign: alignmentStyles[1],
|
||||
padding: `${padding_px}px`,
|
||||
multiline: this._multiline,
|
||||
text: this._text,
|
||||
@ -686,6 +697,18 @@ export class TextBox extends util.mix(VisualStim).with(ColorMixin)
|
||||
}
|
||||
}
|
||||
|
||||
TextBox._alignmentToFlexboxMap = new Map([
|
||||
["center", ["center", "center"]],
|
||||
["top-center", ["flex-start", "center"]],
|
||||
["bottom-center", ["flex-end", "center"]],
|
||||
["center-left", ["center", "left"]],
|
||||
["center-right", ["center", "right"]],
|
||||
["top-left", ["flex-start", "left"]],
|
||||
["top-right", ["flex-start", "right"]],
|
||||
["bottom-left", ["flex-end", "left"]],
|
||||
["bottom-right", ["flex-end", "right"]]
|
||||
]);
|
||||
|
||||
/**
|
||||
* <p>This map associates units to default letter height.</p>
|
||||
*
|
||||
|
@ -867,6 +867,9 @@ function DefaultBoxGenerator(styles)
|
||||
let box = new PIXI.Graphics();
|
||||
|
||||
if (this._multiline) {
|
||||
// When fill and alpha both 0 it for some reason ignores pointer events.
|
||||
// But not when hitArea is set directly...
|
||||
box.hitArea = new PIXI.Rectangle(0, 0, w, h);
|
||||
box.interactive = !this._disabled;
|
||||
box.on("pointerdown", () => {
|
||||
this._dom_input.focus();
|
||||
|
36
src/visual/shaders/radialShader.frag
Normal file
36
src/visual/shaders/radialShader.frag
Normal file
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Radial grating.
|
||||
*
|
||||
* @author Nikita Agafonov
|
||||
* @copyright (c) 2020-2022 Open Science Tools Ltd. (https://opensciencetools.org)
|
||||
* @license Distributed under the terms of the MIT License
|
||||
* @description Creates 2d radial grating image. Based on https://www.shadertoy.com/view/wtjGzt
|
||||
* @usedby GratingStim.js
|
||||
*/
|
||||
|
||||
#version 300 es
|
||||
precision mediump float;
|
||||
|
||||
in vec2 vUvs;
|
||||
out vec4 shaderOut;
|
||||
uniform float uFreq;
|
||||
uniform float uPhase;
|
||||
uniform vec3 uColor;
|
||||
uniform float uAlpha;
|
||||
|
||||
#define M_PI 3.14159265358979
|
||||
#define PI2 2.* M_PI
|
||||
|
||||
float aastep(float x) { // --- antialiased step(.5)
|
||||
float w = fwidth(x); // pixel width. NB: x must not be discontinuous or factor discont out
|
||||
return smoothstep(.7,-.7,(abs(fract(x-.25)-.5)-.25)/w); // just use (offseted) smooth squares
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 uv = vUvs * 2. - 1.;
|
||||
// converting first to [-1, 1] space to get the proper color functionality
|
||||
// then back to [0, 1]
|
||||
float v = uFreq * atan(uv.y, uv.x) / 6.28;
|
||||
float s = aastep(v) * 2. - 1.;
|
||||
shaderOut = vec4(vec3(s) * uColor * .5 + .5, 1.0) * uAlpha;
|
||||
}
|
Loading…
Reference in New Issue
Block a user