'how to calculate border width to scale Image Canvas FabricJS

how to calculate border width to scale Image Canvas FabricJS

The image is smaller but the border size is not smaller.

enter image description here

enter image description here

I want the border scale to be the same all the time. The image is smaller but the border size is not smaller.

index.html

<!DOCTYPE html>                    
<head>
<title>Custom T-Shirts - Design</title>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
      <script src="js/jquery.min.js" type="text/javascript"></script>  
      <script src="js/fabric.js" type="text/javascript"></script>     
      <script src="js/customiseControls.min.js"></script>
      <style>
     

        button.accordion-button:focus {
          box-shadow: 0 0 0 0rem transparent!important;
          border-color: transparent!important;
         }

         #ColorpanelDesign {
           float: left;
         }
         .bg-sub {
          background-color: var(--sub)!important;
         }
         .text-sub {
           color: var(--color-sub)!important;
         }
         .accordion-body {
          border: 1px solid var(--sub)!important;
          border-top: 0px;
          width: 100%;
         }
         .designColorBox {
          display: inline-block;
          border: 1px solid #ccc;
          padding: 3px;
          margin-right: 10px;
         }
         .designColor {
           border: 1px solid #ccc;
           width: 30px;
           height: 30px;
         }

         .design-border {
             z-index: 0;
            background-color: grey;position: absolute;
           }
         .canvas-container {
           margin: 0px auto;
         }
         #wrapper {
           position:relative;
          }
          #wrapper > canvas {
            position:absolute;
            left:0;
            top:0;
          }
      </style>
      
</head>                  

<body>
    
    
    <div class="container">
      <div class="row justify-content-center">
        <div class="col-md-12 col-lg-8" style="touch-action: none;padding: 0px;">
          <div id="wrapper">
            <!-- <div class="canvas-container" id="stack"> -->
              <!-- <canvas id="bounded" style="z-index: 1;"></canvas> -->
              <canvas class="lower-canvas" id="mainscreen"  style=" z-index: 0;"></canvas>


              
            <!-- </div> -->
             <div class="design-border  designBox1" style="width: 120px; height: 2px; top: 70px; left: 75px;"></div>
              <div class="design-border designBox2" style="width: 2px;height: 160px;top: 70px;left: 75px;"></div>
              <div class="design-border designBox3" style="width: 2px;height: 160px;top: 70px;left: 195px;"></div>
              <div class="design-border designBox4" style="text-align: center;color: white; width: 120px;height: 20px;top: 210px;left: 75px;font-size: 14px;">Desgin Box</div>
          </div>
        </div>
        <div class="col-12 col-md-12 col-lg-4" style="padding: 0px;">
          <div class="p-2">
            <div class="accordion accordion-flush" id="accordionFlushExample">
              <div class="accordion-item">
                <h2 class="accordion-header" id="flush-headingOne">
                  <button class="accordion-button bg-sub text-sub" type="button" data-bs-toggle="collapse" data-bs-target="#flush-collapseOne" aria-expanded="true" aria-controls="flush-collapseOne">
                    TYPE
                  </button>
                </h2>
                <div id="flush-collapseOne" class="accordion-collapse collapse show" aria-labelledby="flush-headingOne" data-bs-parent="#accordionFlushExample">
                  <div class="accordion-body" id="TypepanelDesign">
                  </div>
                </div>
              </div>
              <div class="accordion-item">
                <h2 class="accordion-header" id="flush-headingTwo">
                  <button class="accordion-button bg-sub text-sub" type="button" data-bs-toggle="collapse" data-bs-target="#flush-collapseTwo" aria-expanded="true" aria-controls="flush-collapseTwo">
                    COLOR
                  </button>
                </h2>
                <div id="flush-collapseTwo" class="accordion-collapse collapse show" aria-labelledby="flush-headingTwo" data-bs-parent="#accordionFlushExample">
                  <div class="accordion-body" id="ColorpanelDesign">
                  </div>
                </div>
              </div>
              
            </div>
          </div>

        </div>
      </div>
    
         
    </div>
  
    <script src="js/fabric.design.js"></script>  
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>

</body> 
    
</html>

fabric.design.js

let dataServer = {
  color: [
    "#fff",
    "#000",
  ]
}
let setDesign = [];
let sizeWidth = document.getElementById("wrapper").offsetWidth
let CvWidth = 540
let CvHeight = 600

