The challenges of using Three.JS and Blazor: Solving Black Canvas and Console Errors in WebGL

Exploring the world of Blazor web assembly, I embarked on a project to harness the power of JSInterop with Three.JS to draw lines. Following the guidelines provided in their tutorials available Here, I diligently installed Three.JS using npm and webpack, with a prebuild event neatly tucked away in my csproj file.

<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
    <Exec Command="npm install" WorkingDirectory="NpmJS" />
    <Exec Command="npm run build" WorkingDirectory="NpmJS" />
</Target>

Trouble arose when the canvas stubbornly appeared black, devoid of any creations, while the console warned me of numerous errors. Any guidance on troubleshooting this snag would be immensely appreciated. I understand that venturing into the realm of Three.js and webgl within Blazor is slightly uncharted territory. Here is the initial error that surfaced:

crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: (intermediate value).setFromPoints is not a function
      TypeError: (intermediate value).setFromPoints is not a function
          at Object.drawLine (https://localhost:44370/javascript/threeTutorial.js:21:53)
          at https://localhost:44370/_framework/blazor.webassembly.js:1:3942
          at new Promise (<anonymous>)
          at Object.beginInvokeJSFromDotNet (https://localhost:44370/_framework/blazor.webassembly.js:1:3908)
          at Object.w [as invokeJSFromDotNet] (https://localhost:44370/_framework/blazor.webassembly.js:1:64232)
          at _mono_wasm_invoke_js_blazor (https://localhost:44370/_framework/dotnet.5.0.10.js:1:190800)
          at do_icall (<anonymous>:wasm-function[10596]:0x194e4e)
          at do_icall_wrapper (<anonymous>:wasm-function[3305]:0x79df9)
          at interp_exec_method (<anonymous>:wasm-function[2155]:0x44ad3)
          at interp_runtime_invoke (<anonymous>:wasm-function[7862]:0x12efff)

Further investigations through the developer console revealed that THREE.BufferGeometry() was undefined, leading to the error when a method was called on an undefined object.

The code behind my Razor Page appeared as follows:

namespace MyProject.Shared.Components
{
    /// <summary>
    /// The canvas for browser rendering using Webgl.
    /// </summary>
    public partial class GameCanvas : MyLayoutComponentBase
    {       

        protected override async Task OnAfterRenderAsync(bool firstRender)
        {
            if (firstRender)
            {
                await JSRuntime.InvokeVoidAsync("threeTutorial.drawLine");
            }
        }
    }
}

Here's a snippet of my Javascript File:

window.threeTutorial = {
    drawLine: function () {
        const renderer = new THREE.WebGLRenderer();
        renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.getElementById("gameCanvas").appendChild(renderer.domElement);

        const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 500);
        camera.position.set(0, 0, 100);
        camera.lookAt(0, 0, 0);

        const scene = new THREE.Scene();
        //create a blue LineBasicMaterial
        const material = new THREE.LineBasicMaterial({ color: 0x0000ff });

        const points = [];
        points.push(new THREE.Vector3(- 10, 0, 0));
        points.push(new THREE.Vector3(0, 10, 0));
        points.push(new THREE.Vector3(10, 0, 0));

        const geometry = new THREE.BufferGeometry().setFromPoints(points);

        const line = new THREE.Line(geometry, material);

        scene.add(line);
        renderer.render(scene, camera);
    }
}

I also included the following scripts in my wwwroot.index.html page:

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r79/three.min.js"></script>
<script src="javascript/threeTutorial.js"></script>

Additionally, I imported THREE in my NpmJS.src.index.js file like so:

import * as THREE from 'three';

Answer №1

Inmate 849 was spot on:

"Give the newest version of three.js a try. As far as I remember, r79 does not include .setFromPoints() implementation for BufferGeometry"

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

Using TinyMCE editor to handle postbacks on an ASP.NET page

I came up with this code snippet to integrate TinyMCE (a JavaScript "richtext" editor) into an ASP page. The ASP page features a textbox named "art_content", which generates a ClientID like "ctl00_hold_selectionblock_art_content". One issue I encountered ...

Click on the form to initiate when the action is set to "javascript:void(0)"

I am working on an HTML step form that needs to be submitted after passing validation and ensuring all fields are filled. The form currently has an action controller called register.php, but also includes action="javascript:void(0);" in the HTML form. What ...

Contrasting the act of declaring and initializing variables

As someone who is new to C# and programming in general, I have been thinking about the difference between declaring and initializing variables. A good example of my confusion is with the String.Split() method. The documentation states that it returns an ar ...

How can one initialize and assign values to a class's variables using JSON data?

In my current project, I am working on a game where I need to deserialize JSON data into a class and then populate a table in the UI with the retrieved information. The class structure looks like this: using System; [Serializable] public class Table { ...

What seems to be the issue with the useState hook in my React application - is it not functioning as

Currently, I am engrossed in a project where I am crafting a Select component using a newfound design pattern. The execution looks flawless, but there seems to be an issue as the useState function doesn't seem to be functioning properly. As a newcomer ...

Pattern matching using regex can also be used to restrict the number of characters allowed

Having some trouble with regex to match a specific pattern and also limit the number of characters: Let's say I have allowed number prefixes: 2, 31, 32, 35, 37, 38, 39, 41, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60 I only want numb ...

How to achieve the wrapping functionality in ReactJS that is similar to

Is there a ReactJS equivalent to jQuery's wrap method? I want to wrap menuContents with the following element: <ul className="nav nav-pills nav-stacked"></ul> The contents of menuContents are generated like this: let menuContents = thi ...

adjusting the color of ion-button when hovering over the cancel button

I'm working on a button bar for my app and I want the color of the button to change based on its state (false, true). Currently, the button starts out green, turns light green when hovered over, and becomes white when clicked. Once I click it, the bu ...

Learn how to display a "not found" message in a React.js application

I have a piece of code where I am sending a post request to an API and retrieving all the data from the API in a table. I am trying to find currency data based on the currency name, if found I display the data in a div, if not found I want to print "not ...

"Can you guide me on how to display a React component in a

I have a function that loops through some promises and updates the state like this: }).then((future_data) => { this.setState({future_data: future_data}); console.log(this.state.future_data, 'tsf'); }); This outputs an array o ...

A recursive function that utilizes a for loop is implemented

I am encountering a critical issue with a recursive function. Here is the code snippet of my recursive function: iterateJson(data, jsonData, returnedSelf) { var obj = { "name": data.groupName, "size": 4350, "type": data.groupType }; if ...

Press on the menu <li> item to create additional submenus

A group of friends is facing a challenge. They want to create a dropdown sub-menu that appears directly below the selected item when clicking on a link from a menu. So far, they have been able to use ajax to send requests and generate a sub-menu. However, ...

Guide on retrieving the value of "form" from a select using jQuery in a Ruby on Rails application

I am struggling to figure out how to use jQuery to pass the value of the form attribute from the select tag. I have been trying different ways, but so far haven't been successful. When using simple_form_for, the input statement looks like this: < ...

What could be the root cause behind the error encountered while trying to authenticate a JWT?

I've been working on integrating a Google OAuth login feature. Once the user successfully logs in with their Google account, a JWT token is sent to this endpoint on my Express server, where it is then decoded using jsonwebtoken: app.post('/login/ ...

JavaScript refuses to execute

I am facing an issue with a static page that I am using. The page consists of HTML, CSS, and JavaScript files. I came across this design on a website (http://codepen.io/eode9/pen/wyaDr) and decided to replicate it by merging the files into one HTML page. H ...

EMFILE error encountered while attempting to initialize a new react-native project and watch file changes

Looking to start a new react-native project? Here are the steps: Begin with react-native init testproject then run react-native run-ios Encountering an error while watching files for changes: EMFILE {"code":"EMFILE","errno":"EMFILE","syscall":"Error watc ...

Making a standard AJAX request using jQuery without including the XHR header

I am looking to make an ajax-type request using the following headers (or something similar): GET example.com/ajaxapi/article/1 HTTP/1.1 Host: localhost Accept: application/hal+json Cache-Control: no-cache The key aspect here is to accomplish this withou ...

Guide on using JSZip and VUE to handle an array of promises and store them in a local variable

My lack of experience with async functions has me feeling a bit lost right now... I'm attempting to loop through files in a folder within a zip file using JSZip, store these files in an array, sort them, and then save them to a local variable for furt ...

Enable JavaScript in Webdriver Selenium to enhance the functionality of your web

I am facing an issue with my Java program and Selenium WebDriver. The script I have does not detect the button "Open device access" because its style is set to "display: none". Usually, clicking on "Device Access" triggers JavaScript to display the "Open ...

Unable to access the newly created object's properties following the instantiation of a new resource in AngularJS

Currently, I am in the process of developing a new Resource utilizing AngularJS that falls under the category of Person. After successfully creating this resource, my goal is to retrieve the id associated with the new resource from the server. it('sh ...