mirror of
https://github.com/psychopy/psychojs.git
synced 2025-05-10 10:40:54 +00:00
Merge branch '2022.3.0' into particle_system
This commit is contained in:
commit
311de2f494
@ -47,10 +47,34 @@ export class ImageStim extends util.mix(VisualStim).with(ColorMixin)
|
||||
* @param {boolean} [options.autoDraw= false] - whether or not the stimulus should be automatically drawn on every frame flip
|
||||
* @param {boolean} [options.autoLog= false] - whether or not to log
|
||||
*/
|
||||
constructor({ name, win, image, mask, pos, anchor, units, ori, size, color, opacity, contrast, texRes, depth, interpolate, flipHoriz, flipVert, autoDraw, autoLog } = {})
|
||||
constructor({
|
||||
name,
|
||||
win,
|
||||
image,
|
||||
mask,
|
||||
pos,
|
||||
anchor,
|
||||
units,
|
||||
ori,
|
||||
size,
|
||||
color,
|
||||
opacity,
|
||||
contrast,
|
||||
texRes,
|
||||
depth,
|
||||
interpolate,
|
||||
flipHoriz,
|
||||
flipVert,
|
||||
autoDraw,
|
||||
autoLog,
|
||||
blurVal
|
||||
} = {})
|
||||
{
|
||||
super({ name, win, units, ori, opacity, depth, pos, anchor, size, autoDraw, autoLog });
|
||||
|
||||
// Holds an instance of PIXI blur filter. Used if blur value is passed.
|
||||
this._blurFilter = undefined;
|
||||
|
||||
this._addAttribute(
|
||||
"image",
|
||||
image,
|
||||
@ -94,6 +118,11 @@ export class ImageStim extends util.mix(VisualStim).with(ColorMixin)
|
||||
false,
|
||||
this._onChange(false, false),
|
||||
);
|
||||
this._addAttribute(
|
||||
"blurVal",
|
||||
blurVal,
|
||||
0
|
||||
);
|
||||
|
||||
// estimate the bounding box:
|
||||
this._estimateBoundingBox();
|
||||
@ -234,6 +263,33 @@ export class ImageStim extends util.mix(VisualStim).with(ColorMixin)
|
||||
}
|
||||
}
|
||||
|
||||
setBlurVal (blurVal = 0, log = false)
|
||||
{
|
||||
this._setAttribute("blurVal", blurVal, log);
|
||||
if (this._pixi instanceof PIXI.Sprite)
|
||||
{
|
||||
if (this._blurFilter === undefined)
|
||||
{
|
||||
this._blurFilter = new PIXI.filters.BlurFilter();
|
||||
this._blurFilter.blur = blurVal;
|
||||
}
|
||||
else
|
||||
{
|
||||
this._blurFilter.blur = blurVal;
|
||||
}
|
||||
|
||||
// this._pixi might get destroyed and recreated again with no filters.
|
||||
if (this._pixi.filters instanceof Array && this._pixi.filters.indexOf(this._blurFilter) === -1)
|
||||
{
|
||||
this._pixi.filters.push(this._blurFilter);
|
||||
}
|
||||
else
|
||||
{
|
||||
this._pixi.filters = [this._blurFilter];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate the bounding box.
|
||||
*
|
||||
@ -276,6 +332,7 @@ export class ImageStim extends util.mix(VisualStim).with(ColorMixin)
|
||||
|
||||
if (typeof this._pixi !== "undefined")
|
||||
{
|
||||
this._pixi.filters = null;
|
||||
this._pixi.destroy(true);
|
||||
}
|
||||
this._pixi = undefined;
|
||||
@ -359,6 +416,11 @@ export class ImageStim extends util.mix(VisualStim).with(ColorMixin)
|
||||
this._pixi.position = to_pixiPoint(this.pos, this.units, this.win);
|
||||
this._pixi.rotation = -this.ori * Math.PI / 180;
|
||||
|
||||
if (this._blurVal > 0)
|
||||
{
|
||||
this.setBlurVal(this._blurVal);
|
||||
}
|
||||
|
||||
// re-estimate the bounding box, as the texture's width may now be available:
|
||||
this._estimateBoundingBox();
|
||||
}
|
||||
|
141
src/visual/Progress.js
Normal file
141
src/visual/Progress.js
Normal file
@ -0,0 +1,141 @@
|
||||
import * as PIXI from "pixi.js-legacy";
|
||||
import * as util from "../util/Util.js";
|
||||
import { Color } from "../util/Color.js";
|
||||
import { to_pixiPoint } from "../util/Pixi.js";
|
||||
import { VisualStim } from "./VisualStim.js";
|
||||
|
||||
export class Progress extends VisualStim
|
||||
{
|
||||
constructor (
|
||||
{
|
||||
name,
|
||||
win,
|
||||
units,
|
||||
ori,
|
||||
opacity,
|
||||
depth,
|
||||
pos,
|
||||
anchor = "left",
|
||||
size = [300, 30],
|
||||
clipMask,
|
||||
autoDraw,
|
||||
autoLog,
|
||||
progress = 1,
|
||||
type,
|
||||
fillColor,
|
||||
fillTexture
|
||||
})
|
||||
{
|
||||
super({
|
||||
name,
|
||||
win,
|
||||
units,
|
||||
ori,
|
||||
opacity,
|
||||
depth,
|
||||
pos,
|
||||
anchor,
|
||||
size,
|
||||
clipMask,
|
||||
autoDraw,
|
||||
autoLog
|
||||
});
|
||||
|
||||
this._addAttribute("progress", progress, 0);
|
||||
this._addAttribute("type", type, PROGRESS_TYPES.BAR);
|
||||
this._addAttribute("fillColor", fillColor, "lightgreen");
|
||||
this._addAttribute("fillTexture", fillTexture, PIXI.Texture.WHITE);
|
||||
|
||||
if (this._autoLog)
|
||||
{
|
||||
this._psychoJS.experimentLogger.exp(`Created ${this.name} = ${this.toString()}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the progress attribute.
|
||||
*/
|
||||
setProgress (progress = 0, log = false)
|
||||
{
|
||||
this._setAttribute("progress", Math.min(1.0, Math.max(0.0, progress)), log);
|
||||
if (this._pixi !== undefined)
|
||||
{
|
||||
this._pixi.clear();
|
||||
const size_px = util.to_px(this.size, this.units, this.win);
|
||||
const pos_px = util.to_px(this.pos, this.units, this.win);
|
||||
const progressWidth = size_px[0] * this._progress;
|
||||
if (this._fillTexture)
|
||||
{
|
||||
let t = PIXI.Texture.WHITE;
|
||||
if (typeof this._fillTexture === "string")
|
||||
{
|
||||
t = PIXI.Texture.from(this._fillTexture);
|
||||
t.baseTexture.scaleMode = PIXI.SCALE_MODES.NEAREST;
|
||||
}
|
||||
this._pixi.beginTextureFill({
|
||||
texture: t
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
this._pixi.beginFill(new Color(this._fillColor).int, this._opacity);
|
||||
}
|
||||
if (this._type === PROGRESS_TYPES.BAR)
|
||||
{
|
||||
this._pixi.drawRect(pos_px[0], pos_px[1], progressWidth, size_px[1]);
|
||||
}
|
||||
// TODO: check out beginTextureFill(). Perhaps it will allow to use images as filling for progress.
|
||||
this._pixi.endFill();
|
||||
|
||||
// TODO: is there a better way to ensure anchor works?
|
||||
this.anchor = this._anchor;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the stimulus, if necessary.
|
||||
*
|
||||
* @protected
|
||||
*/
|
||||
_updateIfNeeded()
|
||||
{
|
||||
// TODO: figure out what is the error with estimateBoundBox on resize?
|
||||
if (!this._needUpdate)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this._needUpdate = false;
|
||||
|
||||
// update the PIXI representation, if need be:
|
||||
if (this._needPixiUpdate)
|
||||
{
|
||||
this._needPixiUpdate = false;
|
||||
|
||||
if (typeof this._pixi !== "undefined")
|
||||
{
|
||||
this._pixi.destroy(true);
|
||||
}
|
||||
this._pixi = new PIXI.Graphics();
|
||||
// TODO: Should we do this?
|
||||
// this._pixi.lineStyle(this._lineWidth, this._lineColor.int, this._opacity, 0.5);
|
||||
|
||||
// TODO: Should just .setProgress() be called?
|
||||
this.setProgress(this._progress);
|
||||
|
||||
this._pixi.scale.y = -1;
|
||||
this._pixi.zIndex = -this._depth;
|
||||
this.anchor = this._anchor;
|
||||
}
|
||||
|
||||
// set polygon position and rotation:
|
||||
// TODO: what's the difference bw to_px and to_pixiPoint?
|
||||
this._pixi.position = to_pixiPoint(this.pos, this.units, this.win);
|
||||
this._pixi.rotation = -this.ori * Math.PI / 180.0;
|
||||
}
|
||||
}
|
||||
|
||||
export const PROGRESS_TYPES =
|
||||
{
|
||||
BAR: 0,
|
||||
CIRCLE: 1
|
||||
}
|
@ -14,3 +14,4 @@ export * from "./VisualStim.js";
|
||||
export * from "./FaceDetector.js";
|
||||
export * from "./Survey.js";
|
||||
export * from "./ParticleEmitter.js";
|
||||
export * from "./Progress.js";
|
Loading…
Reference in New Issue
Block a user