Resizing rectangle based on user input

Viewed 110

I am trying to resize a rectangle based on the user input, but i get an error saying: Cannot read property 'addEventListener' of null. Do i need to change something in the HTML? I tried moving the script below the body but it didn't work. Seems like everything is alright but it doesn't work.

https://jsfiddle.net/sbLk9zvd/2/


var rect = new fabric.Rect({
  fill: "red",
  width: 300,
  height: 400,
  stroke: "gray",
  strokeWidth: 30,
  fill: "lightgray",
  centeredRotation: true,
  centeredScaling: true,
});

canvas.add(rect);


var Length = document.getElementById("Length");
var Width = document.getElementById("Width");

Length.addEventListener("input", Modify_Length);
Width.addEventListener("input", Modify_Width);

function Modify_Length() {
  var rect = new fabric.Rect({
    fill: "red",
    width: parseFloat(Width.value) || 300,
    height: 400 || parseFloat(Length.value),
    stroke: "gray",
    strokeWidth: 30,
    fill: "lightgray",
    centeredRotation: true,
    centeredScaling: true,
  });
}
function Modify_Width() {
  var rect = new fabric.Rect({
    fill: "red",
    width: parseFloat(Width.value) || 300,
    height: parseFloat(Length.value) || 400,
    stroke: "gray",
    strokeWidth: 30,
    fill: "lightgray",
    centeredRotation: true,
    centeredScaling: true,
  });
}
canvas.renderAll();
1 Answers

There is no need for a separate listener for each element. Just share a single callback function. Also, don't forget to rerender.

const canvas = new fabric.Canvas("c");

const rect = new fabric.Rect({
  fill: "red",
  width: 200,
  height: 80,
  stroke: "gray",
  strokeWidth: 1,
  fill: "lightgray",
  centeredRotation: true,
  centeredScaling: true,
});

canvas.on("object:scaling", function() {
  var obj = canvas.getActiveObject(),
    width = obj.width,
    height = obj.height,
    scaleX = obj.scaleX,
    scaleY = obj.scaleY;

  obj.set({
    width: width * scaleX,
    height: height * scaleY,
    scaleX: 1,
    scaleY: 1,
  });
});

rect.setControlsVisibility({
  mt: false,
  mb: false,
  ml: false,
  mr: false,
  bl: false,
  br: false,
  tl: false,
  tr: false,
  mtr: false,
});

canvas.add(rect);

canvas.centerObject(rect);
canvas.setActiveObject(rect);

canvas.item(0).lockMovementX = true;
canvas.item(0).lockMovementY = true;

const width = document.getElementById('width');
const height = document.getElementById('height');

const adjust = (e) => {
  Object.assign(rect, {
    width: parseFloat(width.value) || 300,
    height: parseFloat(height.value) || 400,
  });
  canvas.renderAll();
};

width.addEventListener('input', adjust);
height.addEventListener('input', adjust);

canvas.renderAll();
label, input {
  display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/451/fabric.min.js"></script>
<canvas id="c" width="250" height="120"></canvas>
<div id="user-input">
  <label for="width">Width:</label>
  <input type="number" id="width" name="width" value="200" />
  <label for="height">Height:</label>
  <input type="number" id="height" name="height" value="80" />
</div>

Related