<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ase Princewill Clifford</title>
    <description>The latest articles on DEV Community by Ase Princewill Clifford (@apcliff).</description>
    <link>https://dev.to/apcliff</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F613018%2F39db8d05-4cf3-42c5-80cf-ae74553f7afe.png</url>
      <title>DEV Community: Ase Princewill Clifford</title>
      <link>https://dev.to/apcliff</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/apcliff"/>
    <language>en</language>
    <item>
      <title>3D Tshirt Configurator With Three.js and Fabric.js</title>
      <dc:creator>Ase Princewill Clifford</dc:creator>
      <pubDate>Sun, 09 Jun 2024 16:13:10 +0000</pubDate>
      <link>https://dev.to/apcliff/3d-tshirt-configurator-with-threejs-and-fabricjs-31j9</link>
      <guid>https://dev.to/apcliff/3d-tshirt-configurator-with-threejs-and-fabricjs-31j9</guid>
      <description>&lt;p&gt;Hello Dev Community,&lt;/p&gt;

&lt;p&gt;I'm a non-code developer working on a pet project to create a 3D T-shirt configurator that allows users to customize a T-shirt model in real-time. The goal is to let users add text, images, and colors to a 3D T-shirt model, manipulate these elements, and interact with the 3D model itself. My target audience is primarily mobile users, so responsiveness and ease of use on smaller screens are critical.&lt;/p&gt;

&lt;p&gt;Current Implementation&lt;/p&gt;

&lt;p&gt;I've been using Three.js for rendering the 3D model and Fabric.js for 2D canvas interactions. However, I've encountered several issues that I haven't been able to resolve. Here’s what I have so far:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Loading the 3D Model: Successfully loading and displaying the 3D T-shirt model.&lt;/li&gt;
&lt;li&gt;Fabric.js Canvas: Overlaid on top of the 3D model to add and manipulate text and images.&lt;/li&gt;
&lt;li&gt;Basic Controls: Buttons for adding text and images, changing colors, rotating the model, and moving the model.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Issues I'm Facing&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Interaction with Added Elements: Users cannot edit, resize, or move added text and images around the 3D model.&lt;/li&gt;
&lt;li&gt;Toolbar Usability: The toolbar is not user-friendly on mobile devices.&lt;/li&gt;
&lt;li&gt;Model Positioning: The 3D model is not centered correctly and often appears misplaced.&lt;/li&gt;
&lt;li&gt;Element Manipulation: Added elements (text, images) are not properly aligned with the 3D model and sometimes cover the entire model instead of specific areas.&lt;/li&gt;
&lt;li&gt;Responsiveness: The overall configurator lacks responsiveness for mobile devices.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Requirements&lt;/p&gt;

&lt;p&gt;I need help with the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Interactivity: Ensuring that users can interact with added elements (text, images) on the 3D model—move, resize, change colors, and edit text in real-time.&lt;/li&gt;
&lt;li&gt;Mobile-Friendly Toolbar: Making the toolbar responsive and user-friendly for mobile devices, possibly with gesture controls.&lt;/li&gt;
&lt;li&gt;Correct Model Centering: Ensuring the 3D model is centered and properly scaled on load.&lt;/li&gt;
&lt;li&gt;Accurate Element Placement: Properly mapping text and images to specific areas of the 3D model without them covering the entire model.&lt;/li&gt;
&lt;li&gt;Overall Responsiveness: Making sure the configurator is fully responsive and functional across different screen sizes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sample Code&lt;/p&gt;

