p5.js is an amazing JavaScript library that streamlines creating graphical applications in your browser. Learn more at https://p5js.org/ They also have an extremely useful online editor https://editor.p5js.org/ which I used for this example and the link to it will be below.

Resource | URL |
Github source code for the display | https://github.com/jonathanmeaney/Seven_Segment_Display_Clock |
p5js editor version of display | https://editor.p5js.org/FugQueue/sketches/q8A2REall |
Inspired by the amazing Coding Train challenge | https://thecodingtrain.com/CodingChallenges/117-seven-segment.html |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let digitHour0, digitHour1, digitMinute0, digitMinute1, digitSecond0, digitSecond1; | |
let colon1, colon2; | |
function setup() { | |
createCanvas(395, 110); | |
} | |
function draw() { | |
background(51); | |
const time = new Date(); | |
// Each segment of the clock should be 2 digits long. | |
let hours = time.getHours(); | |
let hour0 = Number(hours.toString()[0]); | |
let hour1 = Number(hours.toString()[1]); | |
// For 1 – 9 hour0 will be the hour and hour1 will be undefined. | |
// So in this scenario check if hour1 is NaN and if so set hour0 to 0 and | |
// set hour1 to be what hour0 was. | |
if(isNaN(hour1)){ | |
const temp = hour0; | |
hour0 = 0; | |
hour1 = temp; | |
} | |
let minutes = time.getMinutes(); | |
let minute0 = Number(minutes.toString()[0]); | |
let minute1 = Number(minutes.toString()[1]); | |
// For 1 – 9 minute0 will be the minute and minute1 will be undefined. | |
// So in this scenario check if minute1 is NaN and if so set minute0 to 0 and | |
// set minute1 to be what minute0 was. | |
if(isNaN(minute1)){ | |
const temp = minute0; | |
minute0 = 0; | |
minute1 = temp; | |
} | |
let seconds = time.getSeconds(); | |
let second0 = Number(seconds.toString()[0]); | |
let second1 = Number(seconds.toString()[1]); | |
// For 1 – 9 second0 will be the second and second1 will be undefined. | |
// So in this scenario check if second1 is NaN and if so set second0 to 0 and | |
// set second1 to be what second0 was. | |
if(isNaN(second1)){ | |
const temp = second0; | |
second0 = 0; | |
second1 = temp; | |
} | |
// Create digits for hours | |
digitHour0 = new Digit(hour0, new Position(5,5)); | |
digitHour1 = new Digit(hour1, new Position(60,5)); | |
colon1 = new Colon(new Position(115, 5)); | |
// Create digits for minutes | |
digitMinute0 = new Digit(minute0, new Position(145,5)); | |
digitMinute1 = new Digit(minute1, new Position(200,5)); | |
colon2 = new Colon(new Position(255, 5)); | |
// Create digits for seconds | |
digitSecond0 = new Digit(second0, new Position(285,5)); | |
digitSecond1 = new Digit(second1, new Position(340,5)); | |
// Show Hours | |
digitHour0.show(); | |
digitHour1.show(); | |
colon1.show(); | |
// Show Minutes | |
digitMinute0.show(); | |
digitMinute1.show(); | |
colon2.show(); | |
// Show Seconds | |
digitSecond0.show(); | |
digitSecond1.show(); | |
} | |
class Digit{ | |
// seven segments | |
constructor(number, position, options){ | |
options = options || {}; | |
this.number = number; | |
this.position = position; | |
this.width = options.width || 50; | |
this.height = options.height || 100; | |
this.segmentHeight = options.segmentHeight || 10; | |
const horizontalSegmentWidth = floor(this.width – (2 * this.segmentHeight)); | |
const verticalSegmentHeight = floor((this.height – (3 * this.segmentHeight)) / 2); | |
// The segments are placed in a particular layout with each segment being called a different letter. | |
// The segment layout and names is below: | |
// AAAAAAAA | |
// AAAAAAAA | |
// FFFF BBBB | |
// FFFF BBBB | |
// FFFF BBBB | |
// FFFF BBBB | |
// FFFF BBBB | |
// GGGGGGGG | |
// GGGGGGGG | |
// EEEE CCCC | |
// EEEE CCCC | |
// EEEE CCCC | |
// EEEE CCCC | |
// EEEE CCCC | |
// DDDDDDDD | |
// DDDDDDDD | |
// Some common positions used to place segments | |
const centerSideX = this.position.x + this.segmentHeight; | |
const rightSideX = (this.position.x + this.width) – this.segmentHeight; | |
const upperSideY = this.position.y + this.segmentHeight; | |
const lowerSideY = this.position.y + (2 * this.segmentHeight); | |
// Detemine the position for each segment and create a new segment for each side | |
const aPosition = new Position(centerSideX, this.position.y); | |
// bitwise shift the hexadecimal number to determine if the specific segment should be illiminated | |
const aIlluminate = (this.num >> 6) & 1; | |
this.aSegment = new Segment(aPosition, horizontalSegmentWidth, this.segmentHeight, aIlluminate); | |
const bPosition = new Position(rightSideX, upperSideY); | |
const bIlluminate = (this.num >> 5) & 1; | |
this.bSegment = new Segment(bPosition, this.segmentHeight, verticalSegmentHeight, bIlluminate); | |
const cPosition = new Position(rightSideX, lowerSideY + verticalSegmentHeight); | |
const cIlluminate = (this.num >> 4) & 1; | |
this.cSegment = new Segment(cPosition, this.segmentHeight, verticalSegmentHeight, cIlluminate); | |
const dPosition = new Position(centerSideX, lowerSideY + (2 * verticalSegmentHeight)); | |
const dIlluminate = (this.num >> 3) & 1; | |
this.dSegment = new Segment(dPosition, horizontalSegmentWidth, this.segmentHeight, dIlluminate); | |
const ePosition = new Position(this.position.x, lowerSideY + verticalSegmentHeight); | |
const eIlluminate = (this.num >> 2) & 1; | |
this.eSegment = new Segment(ePosition, this.segmentHeight, verticalSegmentHeight, eIlluminate); | |
const fPosition = new Position(this.position.x, upperSideY); | |
const fIlluminate = (this.num >> 1) & 1; | |
this.fSegment = new Segment(fPosition, this.segmentHeight, verticalSegmentHeight, fIlluminate); | |
const gPosition = new Position(centerSideX, upperSideY + verticalSegmentHeight); | |
const gIlluminate = (this.num >> 0) & 1; | |
this.gSegment = new Segment(gPosition, horizontalSegmentWidth, this.segmentHeight, gIlluminate); | |
} | |
show(){ | |
// Call show on each of the named segments. | |
this.aSegment.show(); | |
this.bSegment.show(); | |
this.cSegment.show(); | |
this.dSegment.show(); | |
this.eSegment.show(); | |
this.fSegment.show(); | |
this.gSegment.show(); | |
} | |
// Get the hexadimal encoding associated with the supplied number | |
get num(){ | |
return this.nums[this.number]; | |
} | |
// Array of hexadecimal encodings for displaying digits 0 – 9 (gotten from https://en.wikipedia.org/wiki/Seven-segment_display) | |
get nums(){ | |
return [0x7e, 0x30, 0x6d, 0x79, 0x33, 0x5b, 0x5f, 0x70, 0x7f, 0x7b]; | |
} | |
} | |
// Basic class to store x, y coordinates of a position | |
class Position{ | |
constructor(x, y){ | |
this.x = x; | |
this.y = y; | |
} | |
} | |
// Class that represents a display segment. | |
class Segment{ | |
constructor(position, width, height, illuminate = false){ | |
this.position = position; | |
this.width = width; | |
this.height = height; | |
this.illuminate = illuminate; | |
} | |
show(){ | |
fill(255, 0, 0, this.illuminate ? 255 : 40); | |
rect(this.position.x, this.position.y, this.width, this.height); | |
} | |
} | |
// Class to define a colon between the digit sets | |
class Colon{ | |
constructor(position, options){ | |
options = options || {}; | |
this.position = position; | |
this.width = options.width || 25; | |
this.height = options.height || 100; | |
this.circleWidth = options.circleWidth || 15; | |
this.illuminate = true; | |
// get the center point of the colon boundary | |
const colonCenter = new Position(this.position.x + floor(this.width/2), this.position.y + floor(this.height/2)); | |
// space each circle evenly above and below the center point | |
this.topCirclePosition = new Position(colonCenter.x, colonCenter.y – 2*floor(this.circleWidth / 2)); | |
this.bottomCirclePosition = new Position(colonCenter.x, colonCenter.y + 2*floor(this.circleWidth / 2)); | |
} | |
show(){ | |
fill(255, 0, 0, this.illuminate ? 255 : 40); | |
circle(this.topCirclePosition.x, this.topCirclePosition.y, this.circleWidth); | |
circle(this.bottomCirclePosition.x, this.bottomCirclePosition.y, this.circleWidth); | |
} | |
} |
Advertisement