Leverage the power of Fabric.js canvas to enhance the texture of your Three.js 3D

Recently, I started learning threejs and decided to create a t-shirt configurator using fabric js. My aim is to allow users to upload an image to the canvas (cnvs) which will be applied to the gltf model of a t-shirt. However, I am facing an issue where the texture doesn't display. Below is the code snippet:

var canvas2 = new fabric.Canvas('cnvs', {
backgroundColor: 'red'
});
fabric.Image.fromURL('eo.png', function(myImg) {
// Create an extra var to modify some image properties
var img1 = myImg.set({ left: 0, top: 0 ,width:150,height:150});
canvas2.add(img1); 
canvas2.renderAll();
});

var canvasTexture = new THREE.CanvasTexture(canvas2);
canvasTexture.wrapS = THREE.RepeatWrapping;
canvasTexture.wrapT = THREE.RepeatWrapping;

const gltfLoader2 = new GLTFLoader();
gltfLoader2.load('tshirt2.gltf', (gltf2) => {
model = gltf2.scene;
model.traverse(child => {
 console.log(child.material);
if (child.material && child.material.name === 'Pattern2D_13095') {
// Pattern2D_13095
child.material.map = new TextureLoader().load(  new THREE.MeshStandardMaterial({
  map: canvasTexture,
  
}));
}
});
canvas2.on("after:render", function() {
model.material.map.needsUpdate = true;
});

canvas2.on('mouse:down',function(event){
if(canvas2.getActiveObject()){
 alert(event.target);
 }

})


scene.add(model);
model.rotation.x = 1.5;
model.position.y=310;
model.position.x=-300;
model.position.z=-100;
model.scale.set(1000,1000,1000);
});


});


function resizeRendererToDisplaySize(renderer) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}






function render() {

if (resizeRendererToDisplaySize(renderer)) {
const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}

renderer.render(scene, camera);

requestAnimationFrame(render);
}





function animate(){
requestAnimationFrame(animate);
cloudParticles.forEach(p => {
    p.rotation.z -= 0.001;
 
   
 });


root.rotation.z -= 0.01;

renderer.render(scene, camera);  
model.material.needsUpdate = true;


}
animate();

Lights/Camera:

 let cloudParticles = [];
let root;
let model;
const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1, 
1000 );
camera.position.z = 2;
camera.rotation.x = 1.16;
camera.rotation.y = -0.12;
camera.rotation.z = 0;
const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({canvas});
scene.fog = new THREE.FogExp2(0x11111f, 0.002);
renderer.setClearColor(scene.fog.color);
renderer.setSize(window.innerWidth, window.innerHeight);


document.body.appendChild( renderer.domElement );

let directionalLight = new THREE.DirectionalLight(0xff8c19);
directionalLight.position.set(0,0,1);
scene.add(directionalLight);
let orangeLight = new THREE.PointLight(0xcc6600,50,450,1.7);
orangeLight.position.set(200,300,100);
scene.add(orangeLight);
let redLight = new THREE.PointLight(0xd8547e,50,450,1.7);
redLight.position.set(100,300,100);
scene.add(redLight);
let blueLight = new THREE.PointLight(0x3677ac,50,450,1.7);
blueLight.position.set(300,300,200);
scene.add(blueLight);

let directionalLight2 = new THREE.DirectionalLight(0xffffff);
directionalLight2.position.set(-110,-110,-120);
scene.add(directionalLight2);

HTML:

<div class="cnvscon">
<canvas id="cnvs" height="256" width="256" ></canvas></div>       
<canvas id="c"></canvas>

Check out the resulting image here (the mesh appears black): result gltfviewer

Answer №1

child.texture = new Loader().load( new THREE.Material({ texture: imageTexture }));

There is a mistake in this code snippet. The correct way to assign the imageTexture to the texture property is:

child.texture = imageTexture;

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

Error: React 404 - Unable to make a POST request with

I am new to utilizing Axios and Node.js as a backend technology. I recently inherited some React code for a login page and I'm struggling to understand why I'm unable to send a POST request to the backend. Below is my .env file: REACT_APP_BACKEN ...

I need help using i18N to translate the SELECT option in my VUE3 project. Can someone guide me

