Search code examples
javascriptarraysdom-eventsseven-segment-display

Javascript seven segment display not lighting up or responding to event clicks


I'm brand new to coding, can anyone tell me whats wrong with my code? It's probably some mistake I made within the code, but I've been trying at it for a few hours now, any help would be appreciated!

var theCanvas = document.getElementById("theCanvas");
var c = theCanvas.getContext("2d");

/**
* Construct(x, y) Coordinate object representing a point on a 2D plane
*/
function Coord2D(x_ordinate, y_ordinate) {
 return {
 x : x_ordinate,
 y : y_ordinate
 };
}
theCanvas.center = new Coord2D(theCanvas.width/2, theCanvas.height/2);
var SEGMENT_LENGTH = 150;
var SEGMENT_BREADTH = 20;
var LEFT_X = theCanvas.center.x - SEGMENT_LENGTH/2;
var TOP_Y = theCanvas.center.y - SEGMENT_LENGTH/2 - SEGMENT_BREADTH;
var RIGHT_X = theCanvas.center.x + SEGMENT_LENGTH/2 - SEGMENT_BREADTH;
var BOTTOM_Y = theCanvas.center.y + SEGMENT_LENGTH/2 + SEGMENT_BREADTH;
var MIDBOT_Y = theCanvas.center.y - SEGMENT_BREADTH - SEGMENT_BREADTH;
var MID_Y = theCanvas.center.y ;
// A 2D Segment object: a rectangle representing one display segment
function Segment(x, y, isVertical) {
var segment = {
coord : new Coord2D(x, y),
width : SEGMENT_LENGTH,
height: SEGMENT_BREADTH,
isOn : false
};
if (isVertical) {
segment.width = SEGMENT_BREADTH;
segment.height = SEGMENT_LENGTH;
};
return segment;
}; 

function drawSegment(segment) {
c.fillStyle = 'lightgrey';
if (segment.isOn) {
c.fillStyle = 'red';
}
c.fillRect(segment.coord.x, segment.coord.y,
segment.width, segment.height);
};

var SevenSegDisplay = [
new Segment(LEFT_X, TOP_Y, false), //top segment A
new Segment(RIGHT_X, TOP_Y, true),  //right top vert segment B
new Segment(LEFT_X, MIDBOT_Y, true),  //left bot vert segment C
new Segment(LEFT_X, BOTTOM_Y, false),//bottom segment D
new Segment(RIGHT_X, MIDBOT_Y, true), //right bot vert segment E
new Segment(LEFT_X, TOP_Y, true),//left top vert segment F
new Segment(LEFT_X, MID_Y, false),//middle segment G
];

function drawSevenSegDisplay (key) {
    for(i=0;i<SevenSegDisplay.length;i++){
drawSegment(SevenSegDisplay[i]);
}if(SWITCH_ENCODING.hasOwnProperty(key)){
    var switches = SWITCH_ENCODING[key];
};
};
var ON = true;
var OFF = false;
// Map event.key onto an encoding of the switch state for each segment
var SWITCH_ENCODING = {
'Off' : [OFF,OFF,OFF,OFF,OFF,OFF,OFF],
'0' : [ ON, ON, ON, ON, ON, ON,OFF],
'1' : [ OFF, ON, ON, OFF, OFF, OFF,OFF],
'2' : [ ON, ON, OFF, ON, ON, OFF,ON],
'3' : [ ON, ON, ON, ON, OFF, OFF,ON],
'4' : [ OFF, ON, OFF, OFF, ON, ON,OFF],
'5' : [ ON, OFF, ON, ON, OFF, ON,ON],
'6' : [ ON, OFF, ON, ON, ON, ON,ON],
'7' : [ ON, ON, ON, OFF, OFF, OFF,OFF],
'8' : [ ON, ON, ON, ON, ON, ON,ON],
'9' : [ ON, ON, ON, OFF, OFF, ON,ON],}
document.onkeydown = drawSevenSegDisplay(Event.key);

