0

I want to draw following 2d plan on canvas using javascript. enter image description here

I have width of each wall with its facing direction. I want to draw each wall in room in clockwise direction. In each room I have to first draw wall having direction similar to Main door direction(In this case it is North West[NW])

Can anybody please help me with some code snippets? I can able to draw walls using lines. But I need algorithm for this.

Following code I have tried till now

function drawPlan(cnv) {
    var plan = JSON.parse((localStorage.getItem("plan-name")));

    if (!plan)
        return true;

    var start = { x: planCanvas.width/2 - 100, y: planCanvas.height/2 - 100 };

    var canvasRef = document.getElementById('planner-canvas-reference-holder');

    var ctx = canvasRef.getContext('2d');

    //ctx.scale(100, 100);
    var actualWidth;
    var color = "red";

var plotLine = function(s, e, textX, textY) {
    ctx.beginPath();

    ctx.moveTo(s.x, s.y);
    ctx.lineTo(e.x, e.y);
    ctx.lineWidth = 1;

    ctx.font = "20px Times New Roman"
    ctx.textBaseline = "top";
    ctx.fillText(actualWidth, textX, textY, 20);
    ctx.strokeStyle = color;
    ctx.stroke();
    ctx.closePath();
};

var dir = "";
var mainDoorDirection = "N";
var previousDirection = "";
var currentDirection = "";
ep = { x: planCanvas.width/2 - 400, y: planCanvas.height/2 - 200 };

for (var j in plan) {
    var room = plan[j];
    previousDirection = "";
    currentDirection = "";
    dir = "";
    start = ep;
    start.x = start.x + 300;
    start.y = start.y + 100;

    for (var i in room) {

        var wall = room[i];
        var width = parseFloat(wall.width);
        actualWidth = width.toFixed(2);
        width = feetToPixel(width);
        width = width / 100;
        width = Math.floor(width);
        color = wall.color;
        currentDirection = wall.direction;

        var angle = wall.angle;
        var cd = "";

        if ((angle >= 0 && angle <= 22.5) || (angle >= 337.5 && angle < 360))
            cd = "N";

        if ((angle >= 292.5 && angle <= 337.5))
            cd = "NW";

        if ((angle >= 202.5 && angle <= 247.5))
            cd = "SW";

        if ((angle >= 112.5 && angle <= 157.5))
            cd = "SE";

        if ((angle >= 22.5 && angle <= 67.5))
            cd = "NE";
        if ((angle >= 247.5 && angle <= 292.5))
            cd = "W";

        if ((angle >= 157.5 && angle <= 202.5))
            cd = "S";

        if ((angle >= 67.5 && angle <= 112.5))
            cd = "E";

        if (currentDirection !== cd) {
            currentDirection = cd;
        }
        //console.log(i + "== " + cd + " ==== CUrrent == "+currentDirection+ " ==== Prev == "+previousDirection);
        if (dir) {



            if (currentDirection == 'NE' && (previousDirection == 'N' || previousDirection == 'NW')) {
                dir = 'top-bottom';
            }

            if (currentDirection == 'NW' && (previousDirection == 'NE')) {
                dir = 'left-right';
            }

            if (currentDirection == 'E' && (previousDirection == 'NW' || previousDirection == 'N' )) {
                dir = 'top-bottom';
            }
            if (currentDirection == 'S' && (previousDirection == 'W' || previousDirection == 'NE')) {
                dir = 'right-left';
            }
            if (currentDirection == 'W' && (previousDirection == 'S')) {
                dir = 'bottom-top';
            }

            if (currentDirection == 'SW' && (previousDirection == 'S')) {
                dir = 'bottom-top';
            }

            if (currentDirection == 'SE' && (previousDirection == 'W')) {
                dir = 'right-left';
            }

            if (currentDirection == 'SE' && (previousDirection == 'E' || previousDirection == 'NE')) {
                dir = 'right-left';
            }

            if (currentDirection == 'W' && (previousDirection == 'SW' || previousDirection == 'S' || previousDirection == 'SE')) {
                dir = 'bottom-top';
            }
        } else {
            if (mainDoorDirection == 'N')
                dir = "left-right";
        }


        var end = {};

        if (dir == "left-right") {
            end.x = start.x + width;
            end.x = end.x - 10;
            end.y = start.y;

            var textX = start.x + Math.abs((end.x - start.x) / 2) - 5;
            var textY = start.y - 20;
            plotLine(start, end, textX, textY);
            start = end;
            //dir = "top-bottom"
        } else if (dir == 'top-bottom') {
            end.x = start.x;
            end.y = start.y + width;
            end.y = end.y - 10;
            var textX = start.x + 5;
            var textY = start.y + Math.abs((end.y - start.y) / 2) - 5;
            plotLine(start, end, textX, textY);
            start = end;
            //dir = 'right-left';
        } else if (dir == 'right-left') {
            end.x = start.x - width;
            end.x = end.x + 10;
            end.y = start.y;
            var textX = start.x - Math.abs((end.x - start.x) / 2) - 5;
            var textY = start.y + 5;
            plotLine(start, end, textX, textY);
            start = end;
            //dir = 'bottom-top';
        } else if (dir == 'bottom-top') {
            end.x = start.x;
            end.y = start.y - width;
            end.y = end.y + 10;
            var textX = start.x - 22;
            var textY = start.y - Math.abs((end.y - start.y) / 2) - 5;
            plotLine(start, end, textX, textY);
            start = end;
            //dir = 'left-right';
        }
        wall.startPoint = start;
        wall.endPoint = end;
        ep = end;
        previousDirection = currentDirection;
    }
  }
}

