xxxxxxxxxx
266
/*
todo:
- make setup mode
- save data more like the other one
question:
do we want them to look for multiple differences per image?
i think not.
instructions:
0. Photoshop your image(s) to create small differences.
1. Upload all your (edited and unedited) images to the images folder.
2. Write the filenames for the unedited images in "prenames" and for the edited ones in "postnames"
3. Change setupmode to true.
4. Run the sketch, marking the areas where you made a change.
5. Copy the coordinates into the code.
6. Change setupmode back to false
*/
const setupmode = true;
const prenames = ['0_pre.png', '1_pre.png', '2_pre.png', '3_pre.png', '4_pre.png', '5_pre.png'];
const postnames = ['0_post.png', '1_post.png', '2_post.png', '3_post.png', '4_post.png', '5_post.png'];
const targetCoords = [[0.3453125,0.0875],[0.733333333,0.5875],[0.3296875,0.31875],[0.6859375,0.070833333],[0.50625,0.810416667],[0.5,0.5]];
var experiment = false;
var stimuli = [];
//setup mode variables
let selecting = false;
let selectionCount = 0;
let targetSelection = [];
let res;
let setupText = 'Press Enter to go to the next image <br> Copy the following into the code: <br>';
let targetsText = "[]";
//experiment variables
let presentationOrder = [];
var counter = 0
var max_height = 0;
var max_width = 0;
var image_offset = 50;
var stimulus;
let trial;
let timestamp;
function preload() {
// create a table to store results
output = new p5.Table();
output.columns = ['pre','post','xfiducial','yfiducial','xchosen', 'ychosen', 'dist','rt (ms)']
for (let i = 0; i < prenames.length; i++) {
stimuli.push([
loadImage('images/' + prenames[i]),
loadImage('images/' + postnames[i])
]);
presentationOrder[i] = i;
}
//Comment this out to show images in order
presentationOrder=shuffle(presentationOrder);
}
function setup() {
// determine which image has the biggest width/height
for (let i = 0; i < stimuli.length; i++) {
pair = stimuli[i];
if (max(pair[0].width, pair[1].width) > max_width) {
max_width = max(pair[0].width, pair[1].width)
}
if (max(pair[0].height, pair[1].height) > max_height) {
max_height = max(pair[0].height, pair[1].height)
}
}
// create canvas equal to the largest image, plus a little extra space for text
cnv = createCanvas(max_width, max_height + image_offset);
if(setupmode){
res = select('#setuptext');
res.html(setupText);
cnv.mousePressed(startSelect);
cnv.mouseReleased(endSelect);
cnv.parent("sketch");
document.getElementById('sketch').setAttribute("style","height:" + cnv.height + "px");
}
else{
cnv.mouseClicked(clickOnCanvas);
background(128);
textSize(16);
text('Try to spot the difference',30,40);
text('Click to start the task',30,60);
frameRate(10);
}
}
function draw() {
//this code is to draw the rectangles
if(setupmode){
tint(255, 255); // Display at full opacity
background(128);
image(stimuli[selectionCount][0],0,0);
tint(255, 127); // Display at half opacity
image(stimuli[selectionCount][1],0,0);
strokeWeight(1);
if(selecting){
let xs,ys,ws,hs;
rectfill = color(0, 200, 200);
rectfill.setAlpha(100);
fill(rectfill);
stroke(0,255,255);
if(mouseX>targetSelection[selectionCount][0]){
xs = targetSelection[selectionCount][0];
ws = mouseX - xs;
}else{
xs = mouseX;
ws = targetSelection[selectionCount][0] - xs;
}
if(mouseY>targetSelection[selectionCount][1]){
ys = targetSelection[selectionCount][1];
hs = mouseY - ys;
}else{
ys = mouseY;
hs = targetSelection[selectionCount][1] - ys;
}
rect(xs,ys,ws,hs);
}
}
if (experiment) {
text("Click where you see the change. Trial: " + counter, 20, 20)
trial=presentationOrder[counter];
stimulus = stimuli[trial];
if (frameCount < 5) { // we show the first image at frame 1,2,3,4
image(stimulus[0], 0, 50);
} else if (frameCount > 5 & frameCount < 10) { // second image @ 6,7,8,9
image(stimulus[1], 0, 50);
} else { // we show the background at frame 5 and 10
background(128);
}
if (frameCount == 10) {
// frameCount is a p5 default variable. I.e. it already exists, without me needing to define it. Every frame it is automatically incremented.
frameCount = 0;
}
}
console.log(mouseY)
}
function clickOnCanvas() {
if (experiment) {
let row = output.addRow();
// we add the x,y mouse position. 0,0 is top left, 1,1 is bottom right
x = mouseX / stimuli[trial][0].width
y = (mouseY - image_offset) / stimuli[trial][0].height
// calculate distance from 'correct' answer and the given answer
let d = float(dist(
targetCoords[trial][0], // The 'correct' answer in the input data
targetCoords[trial][1],
x, // the given answer from the participant
y
));
row.set('pre',prenames[trial]);
row.set('post',postnames[trial]);
row.setNum('xfiducial',targetCoords[trial][0]);
row.setNum('yfiducial',targetCoords[trial][1]);
row.setNum('xchosen', x);
row.setNum('ychosen', y);
row.setNum('dist', d);
row.setNum('rt (ms)',millis()-timestamp);
timestamp=millis();
nextTrial();
}
else { // first time, after that ignore
frameCount = 0;
experiment = true
console.log("experiment start")
background(128);
timestamp=millis();
}
}
//called when mouse is pressed in setup mode
function startSelect(){
targetSelection.push([mouseX,mouseY]);
selecting = true;
}
//called when mouse is released in setup mode
function endSelect(){
//sort numbers so they're in "x,y,w,h" format
let xs, ys, ws, hs;
if(mouseX>targetSelection[selectionCount][0]){
xs = targetSelection[selectionCount][0];
ws = mouseX - xs;
}else{
xs = mouseX;
ws = targetSelection[selectionCount][0] - xs;
}
if(mouseY>targetSelection[selectionCount][1]){
ys = targetSelection[selectionCount][1];
hs = mouseY - ys;
}else{
ys = mouseY;
hs = targetSelection[selectionCount][1] - ys;
}
targetSelection[selectionCount] = [int(xs), int(ys), int(ws), int(hs)];
for(i=0;i<targetSelection.length;i++){
if(i==0){
targetsText = '[[' + targetSelection[i] + ']';
}
else{
targetsText += ', [' + targetSelection[i] + ']';
}
}
targetsText += "]";
res.html(setupText + targetsText);
selecting = false;
selectionCount++;
print(targetSelection);
}
function nextTrial() {
// start the next trial
counter++;
frameCount = 0;
background(128);
if (counter == stimuli.length) {
experiment = false // experiment has ended
console.log("experiment end");
text("That's the end of the experiment!", 20, 20)
saveTable(output, 'data.csv');
}
}