Search code examples
javascriptthree.jshtml5-canvasfabricjsbabylonjs

How can i preview 2D flat objects in 3D using babylonjs or threejs?


I am using fabricJS and have few random drawings (e.g circle, square, polygon shape) on plane canvas sized rectangle object (Base).

I want to preview all these drawings engraved on main rectangle object in 3D.

Is their any library available for this? i google a bit and found three.js and Babylon.js but of them have no examples available similar to my requirement, even i don't know if this is possible with these libraries or not.

2D drawing i did on canvas

Now want to convert it in 3D preview using JS library in browser.

after drawing i want to preview my canvas drawings like this

Please guide me.


Solution

  • I think instead of BabylonJs, you should got for Three.JS its more easy to handle and small it size as well.

    Here is an example code maybe you are looking similar to this.

    All you have to do is extract SVG from your FabricJS put it in ThreeJS.

    // --- Init threejs scene
    // ----------------------
    
    const scene = new THREE.Scene();
    
    const ratio = window.innerWidth / window.innerHeight;
    const renderer = new THREE.WebGLRenderer({ antialias: true });
    
    renderer.setSize(window.innerWidth, window.innerHeight);
    
    const camera = new THREE.PerspectiveCamera(100, ratio, 0.01, 1000);
    camera.position.z = 300;
    
    document.querySelector("body").appendChild(renderer.domElement);
    
    // Resize and update camera
    window.addEventListener('resize', function(e) {
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
    
      renderer.setSize(window.innerWidth, window.innerHeight);
    });
    
    // Axes helper
    const axesHelper = new THREE.AxesHelper(500);
    scene.add(axesHelper);
    
    
    
    // --- Main part, load and parse SVG
    // ---------------------------------
    
    const svgMarkup = document.querySelector('svg').outerHTML;
    
    // SVG Loader is not a part of the main three.js bundle 
    // We need to load it separately, it is included in this pen's Settings > JavaScript
    // https://threejs.org/docs/#examples/en/loaders/SVGLoader
    const loader = new THREE.SVGLoader();
    const svgData = loader.parse(svgMarkup);
    
    // Group we'll use for all SVG paths
    const svgGroup = new THREE.Group();
    // When importing SVGs paths are inverted on Y axis
    // it happens in the process of mapping from 2d to 3d coordinate system
    svgGroup.scale.y *= -1;
    
    const material = new THREE.MeshNormalMaterial();
    
    // Loop through all of the parsed paths
    svgData.paths.forEach((path, i) => {
      const shapes = path.toShapes(true);
    
      // Each path has array of shapes
      shapes.forEach((shape, j) => {
        // Finally we can take each shape and extrude it
        const geometry = new THREE.ExtrudeGeometry(shape, {
          depth: 20,
          bevelEnabled: false
        });
    
        // Create a mesh and add it to the group
        const mesh = new THREE.Mesh(geometry, material);
    
        svgGroup.add(mesh);
      });
    });
    
    // Meshes we got are all relative to themselves
    // meaning they have position set to (0, 0, 0)
    // which makes centering them in the group easy
    
    // Get group's size
    const box = new THREE.Box3().setFromObject(svgGroup);
    const size = new THREE.Vector3();
    box.getSize(size);
    
    const yOffset = size.y / -2;
    const xOffset = size.x / -2;
    
    // Offset all of group's elements, to center them
    svgGroup.children.forEach(item => {
      item.position.x = xOffset;
      item.position.y = yOffset;
    });
    
    // Finally we add svg group to the scene
    scene.add(svgGroup);
    
    
    
    // --- Animation loop
    // ------------------
    
    function animate() {
      renderer.render(scene, camera);
    
      // Rotate out group 
      svgGroup.rotation.y += 0.005;
      
      requestAnimationFrame(animate);
    }
    
    animate();
    svg {
      display: none;
    }
    
    canvas {
      display: block;
    }
    
    a {
      font-family: Helvetica, Arial, sans-serif;
      font-size: 15px;
      padding: 10px 16px;
      display: block;
      position: fixed;
      bottom: 0;
      right: 0;
      color: #ddd;
      transition: all 0.25s;
    }
    
    a:hover {
      color: #3498db;  
    }
    <script src="https://unpkg.com/three@0.111.0/build/three.js"></script>
    <script src="https://unpkg.com/three@0.111.0/examples/js/loaders/SVGLoader.js"></script>
    
    
    <svg width="202px" height="202px" viewBox="0 0 202 202" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
          <path fill="none" d="M201,1 L201,201 L1,201 L1,1 L201,1 Z M53.27053,71 L37.6666667,71 L37.6666667,134.333333 L53.27053,134.333333 L53.27053,86.6038647 C59.2367133,86.879227 66.1207733,91.1014493 66.1207733,99.9130433 L66.1207733,134.333333 L80.4396133,134.333333 L80.4396133,99.9130433 C80.4396133,91.1014493 87.32367,86.879227 93.2898567,86.6038647 L93.2898567,134.333333 L110.63768,134.333333 L110.63768,86.6038647 C116.603863,86.879227 123.487923,91.1014493 123.487923,99.9130433 L123.487923,134.333333 L137.806763,134.333333 L137.806763,99.9130433 C137.806763,91.1014493 144.69082,86.879227 150.657003,86.6038647 L150.657003,134.333333 L166.26087,134.333333 L166.26087,71 L150.657003,71 C142.120773,71 133.859903,75.589372 130.647343,80.178744 C127.434783,75.589372 119.173913,71 110.63768,71 L93.2898567,71 C84.7536233,71 76.4927533,75.589372 73.2801933,80.178744 C70.0676333,75.589372 61.8067633,71 53.27053,71 Z" stroke="#979797"></path></svg>

    Example code