0

I'm a bit rough with jQuery so bear with me here. :)

The goal of the code is to on click, if the square is white, color it with the selected color. If it is the selected color, set it back to white. It works except when going from a color to another color, there's a spot of white inbetween. For example:

When I do black > blue, it processes as black > white > blue.

Here's the snippet of my code

$(pixelCanvas).on("click", "td", function(){
let background = $(this).css("background-color");
let isEmpty = !background || background === "rgb(255, 255, 255)" ||
   background === "#ffffff";
let isNotColor = background !== color;
if(isEmpty){
    $(this).css("background-color", color); 
} else if(isNotColor){
    $(this).css("background-color", color);
} else {
    $(this).css("background-color", "#ffffff");
}

});

And here's my codepen link

https://codepen.io/ashleighc207/pen/QaezPO

Thank you in advance!!

Almost_Ashleigh
  • 524
  • 1
  • 4
  • 24
  • 1
    why not use class instead and use addClass() or removeClass() for changing colors? – guradio Feb 02 '18 at 01:38
  • @guradio is totally right .. its really hard (if its possible) to achieve this with `.css()` create css class for each color then use `if($('element').hasClass())` and add/remove Class will be better and simple way to do that – Mohamed-Yousef Feb 02 '18 at 01:44
  • 1
    @guardio But how will I update the CSS class color dynamically. That's my issue. When a user selects a new input here and the value of color changes, how does that get passed to the CSS class? – Almost_Ashleigh Feb 02 '18 at 01:45
  • It works without if else ladder in `$(pixelCanvas).on("click"` event, why do you need it? If you really need to check if background !== color then think of creating a boolean variable and change it accordingly. – Aniket Sahrawat Feb 02 '18 at 01:49
  • @AniketSahrawat I also need to set it to white if it is equal to color. That's why I have the if else – Almost_Ashleigh Feb 02 '18 at 01:57
  • @Almost_Ashleigh I tried to debug your code and one of the things I noticed was the color could be in a different formats (example: hex, rgb, rgba). So when you try to compare `background` with `color` in your `isNotColor` function it could be false even though they are the same color, just different formats. I believe that's why @guradio is suggesting using classes instead. I believe the real challenge here is putting a function together that will compare colors regardless of its format. – David Lee Feb 02 '18 at 02:01
  • @DavidLee yeah, I thought that would probably be the main issue here, but wanted to see if anyone knew a workaround/idea – Almost_Ashleigh Feb 02 '18 at 02:07
  • @Almost_Ashleigh I posted an answer, let me know if it doesn't work for you. – David Lee Feb 02 '18 at 02:23

1 Answers1

1

So I found a function to convert rgb to hex here and used it on your background color. It seems to work fine, but I am not sure if it will work consistently across all browsers and operating systems, tested Chrome with Windows 10. Either way it should give you an idea on what you need to focus on and that is making sure your color codes are all in the same format.