Solution

  • It looks like you have to attach the event listener differently:

    document.onkeydown = drawSevenSegDisplay(Event.key);

    should be: document.onkeydown = function(Event) { drawSevenSegDisplay(Event.key) };

    Also, it looks like the drawSevenSegDisplay does draw the initial display, but does not update it afterwards. You'll want to create a new array of Segments for each number - for example, 0 would be:

    [
        new Segment(LEFT_X, TOP_Y, false), //top segment A
        new Segment(RIGHT_X, TOP_Y, true),  //right top vert segment B
        new Segment(LEFT_X, MIDBOT_Y, true),  //left bot vert segment C
        new Segment(LEFT_X, BOTTOM_Y, false),//bottom segment D
        new Segment(RIGHT_X, MIDBOT_Y, true), //right bot vert segment E
        new Segment(LEFT_X, TOP_Y, true),//left top vert segment F
    ];
    

    1 would be:

    [
        new Segment(RIGHT_X, TOP_Y, true),  //right top vert segment B
        new Segment(RIGHT_X, MIDBOT_Y, true), //right bot vert segment E
    ];
    

    an so on for the rest of the segments. Then, in the for loop, instead of iterating over the SevenSegDisplay array, you could iterate over the array corresponding to the appropriate number for each segment. If you're curious, here's a simple example for a seven-segment display.

    // segments from  top->bottom left->right
    //    
    //    _0_
    //   |   |
    //   1   2
    //   |_3_| 
    //   |   |
    //   4   5
    //   |_6_|
    
    var canvas = document.getElementById('canvas');
    var context = canvas.getContext('2d'); 
    var segmentDefinitions = [
      // this was simply easier to type
      [0, 1, 2, 4, 5, 6],          // 0
      [2, 5],                      // 1
      [0, 2, 3, 4, 6],             // 2
      [0, 2, 3, 5, 6],             // 3
      [1, 2, 3, 5],                // 4
      [0, 1, 3, 5, 6],             // 5
      [0, 1, 3, 4, 5, 6],          // 6
      [0, 2, 5],                   // 7
      [0, 1, 2, 3, 4, 5, 6],       // 8
      [0, 1, 2, 3, 5, 6],          // 9
    ];
    
    // onkeydown expects a callback function
    window.onkeydown = function(event) {
      var key = +event.key; // parse the key as a number
      if (key >=0 && key <= 9)
        drawNumber(key);
    }
    
    // fills the canvas with a white rectangle
    function clearCanvas() {
      context.fillStyle = 'white';
      context.fillRect(0, 0, canvas.width, canvas.height);
    }
    
    // draws a number onto the canvas
    function drawNumber(number) {
      clearCanvas();
      segmentDefinitions[number].forEach(drawSegment)
    }
    
    // draws a specific segment onto the canvas
    function drawSegment(id) {
      var width = canvas.width;
      var height = canvas.height;
      var borderWidth = 20;
      context.fillStyle = 'red';
    
      switch(id) {
        case 0:
          context.fillRect(
            0, 0, 
            width, borderWidth);
          break;
        case 1:
          context.fillRect(
            0, 0, 
            borderWidth, height / 2);
          break;
        case 2:
          context.fillRect(
            width - borderWidth, 0, 
            borderWidth, height/2);
          break;
        case 3:
          context.fillRect(
            0, height / 2, 
            width, borderWidth);
          break;
        case 4:
          context.fillRect(
            0, height / 2, 
            borderWidth, height/2);
          break;
        case 5:
          context.fillRect(
            width - borderWidth, height / 2, 
            borderWidth, height/2);
          break;
        case 6:
          context.fillRect(
            0, height - borderWidth, 
            width, borderWidth);
          break;
      }
    }
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width">
      <title>Seven Segment Display</title>
      <canvas id="canvas" width="80" height="160"></canvas>
      <h4>Click within this area to begin interacting with the canvas</h4>
    </head>
    <body>
    
    </body>
    </html>