DEV Community

Calin Baenen
Calin Baenen

Posted on

Why won't anything draw on my canvas?

Whenever I try to draw a custom image in JS, it doesn't draw anything, when I try to log X or Y in the loop, it returns normal values, when I log the color, it's perfectly normal.

So, why won't it draw anything?

const text = `Example`;



const makeColor = function makeColor(input, maxX=Infinity, maxY=Infinity) {
    let X = 0;
    let Y = 0;

    let peakX = -1;
    let peakY = -1;
    if(maxX < Infinity) maxX;



    const encode = function encode(input) {
        let estr = "";
        for(const chara of input) {
            estr += String(Number(chara.charCodeAt(0), 16));
        }
        return estr;
    };


    const colors = [];
    let color = "";
    let itr = 0;
    for(const chara of encode(input)) {
        color += chara;
        if(color.length >= 6) {
            itr += 1;
            colors.push(color);
            document.writeln(itr+": "+color+"<br/>");
            color = "";
        }
    }

    if(color.length < 6 && color.length > 0) {
        color += "0".repeat(6-color.length);
        colors.push(color);
        document.writeln(color+"<br/>");
        color = "";
    }



    Object.freeze(colors);


    try {
        const canvas = document.getElementById("result");
        const ctx = canvas.getContext("2d");

        try {
            for(const color of colors) {
                console.log(X, Y);
                ctx.fillStyle = "#"+color;
                if(X > maxX) {
                    if(peakX <= -1 || X > peakX) peakX = X-1;
                    X = 0; Y++; ctx.fillRect(X, Y, 1, 1); X++; continue;
                }
                if(Y > maxY) break;
                ctx.fillRect(X, Y, 1, 1); X++;
            }
            if(maxX >= Infinity) peakY = 1;
            canvas.style.width = canvas.width = peakX;
            canvas.style.height = canvas.height = peakY;
        } catch(err) {throw new Error();}
    } catch(err) {console.error("Could not draw image!");}
};



makeColor(text, 30);

Enter fullscreen mode Exit fullscreen mode

Top comments (13)

Collapse
 
ducaale profile image
Mohamed Dahir • Edited

Try to avoid document.writeln() since it deletes your existing HTML elements. If you need to debug your code, you can use console.log() which will output to the console tab of chrome's devtools.

I also have a couple of comments about your coding style if you don't mind:

  • Try to use Prettier's playground to format your code. This way, it will be easier for others to read your code.
  • You don't have to declare your function names twice
const makeColor = function makeColor(input, maxX=Infinity, maxY=Infinity) {}
// should be either
const makeColor = (input, maxX=Infinity, maxY=Infinity) => {}
// or
function makeColor(input, maxX=Infinity, maxY=Infinity) {}
Enter fullscreen mode Exit fullscreen mode
  • By convention, variables should start with a lowercase letter e.g X and Y should be x and y. This doesn't apply to constant which are uppercased e.g UPLOAD_SUCCESS.
  • Don't use backticks unless you need string interpolation
const text = `Example`;
// should be changed to
const text = 'Example';
// or
const text = "Example";
Enter fullscreen mode Exit fullscreen mode
  • You don't have to freeze your objects. Just try to avoid methods that mutate objects.
Collapse
 
baenencalin profile image
Calin Baenen

Okay, maybe I should have specified what I meant by log-ed, as I removed the debug code. But still, come on, document.write()+ is NOT logging, it's WRITING.

Collapse
 
ducaale profile image
Mohamed Dahir

In that case, you should be using innerHTML and not document.writeln()

document.getElementById('some-id').innerHTML += color;
Enter fullscreen mode Exit fullscreen mode
Collapse
 
baenencalin profile image
Calin Baenen

I did use console.log() to debug my code. document.writeln is a different part of the program.

Did you not fully (thoroughly*) read the post? :p

Collapse
 
ducaale profile image
Mohamed Dahir

let's say you had an HTML file like this:

<html>
  <body>
    <canvas id="result"></canvas>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

as soon this line gets executed

document.writeln("#fff<br/>");
Enter fullscreen mode Exit fullscreen mode

your HTML will be converted to this:

<html>
  <body>
    #fff<br/>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

As you can see, this removes your canvas element from the DOM which will lead document.getElementById("result") to fail.

Now let's take a look at your code

for(const chara of encode(input)) {
  color += chara;
  if(color.length >= 6) {
    itr += 1;
    colors.push(color);
    document.writeln(itr+": "+color+"<br/>");
    color = "";
  }
}
Enter fullscreen mode Exit fullscreen mode

Since you called the makeColor() function with the string Example, you would get the string "6912097109112108101". This string contains chars that are greater than 6 which means your canvas element will be overwritten by your document.writeln().

