Merge pull request #1375 from jspsych/bugfix-image-canvas

add img onload fn to draw image when loaded - fixes #1305
This commit is contained in:
Becky Gilbert 2021-01-18 09:52:02 -08:00 committed by GitHub
commit 519abbdb47
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 108 additions and 60 deletions

View File

@ -107,6 +107,7 @@ jsPsych.plugins["image-button-response"] = (function() {
var height, width;
var html;
if (trial.render_on_canvas) {
var image_drawn = false;
// first clear the display element (because the render_on_canvas method appends to display_element instead of overwriting it with .innerHTML)
if (display_element.hasChildNodes()) {
// can't loop through child list because the list will be modified by .removeChild()
@ -119,29 +120,40 @@ jsPsych.plugins["image-button-response"] = (function() {
canvas.id = "jspsych-image-button-response-stimulus";
canvas.style.margin = 0;
canvas.style.padding = 0;
var ctx = canvas.getContext("2d");
var img = new Image();
img.onload = function() {
// if image wasn't preloaded, then it will need to be drawn whenever it finishes loading
if (!image_drawn) {
getHeightWidth(); // only possible to get width/height after image loads
ctx.drawImage(img,0,0,width,height);
}
};
img.src = trial.stimulus;
// determine image height and width
if (trial.stimulus_height !== null) {
height = trial.stimulus_height;
if (trial.stimulus_width == null && trial.maintain_aspect_ratio) {
width = img.naturalWidth * (trial.stimulus_height/img.naturalHeight);
// get/set image height and width - this can only be done after image loads because uses image's naturalWidth/naturalHeight properties
function getHeightWidth() {
if (trial.stimulus_height !== null) {
height = trial.stimulus_height;
if (trial.stimulus_width == null && trial.maintain_aspect_ratio) {
width = img.naturalWidth * (trial.stimulus_height/img.naturalHeight);
}
} else {
height = img.naturalHeight;
}
} else {
height = img.naturalHeight;
}
if (trial.stimulus_width !== null) {
width = trial.stimulus_width;
if (trial.stimulus_height == null && trial.maintain_aspect_ratio) {
height = img.naturalHeight * (trial.stimulus_width/img.naturalWidth);
if (trial.stimulus_width !== null) {
width = trial.stimulus_width;
if (trial.stimulus_height == null && trial.maintain_aspect_ratio) {
height = img.naturalHeight * (trial.stimulus_width/img.naturalWidth);
}
} else if (!(trial.stimulus_height !== null & trial.maintain_aspect_ratio)) {
// if stimulus width is null, only use the image's natural width if the width value wasn't set
// in the if statement above, based on a specified height and maintain_aspect_ratio = true
width = img.naturalWidth;
}
} else if (!(trial.stimulus_height !== null & trial.maintain_aspect_ratio)) {
// if stimulus width is null, only use the image's natural width if the width value wasn't set
// in the if statement above, based on a specified height and maintain_aspect_ratio = true
width = img.naturalWidth;
canvas.height = height;
canvas.width = width;
}
canvas.height = height;
canvas.width = width;
getHeightWidth(); // call now, in case image loads immediately (is cached)
// create buttons
var buttons = [];
if (Array.isArray(trial.button_html)) {
@ -165,8 +177,12 @@ jsPsych.plugins["image-button-response"] = (function() {
btngroup_div.innerHTML = html;
// add canvas to screen and draw image
display_element.insertBefore(canvas, null);
var ctx = canvas.getContext("2d");
ctx.drawImage(img,0,0,width,height);
if (img.complete && Number.isFinite(width) && Number.isFinite(height)) {
// if image has loaded and width/height have been set, then draw it now
// (don't rely on img onload function to draw image when image is in the cache, because that causes a delay in the image presentation)
ctx.drawImage(img,0,0,width,height);
image_drawn = true;
}
// add buttons to screen
display_element.insertBefore(btngroup_div, canvas.nextElementSibling);
// add prompt if there is one

View File

@ -88,6 +88,7 @@ jsPsych.plugins["image-keyboard-response"] = (function() {
var height, width;
if (trial.render_on_canvas) {
var image_drawn = false;
// first clear the display element (because the render_on_canvas method appends to display_element instead of overwriting it with .innerHTML)
if (display_element.hasChildNodes()) {
// can't loop through child list because the list will be modified by .removeChild()
@ -100,33 +101,48 @@ jsPsych.plugins["image-keyboard-response"] = (function() {
canvas.id = "jspsych-image-keyboard-response-stimulus";
canvas.style.margin = 0;
canvas.style.padding = 0;
var ctx = canvas.getContext("2d");
var img = new Image();
img.onload = function() {
// if image wasn't preloaded, then it will need to be drawn whenever it finishes loading
if (!image_drawn) {
getHeightWidth(); // only possible to get width/height after image loads
ctx.drawImage(img,0,0,width,height);
}
};
img.src = trial.stimulus;
// determine image height and width
if (trial.stimulus_height !== null) {
height = trial.stimulus_height;
if (trial.stimulus_width == null && trial.maintain_aspect_ratio) {
width = img.naturalWidth * (trial.stimulus_height/img.naturalHeight);
// get/set image height and width - this can only be done after image loads because uses image's naturalWidth/naturalHeight properties
function getHeightWidth() {
if (trial.stimulus_height !== null) {
height = trial.stimulus_height;
if (trial.stimulus_width == null && trial.maintain_aspect_ratio) {
width = img.naturalWidth * (trial.stimulus_height/img.naturalHeight);
}
} else {
height = img.naturalHeight;
}
} else {
height = img.naturalHeight;
}
if (trial.stimulus_width !== null) {
width = trial.stimulus_width;
if (trial.stimulus_height == null && trial.maintain_aspect_ratio) {
height = img.naturalHeight * (trial.stimulus_width/img.naturalWidth);
if (trial.stimulus_width !== null) {
width = trial.stimulus_width;
if (trial.stimulus_height == null && trial.maintain_aspect_ratio) {
height = img.naturalHeight * (trial.stimulus_width/img.naturalWidth);
}
} else if (!(trial.stimulus_height !== null & trial.maintain_aspect_ratio)) {
// if stimulus width is null, only use the image's natural width if the width value wasn't set
// in the if statement above, based on a specified height and maintain_aspect_ratio = true
width = img.naturalWidth;
}
} else if (!(trial.stimulus_height !== null & trial.maintain_aspect_ratio)) {
// if stimulus width is null, only use the image's natural width if the width value wasn't set
// in the if statement above, based on a specified height and maintain_aspect_ratio = true
width = img.naturalWidth;
canvas.height = height;
canvas.width = width;
}
canvas.height = height;
canvas.width = width;
getHeightWidth(); // call now, in case image loads immediately (is cached)
// add canvas and draw image
display_element.insertBefore(canvas, null);
var ctx = canvas.getContext("2d");
ctx.drawImage(img,0,0,width,height);
if (img.complete && Number.isFinite(width) && Number.isFinite(height)) {
// if image has loaded and width/height have been set, then draw it now
// (don't rely on img onload function to draw image when image is in the cache, because that causes a delay in the image presentation)
ctx.drawImage(img,0,0,width,height);
image_drawn = true;
}
// add prompt if there is one
if (trial.prompt !== null) {
display_element.insertAdjacentHTML('beforeend', trial.prompt);

View File

@ -135,6 +135,7 @@ jsPsych.plugins['image-slider-response'] = (function() {
var half_thumb_width = 7.5;
if (trial.render_on_canvas) {
var image_drawn = false;
// first clear the display element (because the render_on_canvas method appends to display_element instead of overwriting it with .innerHTML)
if (display_element.hasChildNodes()) {
// can't loop through child list because the list will be modified by .removeChild()
@ -150,29 +151,40 @@ jsPsych.plugins['image-slider-response'] = (function() {
canvas.id = "jspsych-image-slider-response-stimulus";
canvas.style.margin = 0;
canvas.style.padding = 0;
var ctx = canvas.getContext("2d");
var img = new Image();
img.onload = function() {
// if image wasn't preloaded, then it will need to be drawn whenever it finishes loading
if (!image_drawn) {
getHeightWidth(); // only possible to get width/height after image loads
ctx.drawImage(img,0,0,width,height);
}
};
img.src = trial.stimulus;
// determine image height and width
if (trial.stimulus_height !== null) {
height = trial.stimulus_height;
if (trial.stimulus_width == null && trial.maintain_aspect_ratio) {
width = img.naturalWidth * (trial.stimulus_height/img.naturalHeight);
// get/set image height and width - this can only be done after image loads because uses image's naturalWidth/naturalHeight properties
function getHeightWidth() {
if (trial.stimulus_height !== null) {
height = trial.stimulus_height;
if (trial.stimulus_width == null && trial.maintain_aspect_ratio) {
width = img.naturalWidth * (trial.stimulus_height/img.naturalHeight);
}
} else {
height = img.naturalHeight;
}
} else {
height = img.naturalHeight;
}
if (trial.stimulus_width !== null) {
width = trial.stimulus_width;
if (trial.stimulus_height == null && trial.maintain_aspect_ratio) {
height = img.naturalHeight * (trial.stimulus_width/img.naturalWidth);
if (trial.stimulus_width !== null) {
width = trial.stimulus_width;
if (trial.stimulus_height == null && trial.maintain_aspect_ratio) {
height = img.naturalHeight * (trial.stimulus_width/img.naturalWidth);
}
} else if (!(trial.stimulus_height !== null & trial.maintain_aspect_ratio)) {
// if stimulus width is null, only use the image's natural width if the width value wasn't set
// in the if statement above, based on a specified height and maintain_aspect_ratio = true
width = img.naturalWidth;
}
} else if (!(trial.stimulus_height !== null & trial.maintain_aspect_ratio)) {
// if stimulus width is null, only use the image's natural width if the width value wasn't set
// in the if statement above, based on a specified height and maintain_aspect_ratio = true
width = img.naturalWidth;
canvas.height = height;
canvas.width = width;
}
canvas.height = height;
canvas.width = width;
getHeightWidth(); // call now, in case image loads immediately (is cached)
// create container with slider and labels
var slider_container = document.createElement('div');
slider_container.classList.add("jspsych-image-slider-response-container");
@ -201,8 +213,12 @@ jsPsych.plugins['image-slider-response'] = (function() {
content_wrapper.insertBefore(slider_container, canvas.nextElementSibling);
// add content wrapper div to screen and draw image on canvas
display_element.insertBefore(content_wrapper, null);
var ctx = canvas.getContext("2d");
ctx.drawImage(img,0,0,width,height);
if (img.complete && Number.isFinite(width) && Number.isFinite(height)) {
// if image has loaded and width/height have been set, then draw it now
// (don't rely on img onload function to draw image when image is in the cache, because that causes a delay in the image presentation)
ctx.drawImage(img,0,0,width,height);
image_drawn = true;
}
// add prompt if there is one
if (trial.prompt !== null) {
display_element.insertAdjacentHTML('beforeend', trial.prompt);