let imgWidth = 1
let imgHeight = 1
$(function() {
    
    setDesign["width"] = 200;
    setDesign["height"] = 230;
    setDesign["top"] =  180;
    setDesign["left"] = (sizeWidth / 2) - (setDesign["width"] / 2 + 0); //3 ปรับความเอียง ยิ่งมากยิ่งไปทางซ่าย
  

    let ColorData = dataServer.color
    canvas = new fabric.Canvas('mainscreen', { preserveObjectStacking: true })
    canvas.setHeight(CvHeight)
    canvas.setWidth(CvWidth)
    
    if(screen.width <= CvWidth) {
      canvas.setWidth(screen.width )
      canvas.setHeight(screen.width  * 1.1112)
      // canvas.overlayImage.scaleToWidth(screen.width )
    }

    window.addEventListener('resize', function(event){
      if(event.target.outerWidth <= CvWidth) {
        canvas.setWidth(event.target.outerWidth)
        canvas.setHeight(event.target.outerWidth * 1.1112)
        canvas.overlayImage.scaleToWidth(event.target.outerWidth)
      }else{
        canvas.setHeight(CvHeight)
        canvas.setWidth(CvWidth)
        canvas.overlayImage.scaleToWidth(CvWidth)
        
      }

    });

   
    

    for (let i = 0; i < ColorData.length; i++) {
      const element = document.createElement("div")
      element.className = 'designColor'
      element.style["background-color"] = ColorData[i]
      element.setAttribute('color', ColorData[i]);
      element.setAttribute("onclick", "changeColor_Pic('"+ColorData[i]+"')");


      const element_box = document.createElement("div")
      element_box.className = 'designColorBox'
      element_box.appendChild(element)

      document.getElementById("ColorpanelDesign").appendChild(element_box)

      // canvas._objects.map(x => console.log(x))
      
        canvas.setOverlayImage('image/product/front-shirt.png', function() {
          canvas.overlayImage.backgroundColor = dataServer.color[1]
          // console.log(screen.width);
          let width = CvWidth;
          if(screen.width <= width) {
            width = screen.width
          }
            canvas.overlayImage.scaleToWidth(width)
      
           $('.designBox1').css({"width": setDesign["width"]+"px", "height": "2px","top": setDesign["top"]+"px","left": setDesign["left"]+"px"});
           $('.designBox2').css({"width": "2px", "height": setDesign["height"]+"px","top": (setDesign["top"]+2)+"px","left": setDesign["left"]+"px"});
           $('.designBox3').css({"width": "2px", "height": setDesign["height"]+"px","top": (setDesign["top"]+2)+"px","left": (setDesign["left"]+setDesign["width"]-2)+"px"});
           $('.designBox4').css({"width": setDesign["width"]+"px", "height": "20px","top": (setDesign["top"]+setDesign["height"]+2)+"px","left": setDesign["left"]+"px"});
   
            canvas.renderAll()
        })
      // console.log();

      // $('.designBox1').css({"width": setDesign["width"]+"px", "height": "2px","top": setDesign["top"]+"px","left": setDesign["left"]+"px"});
      // $('.designBox2').css({"width": "2px", "height": setDesign["height"]+"px","top": (setDesign["top"]+2)+"px","left": setDesign["left"]+"px"});
      // $('.designBox3').css({"width": "2px", "height": setDesign["height"]+"px","top": (setDesign["top"]+2)+"px","left": (setDesign["left"]+setDesign["width"]-2)+"px"});
      // $('.designBox4').css({"width": setDesign["width"]+"px", "height": "20px","top": (setDesign["top"]+setDesign["height"]+2)+"px","left": setDesign["left"]+"px"});
   }




});
function changeColor_Pic(color,canvasA = canvas) {
  canvasA.setOverlayImage('image/product/front-shirt.png', function() {
    canvasA.overlayImage.backgroundColor = color
    canvasA.renderAll()
  })
  // console.log(color);
}

Thank you



Solution 1:[1]

The property you're looking for is called strokeUniform. You can use it like this to make a specific image have a constant border size that's independent of scale:

image.set('strokeUniform', true)

You can also change the default setting for all images like this:

fabric.Image.prototype.strokeUniform = true

Or for all types of objects like this:

fabric.Object.prototype.strokeUniform = true

See http://fabricjs.com/docs/fabric.Object.html#strokeUniform

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 melchiar