Home > Mobile >  Canvas Draw lines not appearing
Canvas Draw lines not appearing

Time:09-16

I'm creating a hex based map generator and as part of that I am trying to - on the client side - draw "rivers", lines that travel through the centres of the hexes that the server end calculates have rivers.

Here are the relevant variables (this works it gets values inserted by django from the server end I've tested it it all works fine)

       // The optional populators
        const rivers = {{ rivers |safe}};
        const cities = {{ cities |safe}};
        const roads = {{roads |safe}};

        // Constants for our angles and scales, starting with scale 5
        const a = Math.PI/3;
        var r = 5;

And here is the function that draws the rivers

        // Function that draws Rivers
        function DrawRivers(){
            // For each river in the rivers
            for (var river of rivers) {
                // Set up point tracking
                let x_coord = r   river[0][0] * (r   (r * Math.cos(a)));
                let y_coord = r   river[0][1] * (r   (r*Math.sin(a)));
                if (river[0][0] % 2 == 1) {
                    y_off = y_coord;
                } else { // If it's an even number of tiles in the row it'll be the lower part
                    y_off = y_coord   r * Math.sin(a);
                }

                ctx.beginPath();
                ctx.lineWidth = r;
                ctx.strokeStyle = "#000000";
                ctx.moveTo(x_coord, Math.round(y_off))
                // For each point in the river
                for (var river_hex of river){
                    let x_coord = r   river[0][0] * (r   (r * Math.cos(a)));
                    let y_coord = r   river[0][1] * (r   (r*Math.sin(a)));
                    if (river[0][0] % 2 == 1) {
                        y_off = y_coord;
                    } else { // If it's an even number of tiles in the row it'll be the lower part
                        y_off = y_coord   r * Math.sin(a);
                    }
                    ctx.lineTo(x_coord, Math.round(y_off))
                }
                ctx.closePath();
                ctx.stroke();
                

            }
        }

However when I run this code the lines do not draw. I've stepped through the code and everything seems like it works; there aren't any points where the code doesn't have the required variables, it's just when the ctx.stroke() command is called it doesn't actually draw the line.

Can someone else see where I've gone wrong? Because I honestly can't...

CodePudding user response:

In your inner loop "For each point in the river" you are only using river[0], not river_hex (likely a copy-paste error), so you ended up drawing a single point.

You can simplify your code (and make less copy-paste mistakes ;-) ) by moving the hex-to-screen coordinate computation to a separate function, and by using an old-school for loop so you don't need to handle the first moveTo separately.

const rivers = [
  [
    [0, 0],
    [1, 0],
    [1, 1],
    [1, 2],
    [1, 3],
    [1, 4],
    [2, 4],
    [3, 5],
    [4, 5],
  ],
];

const a = Math.PI / 3;
var r = 15;

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

function convertCoordinate(hex) {
  const [hexX, hexY] = hex;
  const x_coord = r   hexX * (r   (r * Math.cos(a)));
  let y_coord = r   hexY * (r   (r * Math.sin(a)));
  if (hexX % 2 !== 1) {
    // If it's an even number of tiles in the row it'll be the lower part
    y_coord  = r * Math.sin(a);
  }
  return [x_coord, y_coord];
}

// Function that draws Rivers
function DrawRivers() {
  // For each river in the rivers
  for (var river of rivers) {
    ctx.lineWidth = r;
    ctx.strokeStyle = '#000000';
    ctx.beginPath();
    // For each point in the river
    for (let i = 0; i < river.length; i  ) {
      const [x, y] = convertCoordinate(river[i]);
      if (i === 0) ctx.moveTo(x, y);
      else ctx.lineTo(x, y);
    }
    // Not quite sure if a river should be closed...
    // ctx.closePath();
    ctx.stroke();
  }
}

DrawRivers();
canvas {
  border: 1px solid orange;
}
<canvas id="canvas" width="500" height="500"></canvas>

  • Related