Running a JavaScript loop through an array using setTimeout can encounter issues with undefined split

I currently have a WordPress page that has a feature allowing users to create a small comic strip. This feature generates three images representing the comic strip.

Users can customize their character's hair, eyes, t-shirt, choose from five scenarios, and select from three options for how the scenario ends. The output consists of three images or panels made up of layered PNGs. These layered images include the chosen hair, eyes, t-shirt, backgrounds for selected scenarios, etc.

To make these images shareable, I decided to use html2canvas to render all possible combinations of images that could be created from the user choices, totaling 1260 variations. As html2canvas can be unreliable for live usage, I am attempting to generate all images programmatically beforehand.

The image generation process is going smoothly through my array of 1260 potential combinations until approximately halfway when I encounter a "split undefined" error suddenly. Despite checking each value in all 1260 indices, everything appears to be in order, leaving me completely puzzled.

Here is the JavaScript code:

// TWo-dimensional (2D) array representing the possible values a user can select per HTML panel. Each choice reveals the next panel.
var allArrays = [['0','1','2','3','4','5','6'], ['1','2'], ['0','1','2','3','4','5'], ['1','2','3','4','5'], ['1','2','3']];

// Recursive function to find all unique combinations of choices that users can make, resulting in 1260 possibilities
function allPossibleCases(arr) {
    if (arr.length === 1) {
        return arr[0];
    } else {
        var result = [];
        var allCasesOfRest = allPossibleCases(arr.slice(1));
        for (var i = 0; i < allCasesOfRest.length; i++) {
            for (var j = 0; j < arr[0].length; j++) {
                result.push(arr[0][j] + " " + allCasesOfRest[i]);
            }
        }
        return result;
    }
}

// Initiate recursion to get the 2D array of results
var uniqueIds = allPossibleCases(allArrays);

// Flatten the resulting 2D array output from 'allPossibleCases' into a single array with all 1260 unique combinations
var merged = [];
merged = merged.concat.apply(merged, uniqueIds);

// Output the flattened array with all 1260 values
console.log(merged);

var id1 = 0;
var id2 = 0;
var id3 = 0;
var id4 = 0;
var id5 = 0;

// Incrementation value for the myTimer function
var i = 0;

function myTimer() {

    // Extract each string integer from the merged array items (all 1260) to populate individual text inputs on the website's frontend, simulating user choices programmatically.
    var str = merged[i];
    console.log('Current render increment = ' + i);
    console.log('The array\'s current increment = ' + str);
    var res = str.split(" ");

    // Cast split string integers to proper integers
    id1 = parseInt(res[0]);
    id2 = parseInt(res[1]);
    id3 = parseInt(res[2]);
    id4 = parseInt(res[3]);
    id5 = parseInt(res[4]);

    // Populate form fields with fake user choices
    $('.manualImageGen .hair').val(id1);
    $('.manualImageGen .eyes').val(id2);
    $('.manualImageGen .outfit').val(id3);
    $('.manualImageGen .scenario').val(id4);
    $('.manualImageGen .resolution').val(id5);

    // Update Angular UI
    $('.manualImageGen input').trigger('input');

    // Assign a unique ID to the image generated by html2canvas related to one of the 1260 outcomes
    var fileid = res[0] + res[1] + res[2] + res[3] + res[4];

    // Capture a screenshot of the final image using html2canvas after faking the selections
    html2canvas($('.finalImages'), {
        onrendered: function(canvas) {

            var data = canvas.toDataURL();

            $.ajax({
                type: "POST",
                url: ajaxurl,
                data: { 
                    'action':'nopriv_ra_addrelationstick',
                    'relStick': data,
                    'fileid': fileid
                }
            })
            .done(function(msg) {
                if (msg == "false") {
                    alert('Sorry but you need to log in to save your R Stick');
                }
            });

        }
    });

    if (i <= merged.length - 1) {
        i++;
        console.log("Items left to render = " + merged.length--);
    } else {
        clearInterval(myVar);
    }

}

// Perform the myTimer function every second via setTimeout to avoid browser freezes and allow html2canvas to complete its task
var myVar = setInterval(function () {myTimer()}, 1000);

Answer №1

If you happen to have those images stored on your domain already, here is the method I suggest for resolving this issue:

var layer0 = document.getElementById('input_layer0').value;
var layer1 = document.getElementById('input_layer1').value;
var layer2 = document.getElementById('input_layer2').value;
...
var panel = [layers[0][layer0],layers[1][layer1],layers[2][layer2]...];
var c = document.createElement('canvas').getContext('2d');
c.canvas.width = 200;
c.canvas.height = 200;
c.clearRect(0,0,200,200);
for(var i=0;i<panel.length;i++)
 c.drawImage(panel[i],0,0);
document.getElementById('result_image').src = c.canvas.toDataURL();

In this code snippet, "layers" refers to an array containing image arrays representing different layers.

i = new Image();
i.src = 'bg1.jpg';
layers[0].push(i);
i = new Image();
i.src = 'bg2.jpg';
layers[0].push(i);
i = new Image();
i.src = 'body_sitting.png';
layers[1].push(i);
i = new Image();
i.src = 'body_standing.png';
layers[1].push(i);

And so forth.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips to retrieve an Angular `value` from outside the module

