Louis Hudson
Louis Hudson

Reputation: 35

How can I render circles around rectangle in Konva js?

I need to render table and chairs like in this picture:

enter image description here

I dont know how to calculate position of circles around rect. I tried some code, but its not working...Anybody knows how to solve it?

Check my code:

 let smallCircleRadius = 20
let tableSize = { 
    width: ((seats-4/2)*(smallCircleRadius)),
    height: ((seats-4/2)*(smallCircleRadius))
}
let controlY = 0
let totalCircleSide = (seats-4)/2
let controlX = 0
let distanceY = 0
let distanceX = 0
let table = new Konva.Rect({
    width: tableSize.width,
    height: tableSize.height,
    fill: '#fff',
    stroke: '#c3c6cf',//'#b2cfcf',
    strokeWidth: 8,
    x:150,
    y: 150
});
let count = 0

group.add(table)


for (var i = 0; i < seats; i++) {
    

    // let distanceToTable =  tableSize.width/2;
    // let x = i <= 2 ? table.x() + distanceToTable * i + (smallCircleRadius + 8) : count > totalCircleSide ? distanceToTable + distanceX+smallCircleRadius:  controlX
    // let y = i < 2 ? table.y() - distanceToTable/2: count > totalCircleSide ? controlY : distanceToTable + distanceY*smallCircleRadius

    //let x = table.x()
    //let y = table.y()
    group.add(new Konva.Circle({ radius: smallCircleRadius, fill: '#d2d6df', stroke: '#c3c6cf',strokeWidth: 3, x, y }));
    
   
}

Upvotes: 2

Views: 389

Answers (1)

Vanquished Wombat
Vanquished Wombat

Reputation: 9535

Make yourself a simple model that describes the position of the circles in simple relationship of circles to the table. Something like this can be extended via different models to accommodate other table layouts as the description of the layout is entirely in the model data.

const
  // Set up a canvas stage
  containerEle = document.getElementById('container'),
  stage = new Konva.Stage({
    container: "container",
    size: {
      width: containerEle.offsetWidth,
      height: containerEle.offsetHeight
    }
  }),

  layer = new Konva.Layer();

stage.add(layer);

const model = {
  table: {
    x: 100,
    y: 100,
    width: 200,
    height: 400,
    fill: 'black',
    stroke: 'silver',
    strokeWidth: 5
  },
  seat: {
    radius: 40,
    fill: 'white',
    stroke: 'silver',
    strokeWidth: 5,
    gap: 20
  },
  seats: [{
      name: "Seat 1",
      x: "25%",
      y: "-1r"
    },
    {
      name: "Seat 2",
      x: "75%",
      y: "-1r"
    },
    {
      name: "Seat 3",
      tableX: 1,
      tableY: 0,
      x: "1r",
      y: "16.6%"
    },
    {
      name: "Seat 4",
      tableX: 1,
      tableY: 0,
      x: "1r",
      y: "50%"
    },
    {
      name: "Seat 5",
      tableX: 1,
      tableY: 0,
      x: "1r",
      y: "83.3%"
    },
    {
      name: "Seat 6",
      tableX: 0,
      tableY: 1,
      x: "75%",
      y: "1r"
    },
    {
      name: "Seat 7",
      tableX: 0,
      tableY: 1,
      x: "25%",
      y: "1r"
    },
  ]
}

// make the table

const table = new Konva.Rect(model.table);

layer.add(table)

for (const seat of model.seats) {
  const seatShape = new Konva.Circle(model.seat);

  let tablePos = {
    x: seat.tableX && seat.tableX === 1 ? model.table.x + model.table.width : model.table.x,
    y: seat.tableY && seat.tableY === 1 ? model.table.y + model.table.height : model.table.y
  }

  let position = {
    x: tablePos.x + getPosComponent(seat.x, model.seat.radius, model.table.width, model.seat.gap),
    y: tablePos.y + getPosComponent(seat.y, model.seat.radius, model.table.height, model.seat.gap)
  } 
  seatShape.position(position)
  layer.add(seatShape);

}

function getPosComponent(val, radius, size, gap) {

  if (val.indexOf('r') > 0) {
    let num = parseInt(val),
      sign = Math.sign(num);
    return sign * ((Math.abs(num) * radius) + gap);
  } else if (val.indexOf('%') > 0) {
    let num = parseFloat(val),
      sign = Math.sign(num);
    return sign * (size * num / 100);
  }

  throw new Error("Unexpected val format " + val);
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset=UTF-8>
  <script src="https://unpkg.com/konva@8/konva.min.js"></script>

  <style>
    #container {
      width: 800px;
      height: 600px;
    }
  </style>

</head>

<body>
  <div id="container"></div>


</body>

</html>

Upvotes: 2

Related Questions