This is my code:
"use client"
import { useEffect, useRef } from 'react';
import * as THREE from 'three';
import * as fabric from 'fabric';
export default function Home() {
const fabricCanvasRef = useRef(null);
useEffect(() => {
/**
* Fabric.js Setup
*/
if (!fabricCanvasRef.current) {
// Initialize Fabric.js canvas
fabricCanvasRef.current = new fabric.Canvas('canvas', {
backgroundColor: '#FFBE9F',
});
const rectangle = new fabric.Rect({
top: 100,
left: 100,
fill: '#FF6E27',
width: 100,
height: 100,
transparentCorners: false,
centeredScaling: true,
borderColor: 'black',
cornerColor: 'black',
cornerStrokeColor: 'black',
});
fabricCanvasRef.current.add(rectangle);
// Adding image click functionality for images in the library
document.querySelectorAll('.library img').forEach(img => {
img.addEventListener('click', () => {
console.log('Image clicked:', img.src); // Logging for debugging
fabric.FabricImage.fromURL(img.src, (fabricImg) => {
console.log('Image loaded into Fabric canvas');
fabricCanvasRef.current.add(fabricImg); // Add the image to the Fabric canvas
fabricCanvasRef.current.renderAll(); // Re-render the canvas
});
});
});
}
/**
* Three.js Setup
*/
let camera, renderer, scene, cube, texture;
const container = document.getElementById('renderer');
const containerHeight = 512;
const containerWidth = 512;
function init() {
// Camera
camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 0.01, 100);
camera.position.set(0, 0, 3.5);
// Renderer
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(containerWidth, containerHeight);
container.appendChild(renderer.domElement);
// Scene
scene = new THREE.Scene();
scene.background = new THREE.Color(0x000000);
// Texture
texture = new THREE.Texture(document.getElementById('canvas'));
texture.anisotropy = renderer.capabilities.getMaxAnisotropy();
// Material
const material = new THREE.MeshBasicMaterial({ map: texture });
// Model
const geometry = new THREE.BoxGeometry(1, 1, 1);
cube = new THREE.Mesh(geometry, material);
scene.add(cube);
}
function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.004;
cube.rotation.y += 0.001;
texture.needsUpdate = true;
renderer.render(scene, camera);
}
init();
animate();
// Cleanup on component unmount
return () => {
if (fabricCanvasRef.current) {
fabricCanvasRef.current.dispose();
fabricCanvasRef.current = null;
}
container.removeChild(renderer.domElement);
};
}, []);
return (
<div className="container">
<div className="c-left">
<h3>Renderer</h3>
<div id="renderer"></div>
</div>
<div className="c-right">
<h3>Canvas</h3>
<canvas id="canvas" width="512" height="512"></canvas>
</div>
<div className='library'>
<img src='Virtualthreads.png' alt="Image 1"></img>
<img src='Untitled.png' alt="Image 2"></img>
</div>
<style jsx>{`
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
background: #FFF7F4;
}
.container {
display: flex;
width: 100%;
height: 100vh;
}
.c-left, .c-right {
width: 50%;
height: 100%;
}
.c-right {
float: right;
}
.library {
display: flex;
flex-direction: column;
width: 150px;
background: #eee;
}
.library img {
background: #eee;
margin-bottom: 10px;
cursor: pointer;
}
#renderer {
width: 512px;
height: 512px;
}
`}</style>
</div>
);
}
For some reason I am not able to add an image onto my fabric canvas, here there is a library of images displayed on the right(I used only two images for now) when ever I click on the image I want it to get displayed on my canvas but it isnt getting displayed.
My ultimate goal is to make a file picker which accepts images, as we pick the images they get added into the library and whenever we click on the specific image it will get displayed on the fabric canvas