My json file structures is as follows

{
  "rcptn": {
    "w1": {"width":12, "direction": "N", "angle": 343, "color": "red"},
    "w2": {"width":10, "direction": "E", "angle": 75, "color": "red"},
    "w3": {"width":12, "direction": "SE", "angle": 153, "color": "red"},
    "w4": {"width":10, "direction": "W", "angle": 251, "color": "red"}
  },
  "Living Room": {
    "w1": { "width": "22", "direction": "NW", "angle": 324, "color": "green"},
    "w2": { "width": "40", "direction": "NE", "angle": 63, "color": "green"},
    "w3": { "width": "4", "direction": "NW", "angle": 324, "color": "green"},
    "w4": { "width": "5", "direction": "E", "angle": 72, "color": "green"},
    "w5": { "width": "14", "direction": "SE", "angle": 152, "color": "green"},
    "w6": { "width": "10", "direction": "W", "angle": 248, "color": "green"},
    "w7": { "width": "2", "direction": "S", "angle": 182, "color": "green"},
    "w8": { "width": "4", "direction": "W", "angle": 249, "color": "green"},
    "w9": { "width": "8", "direction": "SE", "angle": 147, "color": "green"},
    "w10": { "width": "29", "direction": "SW", "angle": 249, "color": "green"}
  },
  "Study Room": {
    "w1": { "width": "12", "direction": "NW", "angle": 328, "color": "blue"},
    "w2": { "width": "20", "direction": "E", "angle": 68, "color": "blue"},
    "w3": { "width": "12", "direction": "SE", "angle": 156, "color": "blue"},
    "w4": { "width": "20", "direction": "W", "angle": 278, "color": "blue"}
  },
  "Kitchen 1": {
    "w1": { "width": "12", "direction": "NW", "angle": 333, "color": "orange"},
    "w2": { "width": "10", "direction": "NE", "angle": 60, "color": "orange"},
    "w3": { "width": "12", "direction": "S", "angle": 158, "color": "orange"},
    "w4": { "width": "10", "direction": "SW", "angle": 246, "color": "orange"}
  }
}
prashant
  • 127
  • 2
  • 10
  • If you know how to draw lines and you know the lines positions/rotations, what exactly do you need help with? Are you trying to animate this? If so, what have you tried so far? – DBS Nov 13 '17 at 11:13
  • @DBS, Yes I need to dynamically draw this plan. I am unable to find x and y coordinates for each wall. If I can draw each room individually. But I cannot able to write code which we will draw each room exactly like image I added.In short I need a program for this. I can also post code which I wrote. Thanks for your reply. – prashant Nov 13 '17 at 11:25
  • Well, you have the measurements of each wall, so you can work out their relative coordinates (just assign a certain number of pixels per ft and it should be simple enough). In terms of drawing them in an animated way, there are already some detailed explanations of this on this site: https://stackoverflow.com/questions/23939588/how-to-animate-drawing-lines-on-canvas – DBS Nov 13 '17 at 11:35

1 Answers1

1

I cannot see your coordinate sets, but it is easy to draw and stroke a polygon on canvas.

Make a list of coordinates for each room and loop over them, using beginPath(),closePath() and stroke() to draw them on the canvas.

var canvas = document.body.appendChild(document.createElement("canvas"));
var size = canvas.width = canvas.height = 1000;
var scale = 20;
var ctx = canvas.getContext("2d");
var coordinateSets = [
  //Big room
  [{
      x: 0,
      y: 0
    },
    {
      x: 22,
      y: 0
    },
    {
      x: 22,
      y: 0
    },
    {
      x: 22,
      y: 40
    },
    {
      x: 26,
      y: 40
    },
    {
      x: 26,
      y: 45
    },
    {
      x: 10,
      y: 45
    },
    {
      x: 10,
      y: 33
    },
    {
      x: 8,
      y: 33
    },
    {
      x: 8,
      y: 29
    },
    {
      x: 0,
      y: 29
    },
  ],
  //Little room 1
  [{
      x: 22,
      y: 0
    },
    {
      x: 34,
      y: 0
    },
    {
      x: 34,
      y: 10
    },
    {
      x: 22,
      y: 10
    },
  ],
  //Little room 2
  [{
      x: 22,
      y: 10
    },
    {
      x: 34,
      y: 10
    },
    {
      x: 34,
      y: 30
    },
    {
      x: 22,
      y: 30
    },
  ],
  //Little room 3
  [{
      x: 22,
      y: 30
    },
    {
      x: 34,
      y: 30
    },
    {
      x: 34,
      y: 40
    },
    {
      x: 22,
      y: 40
    },
  ],
];
coordinateSets.forEach(function(coordinates) {
  ctx.beginPath();
  ctx.moveTo(coordinates[0].x * scale, coordinates[0].y * scale);
  coordinates.forEach(function(coordinate) {
    ctx.lineTo(coordinate.x * scale, coordinate.y * scale);
  });
  ctx.closePath();
  ctx.stroke();
});
Emil S. Jørgensen
  • 6,216
  • 1
  • 15
  • 28
  • Thanks for code snippet. Actually my problem is same. I cannot able to find x.y coordinates dynamically. I have to first draw room having main door. I have to draw room similarly as it is defined in my json file. – prashant Nov 14 '17 at 05:15
  • @prashant You only have dimensions for the room. From your JSON we don't even know which rooms lead to one another. You need to either know the coordinates for the rooms or their position relative to each other to draw them. – Emil S. Jørgensen Nov 15 '17 at 08:10