xxxxxxxxxx
253
/*
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 = false;
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 = [[196,70,48,44], [278,372,93,86], [192,179,41,34], [400,57,74,53], [294,407,61,59], [178,318,67,27]]
const randomOrder = true;
//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
var experiment = false;
var stimuli = [];
let presentationOrder = [];
var trial = 0
let randomtrial;
var max_height = 0;
var max_width = 0;
var image_offset = 50;
var stimulus;
let startTime;
function preload() {
// create a table to store results
data = new p5.Table();
data.columns = ['target','reaction time (ms)','hit/distance','x','y']
for (let i = 0; i < prenames.length; i++) {
stimuli.push([
loadImage('images/' + prenames[i]),
loadImage('images/' + postnames[i])
]);
presentationOrder[i] = i;
}
if(randomOrder){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, 50);
tint(255, 127); // Display at half opacity
image(stimuli[selectionCount][1],0, 50);
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: " + trial+1, 20, 20)
randomtrial=presentationOrder[trial];
stimulus = stimuli[randomtrial];
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 = 0;
}
}
}
function clickOnCanvas() {
if (experiment) {
// check accuracy
let randomtrial=presentationOrder[trial]; //i really dont like this
let d;
if(mouseX>=targetCoords[randomtrial][0] && mouseX<=targetCoords[randomtrial][0] + targetCoords[randomtrial][2] && mouseY>=targetCoords[randomtrial][1] && mouseY<=targetCoords[randomtrial][1] + targetCoords[randomtrial][3]){
d = 0;
} else{
var dx = Math.max(targetCoords[randomtrial][0] - mouseX, 0, mouseX - (targetCoords[randomtrial][0] + targetCoords[randomtrial][2]));
var dy = Math.max(targetCoords[randomtrial][1] - mouseY, 0, mouseY - (targetCoords[randomtrial][1] + targetCoords[randomtrial][3]));
d = sqrt(dx*dx + dy*dy)
}
//write result to table
let newRow = data.addRow();
newRow.setNum('target', presentationOrder[trial]);
newRow.setNum('reaction time (ms)', millis()-startTime);
newRow.setNum('hit/distance', int(d));
newRow.setNum('x', int(mouseX));
newRow.setNum('y', int(mouseY));
nextTrial();
}
else { // first time, after that ignore
frameCount = 0;
experiment = true
console.log("experiment start")
background(128);
startTime=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
trial++;
frameCount = 0;
background(128);
if (trial == stimuli.length) {
experiment = false // experiment has ended
console.log("experiment end");
text("That's the end of the experiment!", 20, 20)
saveTable(data, 'data.csv');
}
}