customConfig.js angular.module("steam") .value("customConfig", { baseurl: "http://dev-back1.techgrind.asia/" }); To access the value outside the module, replace the " .." with customConfig.baseurl apiTest.js var frisby = require("frisby"); fris ...

Convert the text '#ff00fffirstword#445533secondword#008877thirdword' to HTML tag format

Is there a way to convert the string #ff00fffirstword#445533secondword#008877thirdword into <font color='#ff00ff'>firstword</font><font color='#445533'>secondword</font><font color='#008877'>thi ...

When null is multiplied by any number in Typescript, the result should be null, not 0

In C#, I encountered a situation: decimal? x; // number decimal? y; // null c=x*y //c returns null Contrastingly, in TypeScript: let x:number=null; let y:number=12; c=x*y //c returns 0 **How can I achieve null instead of 0 in TypeScript? I'm look ...

What is the best method to determine if a text box is filled or empty?

I need to verify whether a text box is populated with a name. If it is empty, an alert message should be shown upon clicking the submit button, and the page should not proceed with submitting the blank value. If there is a value in the text box, then that ...

Issue with lodash set function: Unable to generate a sub-object with an integer key

Having trouble with setting an object using Lodash's set function, specifically in this format: { '288452': { '57': 'value1', '69': 'value2', '01': 'value3 ...

Buefy: Secure the header of the table in place while allowing the rows to scroll freely

How can I make the header of the table component stay fixed while allowing only the rows to scroll? ...

Having trouble with the splice function in JavaScript when trying to remove a React component

I have a parent component called Show and a child component called Editable. The Parent component contains an array where Child elements are pushed. I've included a screenshot for better understanding. https://i.sstatic.net/x3MvH.png In my code, I&a ...

Organizing data in TypeScript

Is there a way to alphabetically sort this list of objects by name using TypeScript? "[{name:"Prasanna",age:"22",sex:"Male",Designation:"System Engineer",Location:"Chennai"}, {name:"Nithya",age:"21",sex:"Female",Designation:"System Engineer",Location ...

Setting up a plan for executing Javascript server side scripts

Can JavaScript be executed server-side? If I attempt to access a script , can it be scheduled to run every four hours? Would most web hosts allow this, or is it considered poor webmaster practice? The main goal is to activate my website's webcrawler/ ...

The specified type does not meet the constraint as it lacks the required index signature

I'm currently working on refactoring a TypeScript project that utilizes React Hooks. While I have some knowledge of TypeScript, I am still more of a beginner than an expert. My main goal is to create reusable code for this project through the use of ...

Preserving state values with the useState hook throughout various function invocations

When I click the button to delete department rows from my table, I am using the "deleteDepartment" function. The issue arises when trying to get the selected row index in the "selectedRows" hook. It seems that the "rowSelection" state keeps accumulating va ...

Encountered an Error: Trying to use a function that is undefined - While utilizing Jquery Tabs

Working on implementing Jquery Tabs using the "description" and "reviews" li tags as tabs. Testing it out here . Everything seems to be functioning correctly here Key Points: This is Wordpress Multi-Site setup. The issue occurs in certain folders or "si ...

Expanding JSON array parameter with jQuery

Currently, I am diving into the world of jQuery extend method and trying to grasp its concepts. According to the official documentation, the merge operation carried out by $.extend() is not recursive by default. This means that if a property of the first o ...

When accessing tagName in Internet Explorer 11, the name will be returned in uppercase with the namespace included. However, in Internet Explorer 7,

My goal is to extract all child elements within a DOM element with a specific tag name and store them in an array. <xs:menu> <xs:submenu> </xs:submenu> </xs:menu> var item=menu.children.tags("XS:SUBMENU") ; Internet Explorer 7 ...

Issue with the Jquery rich text plugin in Internet Explorer causing functionality problems

I have encountered an issue while trying to use a jQuery richtext editor in Internet Explorer. Interestingly, it fails to work in IE but functions properly in Chrome. Here is the code snippet where I call the plugin and it works well in all browsers excep ...

Is it possible to define a variable within a JavaScript function and then access it outside of the function?

I have a Node.js application where I need to define a variable inside a function and access its value outside the function as well. Can someone provide guidance on how to achieve this in my code? var readline = require('readline'); var rl = read ...

Can anyone explain the meaning of (0, _jquery["default"]) in relation to jQuery selectors or functions?

Trying to implement jQuery on an offline page can be challenging when dealing with EmberJS, RequireJS, and other technologies. My goal is to replace complex code with simple jQuery. The HTML below should respond to user interaction: Loading i ...

Chart.js is able to read JSON files offline, but it encounters difficulties reading them online

I am encountering an issue with my chart.js. When I attempt to read an offline JSON file, the chart appears as expected. However, when using an online JSON file from Firebase, it only displays a white screen. I have exported a JSON file from Firebase and ...

Learn how to bind a click event to a directive in AngularJS

Hello there! I am a beginner in AngularJS and I have a situation where I need to change the background color of a div with the ID "#single" and then make a call to the back-end server on a click event. Unfortunately, I am unsure how to achieve this using a ...

Passing arguments with $emit - Vue

Here is a simple method to handle alerts using $emit. But when passing arguments, it seems like the event is not being triggered at all. The goal is to update the value of alert with the result. Listening for the event on mount: this.$eventHub.$on(' ...