/* global $ */
$(document).ready(function() {
  let color = $("#colorPicker").val();
  let row = $(".row");
  let column = $(".column");
  let submitBtn = $("#submitBtn");
  let pixelCanvas = $("#pixel_canvas");
  let mouseDown = false;


  function makeGrid(height, width) {
    for (let i = 0; i < height; i++) {
      let tableRow = $("<tr class=\"row\"></tr>");
      for (let j = 0; j < width; j++) {
        tableRow.append("<td class=\"column\"></td>");
      }
      pixelCanvas.append(tableRow);
    }
  }

  function removeGrid() {
    $("tr").remove();
  }

  function rgbToHex(rgb) {
    var a = rgb.split("(")[1].split(")")[0].split(",");
    return "#" + a.map(function(x) {
      x = parseInt(x).toString(16);
      return (x.length == 1) ? "0" + x : x;
    }).join("");
  }

  $(submitBtn).on("click", function(evt) {
    evt.preventDefault();
    removeGrid();
    let inputHeight = $("#inputHeight").val();
    let inputWidth = $("#inputWidth").val();
    makeGrid(inputHeight, inputWidth);
  });

  $("#colorPicker").on("change", function() {
    color = $("#colorPicker").val();
  });

  $(pixelCanvas).on("mousedown", function() {
    mouseDown = true;
  });

  $(pixelCanvas).on("click", "td", function() {
    let background = rgbToHex($(this).css("background-color"));
    let isEmpty = !background || background === "rgb(255, 255, 255)" ||
      background === "#ffffff";
    let isNotColor = background !== color;

    console.log(color);
    console.log(background);
    console.log(isEmpty);
    console.log(isNotColor);

    if (isEmpty) {
      $(this).css("background-color", color);
    } else if (isNotColor) {
      $(this).css("background-color", color);
    } else {
      $(this).css("background-color", "#ffffff");
    }
  });


  $(pixelCanvas).on("mouseup", function() {
    mouseDown = false;
  });

  $(pixelCanvas).on("mousemove", "td", function(evt) {
    evt.preventDefault();
    if (mouseDown) {
      $(this).attr("style", `background-color: ${color}`);
    }
  });
});
body {
  margin: 0px;
  margin-bottom: 500px; /* added this cause logs are blocking screen */
}

.container {
  text-align: center;
  font-family: Century Gothic, helvetica;
  display: flex;
  flex-direction: column;
  height: 20%;
  min-height: 100vh;
}

.row,
.column {
  background-color: #FFFFFF;
}

.content {
  display: flex;
  text-align: center;
  height: 80%;
  padding: 2%;
  justify-content: space-around;
}

.column-1 {
  display: flex;
  order: 1;
  flex: 0 1 20%;
  flex-direction: column;
}

.column-2 {
  display: flex;
  order: 2;
  flex: 0 1 80%;
  flex-direction: column;
}

.heading-one {
  flex: 0 1 100%;
  font-family: Century Gothic, helvetica;
  font-size: 70px;
  margin: 0px;
  height: 10%;
}

.form-group {
  padding: 5% 0%;
}

#pixel_canvas,
.row,
.column {
  border: 1px solid black;
}

#pixel_canvas {
  border-collapse: collapse;
  margin: 0 auto;
}

.row {
  height: 20px;
}

.column {
  width: 20px;
}

#inputHeight,
#inputWidth {
  width: 6em;
}

#submitBtn,
#colorPicker {
  border-radius: 5px;
}

#colorPicker {
  border: none;
  box-shadow: 1px 1px 1px #777777;
}
<!DOCTYPE html>
<html>

<head>
  <title>Pixel Art</title>
  <link rel="stylesheet" href="stylesheet.css">
</head>

<body class="container">
  <h1 class="heading-one">Pixel Art Maker</h1>
  <div class="content">
    <div class="column-1">
      <h2 class="heading-two">Choose Pixel Grid Size</h2>
      <form id="sizePicker">
        <div class="form-group">
          <label for="input_height">
                    Grid Height:
                </label>
          <input type="number" id="inputHeight" name="height" min="1" max="50" value="1">
        </div>
        <div class="form-group">
          <label for="input_width">
                    Grid Width:
                </label>
          <input type="number" id="inputWidth" name="width" min="1" value="1">
          <div class="form-group">
            <input type="submit" id="submitBtn" value="Create!">
          </div>
        </div>
      </form>
      <h2 class="heading-two">Pick A Color</h2>
      <div class="form-group">
        <input type="color" id="colorPicker">
      </div>
    </div>
    <div class="column-2">
      <h2 class="heading-two">Design Canvas</h2>
      <table id="pixel_canvas"></table>
    </div>
  </div>
  <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
  <script type="text/javascript" src="designs.js"></script>
</body>

</html>

EDIT: Added margin to bottom so logs don't block inputs and specified browser and OS.

David Lee
  • 2,040
  • 17
  • 36