Thread Thread
 
baenencalin profile image
Calin Baenen

It wasn't overriden, though, it just stayed black (which was the default color I gave it).

Thread Thread
 
ducaale profile image
Mohamed Dahir

Did you set the color through CSS? In that case, may I see your CSS file?

Thread Thread
 
baenencalin profile image
Calin Baenen

I set the color using inline (element) styling.

Collapse
 
ducaale profile image
Mohamed Dahir

I take back my comments about document.writeln(). Your problems seem to stem from the following:

  • You are setting the canvas' width and height to peakX and peakY which equal -1;
  • You fillRect calls were drawing boxes that were too tiny. You can make things larger by multiplying them with a scaler value
function makeColor(input, maxX = Infinity, maxY = Infinity) {
  let X = 0;
  let Y = 0;

  let peakX = -1;
  let peakY = -1;

  function encode(input) {
    let estr = "";
    for (const chara of input) {
      estr += String(Number(chara.charCodeAt(0), 16));
    }
    return estr;
  };

  const colors = [];
  let color = "";
  let itr = 0;
  for (const chara of encode(input)) {
    color += chara;
    if (color.length >= 6) {
      itr += 1;
      colors.push(color);
      document.writeln(itr + ": " + color + "<br/>");
      color = "";
    }
  }

  if (color.length < 6 && color.length > 0) {
    color += "0".repeat(6 - color.length);
    colors.push(color);
    document.writeln(color + "<br/>");
    color = "";
  }

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

  for (const color of colors) {
    ctx.fillStyle = "#" + color;
    if (X > maxX) {
      if (peakX <= -1 || X > peakX) peakX = X - 1;
      X = 0;
      Y++;
      console.log(ctx.fillStyle, X, Y, 1, 1)
      ctx.fillRect(X, Y, 1, 1);
      X++;
      continue;
    }
    if (Y > maxY) break;
    ctx.fillRect(X * 25, Y * 25, 25, 25);
    X++;
  }
  if (maxX >= Infinity) peakY = 1;
  //canvas.style.width = canvas.width = peakX;
  //canvas.style.height = canvas.height = peakY;

}

makeColor('Example', 30);
Enter fullscreen mode Exit fullscreen mode
Collapse
 
baenencalin profile image
Calin Baenen

PeakX and PeakY were not negative 1, Peak* changes once Axis is greater than PeakAxis, meaning something went wrong.

Also, I didn't upscale the pixels because I wanted a 1:1 image.

Collapse
 
baenencalin profile image
Calin Baenen

Nevermind. Why is peakX and peakY behaving strangely?

Collapse
 
ducaale profile image
Mohamed Dahir

Can you show the whole code? right now, there are a couple of variables missing. Btw, you don't have to use try/catch until it is absolutely necessary.

Collapse
 
baenencalin profile image
Calin Baenen
const text = `Example`;



const makeColor = function makeColor(input, maxX=Infinity, maxY=Infinity) {
    let X = 0;
    let Y = 0;

    let peakX = -1;
    let peakY = -1;
    if(maxX < Infinity) maxX;



    const encode = function encode(input) {
        let estr = "";
        for(const chara of input) {
            estr += String(Number(chara.charCodeAt(0), 16));
        }
        return estr;
    };


    const colors = [];
    let color = "";
    let itr = 0;
    for(const chara of encode(input)) {
        color += chara;
        if(color.length >= 6) {
            itr += 1;
            colors.push(color);
            document.writeln(itr+": "+color+"<br/>");
            color = "";
        }
    }

    if(color.length < 6 && color.length > 0) {
        color += "0".repeat(6-color.length);
        colors.push(color);
        document.writeln(color+"<br/>");
        color = "";
    }



    Object.freeze(colors);


    try {
        const canvas = document.getElementById("result");
        const ctx = canvas.getContext("2d");

        try {
            for(const color of colors) {
                console.log(X, Y);
                ctx.fillStyle = "#"+color;
                if(X > maxX) {
                    if(peakX <= -1 || X > peakX) peakX = X-1;
                    X = 0; Y++; ctx.fillRect(X, Y, 1, 1); X++; continue;
                }
                if(Y > maxY) break;
                ctx.fillRect(X, Y, 1, 1); X++;
            }
            if(maxX >= Infinity) peakY = 1;
            canvas.style.width = canvas.width = peakX;
            canvas.style.height = canvas.height = peakY;
        } catch(err) {throw new Error();}
    } catch(err) {console.error("Could not draw image!");}
};



makeColor(text, 30);
Enter fullscreen mode Exit fullscreen mode