<n-select v-model:value="value" :options="options" /> options: [ { label: "Every Person", value: 'file', }, { label: 'Drive My Vehicle', ...

Standardize date formatting in AngularJS

Retrieve the date in the shared format: {{ dateValue | date:{{dateFormat}} }} The following service is provided: app.service('formatting', function() { var format = new Object(); format.dateFormat = 'medium' var ...

Opening multiple dialogs in Jquery Dialog box

I have several images displayed on a single page. When each image is clicked, I want a dialog box to open. I currently have 6 instances of this setup in my HTML. However, when I click on an image, all 6 dialogs pop up with the same information as the first ...

Obtain the elements within a rectangular region of a webpage

Exploring how to identify a specific subset of DOM elements within a webpage that fall within the boundaries of a defined rectangle, given two points as reference. Currently developing a web gallery where each photo is enclosed within an li tag. Planning ...

The 'string' Type in Typescript cannot be assigned to the specified type

Within the fruit.ts file, I've defined a custom type called Fruit which includes options like "Orange", "Apple", and "Banana" export type Fruit = "Orange" | "Apple" | "Banana" Now, in another TypeScript file, I am importing fruit.ts and trying to as ...

Troubleshooting Issues with Form Inputs in JS/Angular Using Places API and document.getElementById Method

I have integrated the Google Places API to automatically populate locations/destinations into a form after a user searches. The auto-population works correctly, but I am facing an issue when trying to submit the form into my database – the object is alwa ...

Designing a fixed bottom footer enclosed within a wrapper that expands from the top header to the bottom footer

I have created the basic structure of my webpage using HTML / CSS. However, I now realize that I need a sticky footer that remains at the bottom of the screen with a fixed position. Additionally, I want the main content area, known as the "wrapper," to str ...

I am implementing a new method in the prototype string, but I am uncertain about its purpose

I am trying to wrap my head around the concept here. It seems like the phrase will pass a part of an array, in this case eve, to the phrase.palindrome method. This method will then process it. First, the var len takes the length of eve and subtracts 1 from ...

Instructions for adding an onfocus event listener to an input field in order to dynamically change the formatting of associated labels

I'm looking to change the style of my input labels to a more fancy look by implementing the .fancyclass style when using the onfocus event on the input field. I am curious to know how this can be achieved through event listeners in Javascript? ...

Oops! The function 'ModalDemoCtrl' has not been defined, causing an error

Hey there, I'm encountering an error when using angularJS in my project. The project is built on the django framework and does not include any additional JS files. Here are some snippets of my code: JavaScript: {{ ngapp }}.controller("ModalDemoCtrl" ...

Take action once all deferred operations have been successfully completed

Below is the code snippet I am working with: loadOpportunities: function () { return $.getJSON("/Opportunity/GetAll").pipe(function (result) { //do stuff }); }, loadTypes: function () { return $.getJSON("/OpportunityTypes/GetAll", nul ...

What is the best way to combine an array of objects into a single object in typescript?

Looking for some help with converting an array of objects into a single object using TypeScript. Here's the structure of the array: myArray = [ {itemOneKey: 'itemOneValue', itemTwoKey: 'itemTwoValue'}, {itemThreeKey: ' ...

Attempting to send a GET request from localhost:8080 to localhost:3000 is proving to be a challenge as I keep encountering a CORS error. Even after trying to install CORS on my node.js server, the issue

While attempting to send an axios GET request from my front-end app on localhost:8080 to my Node.js/Express.js server on localhost:3000, I encountered a CORS error. Despite installing the cors npm package and using it as middleware in my Node.js/Express.js ...

Creating JEST unit tests for a basic functionality

Here is the React code I have written: getDetails: function () { var apiUrl = ConfigStore.get('api') request .get(apiUrl) .set('X-Auth-Token', AuthStore.jwt) .set('Accept&apo ...

"Troubleshooting the issue of Delete Requests failing to persist in Node.js

Whenever I send a delete request to my node.js server, it can only delete one item from my JSON file until the server restarts. If I attempt to make a second delete request, it successfully deletes the item but also reverts the deletion of the last item. ...

Can you explain the concept of a TransientTransactionError within Mongoose (or MongoDB)?

Two important files in my project are server.js and db.js. The db.js file is responsible for interacting with the database using Mongoose, while server.js calls functions from db.js: var mongoose = require('mongoose'); mongoose.connect('&ap ...

Determining the total of input values based on identification number

Can anyone help me figure out how to calculate the total sum of the values entered using IDs? I've been struggling with it and can't seem to get it to work. Your assistance would be greatly appreciated. <input type="number" id=&quo ...

What could be causing the service method in the controller not to be called by Node JS?

In my current Node JS project, the folder structure of my app is as follows: src │ index.js # Main entry point for application └───config # Contains application environment variables and secrets └───controllers # Hou ...