&lt;p&gt;Here is the current version of my code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;html
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;meta charset="UTF-8"&amp;gt;
  &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&amp;gt;
  &amp;lt;title&amp;gt;3D T-shirt Configurator&amp;lt;/title&amp;gt;
  &amp;lt;style&amp;gt;
    body { margin: 0; }
    #container { display: flex; flex-direction: column; height: 100vh; }
    #3d-view { flex: 1; }
    #toolbar { position: fixed; bottom: 0; width: 100%; background-color: #eee; display: flex; justify-content: center; padding: 10px; }
    canvas { display: block; }
  &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;div id="container"&amp;gt;
    &amp;lt;div id="3d-view"&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;div id="toolbar"&amp;gt;
      &amp;lt;!-- Toolbar buttons here --&amp;gt;
      &amp;lt;input type="file" id="uploadTexture" /&amp;gt;
      &amp;lt;input type="color" id="colorPicker" /&amp;gt;
      &amp;lt;button id="addText"&amp;gt;Add Text&amp;lt;/button&amp;gt;
      &amp;lt;button id="moveUp"&amp;gt;Up&amp;lt;/button&amp;gt;
      &amp;lt;button id="moveDown"&amp;gt;Down&amp;lt;/button&amp;gt;
      &amp;lt;button id="moveLeft"&amp;gt;Left&amp;lt;/button&amp;gt;
      &amp;lt;button id="moveRight"&amp;gt;Right&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;script src="https://cdn.jsdelivr.net/npm/three@0.138.3/build/three.min.js"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;script src="https://cdn.jsdelivr.net/npm/three@0.138.3/examples/js/loaders/GLTFLoader.min.js"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;script src="https://cdn.jsdelivr.net/npm/fabric@4.5.0/dist/fabric.min.js"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;script&amp;gt;
    let scene, camera, renderer, model, fabricCanvas;

    function initThreeJS() {
      const container = document.getElementById('3d-view');
      scene = new THREE.Scene();
      camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
      renderer = new THREE.WebGLRenderer({ antialias: true });
      renderer.setSize(window.innerWidth, window.innerHeight * 0.8);
      container.appendChild(renderer.domElement);

      const light = new THREE.AmbientLight(0xffffff, 1);
      scene.add(light);

      const loader = new THREE.GLTFLoader();
      loader.load('path/to/your/model.gltf', function(gltf) {
        model = gltf.scene;
        scene.add(model);
        camera.position.z = 3;
      });

      const controls = new THREE.OrbitControls(camera, renderer.domElement);
      controls.enableZoom = true;
      controls.enableRotate = true;
      controls.enablePan = false;

      animate();
    }

    function initFabricJS() {
      fabricCanvas = new fabric.Canvas('fabricCanvas', {
        width: window.innerWidth,
        height: window.innerHeight * 0.2,
        backgroundColor: 'transparent',
      });

      fabricCanvas.on('object:modified', generateTexture);
      fabricCanvas.on('object:added', generateTexture);
    }

    function generateTexture() {
      fabricCanvas.renderAll();
      fabricCanvas.getElement().toBlob(function(blob) {
        const texture = new THREE.TextureLoader().load(URL.createObjectURL(blob));
        texture.flipY = false;
        model.traverse(function(child) {
          if (child.isMesh) {
            child.material.map = texture;
            child.material.needsUpdate = true;
          }
        });
      });
    }

    document.getElementById('addText').addEventListener('click', function() {
      const text = new fabric.Text('Sample Text', { left: 100, top: 100, fill: 'black', fontSize: 24 });
      fabricCanvas.add(text);
    });

    document.getElementById('uploadTexture').addEventListener('change', function(event) {
      const file = event.target.files[0];
      const reader = new FileReader();
      reader.onload = function(e) {
        fabric.Image.fromURL(e.target.result, function(img) {
          img.scaleToWidth(200);
          fabricCanvas.add(img);
        });
      };
      reader.readAsDataURL(file);
    });

    document.getElementById('colorPicker').addEventListener('input', function(event) {
      const activeObject = fabricCanvas.getActiveObject();
      if (activeObject) {
        activeObject.set({ fill: event.target.value });
        fabricCanvas.renderAll();
        generateTexture();
      }
    });

    document.getElementById('moveUp').addEventListener('click', function() {
      model.position.y += 0.1;
    });

    document.getElementById('moveDown').addEventListener('click', function() {
      model.position.y -= 0.1;
    });

    document.getElementById('moveLeft').addEventListener('click', function() {
      model.position.x -= 0.1;
    });

    document.getElementById('moveRight').addEventListener('click', function() {
      model.position.x += 0.1;
    });

    window.addEventListener('resize', function() {
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
      renderer.setSize(window.innerWidth, window.innerHeight * 0.8);
    });

    initThreeJS();
    initFabricJS();
  &amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Features Needed&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Editable Text: Users should be able to add, edit, resize, and move text around the 3D model.&lt;/li&gt;
&lt;li&gt;Image Manipulation: Users should be able to upload images, resize, move, and apply them to specific areas of the 3D model.&lt;/li&gt;
&lt;li&gt;Color Customization: Users should be able to change the color of the text and images applied to the 3D model.&lt;/li&gt;
&lt;li&gt;Model Controls: Users should be able to move, rotate, and zoom in/out the 3D model.&lt;/li&gt;
&lt;li&gt;Mobile Responsiveness: The entire configurator should be optimized for mobile use, with easy-to-use controls and a responsive design.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Request for Help&lt;/p&gt;

&lt;p&gt;I would appreciate any guidance, code snippets, or resources that could help me achieve the desired functionality. Specifically, I'm looking for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Improved User Interactivity: How can I enable users to interact with added elements (text, images) directly on the 3D model?&lt;/li&gt;
&lt;li&gt;Mobile Optimization: Tips or best practices for making the toolbar and overall interface more mobile-friendly.&lt;/li&gt;
&lt;li&gt;Accurate Texture Mapping: How can I ensure that the added text and images are correctly mapped to specific areas of the 3D model?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thank you for taking the time to read this. Any help or pointers would be greatly appreciated!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Browzwear API to Azure</title>
      <dc:creator>Ase Princewill Clifford</dc:creator>
      <pubDate>Tue, 28 Nov 2023 18:00:11 +0000</pubDate>
      <link>https://dev.to/apcliff/browzwear-api-to-azure-1a6i</link>
      <guid>https://dev.to/apcliff/browzwear-api-to-azure-1a6i</guid>
      <description>&lt;p&gt;I need help on hosting Browzwear Python API on Azure and then generate SDK/API in JavaScript on Azure. &lt;/p&gt;

&lt;p&gt;I want to use the Browzwear Python API on bubble.io&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
