p5.js Seven Digit Segment Clock

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.

The beautiful clock
ResourceURL
Github source code for the displayhttps://github.com/jonathanmeaney/Seven_Segment_Display_Clock
p5js editor version of displayhttps://editor.p5js.org/FugQueue/sketches/q8A2REall
Inspired by the amazing Coding Train challengehttps://thecodingtrain.com/CodingChallenges/117-seven-segment.html
Resource links
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);
}
}
view raw sketch.js hosted with ❤ by GitHub

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s