xxxxxxxxxx
295
/*
BUBBLE VIEW
INPUT: IMAGE, PROMPT
OUTPUT: VIEWING COORDINATES, PROMPT RESPONSE
HOW TO USE:
1. In SAVE_DATA_SHEET_NAME, write the name of the sheet you want to save the data to, preferrably as: "studentID_visualsearch"
2. Upload your image(s) to the images folder.
3. Write the names of the images in filenames.
4. Write a prompt for the participant to answer and to give them a goal in viewing the image
OR do not write a prompt and set freelook to true.
> Click File>Share and send the "Fullscreen" link to your participants
*/
// !! Change this to you own project's name in order to save your experiments data.
// The data can be found on the google drive
const SAVE_DATA_SHEET_NAME = "5600065_bubbleview";
// write the filenames of your images as strings
const filenames = [
"Realistic_13.jpg",
"Realistic_6.png",
"Sur_mirrorreflection.jpg",
"Sur_painting.jpg"
];
// Here you can change the prompt the user gets in the text box.
// If you want specific ones for each image, write them in the array in the same order as filenames
const prompt = ["On what base did you explore the scene? What are your thoughts on the scene?"];
// Set this to false to remove the text input
const freelook = false;
// radius of the aperture
let radius = [50];
// set this to false to show images in the order of filenames
const randomOrder = true;
// ************* END OF PARAMETERS *************
let blurims = [],
sharpims = [];
let presentationOrder = [];
let aperture, currad;
let mwidth, mheight;
let trial = 0,
imgtrial = 0;
let data, data2;
let max_width = 0,
max_height = 0;
let imgscale;
let sub;
let clicked = false,
done = false,
saved = false;
function preload() {
for (i = 0; i < filenames.length; i++) {
sharpims.push(loadImage("images/" + filenames[i]));
blurims.push(loadImage("images/" + filenames[i]));
}
}
function setup() {
// determine which image has the biggest width/height
for (i = 0; i < sharpims.length; i++) {
presentationOrder[i] = i;
blurims[i].filter(BLUR, 10);
if (sharpims[i].width > max_width) {
max_width = sharpims[i].width;
}
if (sharpims[i].height > max_height) {
max_height = sharpims[i].height;
}
}
if (randomOrder) {
shuffle(presentationOrder, true);
}
//use the image size for the canvas, so mind that your images are the right size
cnv = createCanvas(max_width, max_height);
cnv.parent("sketch");
document
.getElementById("sketch")
.setAttribute("style", "height:" + max_height + "px");
cnv.mouseClicked(clickOnCanvas);
setApertureAndPrompt();
noCursor();
sub = createButton("Submit").mousePressed(submit);
if (freelook) {
sub.position(0, cnv.height);
} else {
sub.position(0, cnv.height + 100);
}
data = new p5.Table();
data.columns = ["image", "x", "y", "r"];
for (i = 0; i < filenames.length; i++) {
data.addColumn(filenames[i]);
data.addColumn(sharpims[i].width);
data.addColumn(sharpims[i].height);
data.addColumn("answer");
}
}
function draw() {
background(0);
imageMode(CORNER);
image(blurims[presentationOrder[imgtrial]], 0, 0);
imageMode(CENTER);
if (clicked) {
image(aperture, data.getNum(trial - 1, "x"), data.getNum(trial - 1, "y"));
}
noFill();
stroke(255, 0, 0);
circle(mouseX, mouseY, 2 * currad);
if (done) {
textSize(16);
noStroke();
fill(0);
cursor(ARROW);
background(255);
text("Experiment over!", 30, 60);
if (!saved) {
text("Sending data...", 30, 90);
} else {
text("Data sent!", 30, 90);
}
}
}
function setApertureAndPrompt() {
if (!freelook) {
if (prompt[presentationOrder[imgtrial]]) {
document.getElementById("input").placeholder =
prompt[presentationOrder[imgtrial]];
} else {
document.getElementById("input").placeholder = prompt[0];
}
} else if (document.getElementById("input")) {
document.getElementById("input").remove();
}
currad = radius[presentationOrder[imgtrial]];
if (currad) {
aperture = createImage(2 * currad, 2 * currad);
} else {
aperture = createImage(2 * radius[0], 2 * radius[0]);
currad = radius[0];
}
}
function clickOnCanvas() {
if (!done) {
trial++;
sharpims[presentationOrder[imgtrial]].loadPixels();
aperture.loadPixels();
let c;
for (let i = 0; i < aperture.width; i++) {
for (let j = 0; j < aperture.height; j++) {
if (
dist(i, j, aperture.width / 2, aperture.height / 2) <
aperture.width / 2
) {
c = sharpims[presentationOrder[imgtrial]].get(
mouseX + i - aperture.width / 2,
mouseY + j - aperture.height / 2
);
aperture.set(i, j, c);
} else {
aperture.set(i, j, color(0, 0, 0, 0));
}
}
}
aperture.updatePixels();
let newRow = data.addRow();
newRow.setString("image", filenames[presentationOrder[imgtrial]]);
newRow.setNum("x", int(mouseX));
newRow.setNum("y", int(mouseY));
newRow.setNum("r", currad);
if (clicked) {
clicked = true;
} else {
clicked = true;
}
}
}
function submit() {
clicked = false;
if (!freelook) {
data.columns[7 + presentationOrder[imgtrial] * 4] = document.getElementById(
"input"
).value;
document.getElementById("input").value = "";
}
// document.getElementById("input").placeholder = 'New placeholder...';
if (imgtrial + 1 == filenames.length) {
done = true;
document.getElementById("input").remove();
sub.remove();
// Translate the p5 Table to a two dimensional array and send it to Google sheets
dataExport = data.getArray();
dataExport.unshift(data.columns);
saveToSheet(SAVE_DATA_SHEET_NAME, dataExport);
} else {
imgtrial++;
setApertureAndPrompt();
}
}
/**
* This function saves the data to a google sheet of the given name.
* Make sure that the name is unique for you project!
* If your name is not unique then you will share a google sheet with someone else.
*
*
* @param {string} sheetName - The name of you sheet. Make sure it is unique to your project.
* @param {Array<Array>} data - A two dimensional array representing the data.
* Data example:
* data = [
* (row1:) [col1, col2, col3],
* (row2:) [col1, col2, col3]
* ]
* @param {string} [tabName] - (OPTIONAL) The name of the tab/worksheet that this instance of data will be in.
* If you leave this empty it will fall back to using the current time of data submission as tab name
* IMPORTANT! if you are using custom tab names make sure that every name is unique.
* If a name already exists saving wil result in an error.
*/
async function saveToSheet(sheetName, data, tabName) {
// Safety check
if (!sheetName) {
return console.error("The name for the sheet was not valid!");
}
if (!data || data.length === 0) {
return console.error("Cannot save empty data!");
}
// Building save request
const requestBody = {
sheetName,
data,
};
// Add tabName if it exists
if (tabName && typeof tabName === "string") {
requestBody.tabName = tabName;
}
try {
// Send the save request
const response = await fetch("https://node.bykrijgsman.com/save-data", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(requestBody),
});
const result = await response.text();
console.log(result);
if (result == "SAVED!") {
saved = true;
}
} catch (e) {
// There was an error while saving if we get here!
console.error(e);
}
}