I have a data set which contains an array of layers for an HTML5 canvas. I’m using fabric.js to manage all elements of my canvas. The layers are supposed to load in order, forming different scenes. I’m looping through the data set via a forEach loop. (EDIT - after further research, I see that both for and forEach loops are synchronous).
The problem is, once the code gets to the point of loading an image, asynchronous behavior kicks in and the process jumps to the next iteration of my loop to start processing the next layer. As you can imagine, this leads to layers appearing out of order on the canvas and ultimately distorted scenes.
I’ve been working on this and researching it for weeks and haven’t had much luck.
Is there any way to prevent a forEach loop (or a for loop for that matter) to not start the next iteration before the current one finishes?
Here is my code for the forEach loop:
$.ajax({
url: url,
method: "GET"
}).done(function (data) {
data.forEach(function (data) {
switch (data.layer_type) {
case "texture":
{
addTexture(data)
break;
}
case "color":
{
addColor(data)
break;
}
case "room":
{
addBaseImg(data);
break;
}
case "decor":
{
addBaseImg(data);
break;
}
case "floor":
{
addBaseImg(data);
break;
}
default:
{
addOtherObjects(data);
}
}
});
});
Here is an example of a case that loads an image:
The initial function triggers a click event:
function addTexture(data) {
$('img[data-obj-id="' + data.object_id + '"]').trigger("click");
}
that leads to this function:
$(document).on("click", ".img-patt", function () {
var imgURL = $(this).data("src");
var _this = this;
//this is where the process skips to the next iteration, before the image is loaded and added to the canvas
fabric.Image.fromURL(imgURL, function (img) {
//some code to handle the pattern removed from here just to shorten up the snippet
var rect = new fabric.Rect({
name: "texture",
visible: true,
selectable: false,
data: {
type: $(_this).data("type"),
objid: $(_this).data("obj-id")
},
top: 0,
left: 0,
width: fabCanvas.width,
height: fabCanvas.height,
fill: pattern
});
fabCanvas.add(rect);
fabCanvas.renderAll();
});
});