1- import { css , customElement , html , LitElement , property } from 'lit-element' ;
1+ import { css , customElement , html , LitElement , property , svg } from 'lit-element' ;
2+ import { ElementPin } from './pin' ;
23
34@customElement ( 'wokwi-7segment' )
45export class SevenSegmentElement extends LitElement {
6+ /** The color of a lit segment */
57 @property ( ) color = 'red' ;
8+
9+ /** The colon of an unlit segment */
10+ @property ( ) offColor = '#444' ;
11+
12+ /** The background color of the 7-segment display */
13+ @property ( ) background = 'black' ;
14+
15+ /** Number of digits to display (1, 2 or 4 are common values) */
16+ @property ( { type : Number } ) digits = 1 ;
17+
18+ /** Whether to show a colon (clock mode) */
19+ @property ( { type : Boolean } ) colon = false ;
20+
21+ /** Whether the colon is lit or not */
22+ @property ( { type : Boolean } ) colonValue = false ;
23+
24+ /**
25+ * Pin format. `top` to draw pins on top of the segment display panel,
26+ * `extend` to extend them to the sides of the panel, and `none` to
27+ * disable drawing the pins.
28+ */
29+ @property ( ) pins : 'top' | 'extend' | 'none' = 'top' ;
30+
31+ /**
32+ * The values for the individual segments. Each digits has 8
33+ * segment values in the following order: A, B, C, D, E, F, G, DP
34+ *
35+ * The values are 1 for a lit segment, and 0 for an unlit segment.
36+ */
637 @property ( { type : Array } ) values : number [ ] = [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] ;
738
39+ get pinInfo ( ) : ElementPin [ ] {
40+ const pinXY = ( n : number ) => {
41+ const { startX, cols, bottomY } = this . pinPositions ;
42+ const col = ( n - 1 ) % cols ;
43+ const row = Math . floor ( ( n - 1 ) / cols ) ;
44+ const xOffset = 1.27 ;
45+ const mmToPix = 3.78 ;
46+ const x = startX + xOffset + col * 2.54 ;
47+ const y = this . pins === 'top' ? ( row ? bottomY + 1 : 1 ) : row ? bottomY + 2 : 0 ;
48+ return { number : n , x : x * mmToPix , y : y * mmToPix } ;
49+ } ;
50+
51+ switch ( this . digits ) {
52+ case 4 :
53+ // Pinout based on KW4-56NALB model
54+ return [
55+ { name : 'A' , ...pinXY ( 13 ) , signals : [ ] , description : 'Segment A' } ,
56+ { name : 'B' , ...pinXY ( 9 ) , signals : [ ] , description : 'Segment B' } ,
57+ { name : 'C' , ...pinXY ( 4 ) , signals : [ ] , description : 'Segment C' } ,
58+ { name : 'D' , ...pinXY ( 2 ) , signals : [ ] , description : 'Segment D' } ,
59+ { name : 'E' , ...pinXY ( 1 ) , signals : [ ] , description : 'Segment E' } ,
60+ { name : 'F' , ...pinXY ( 12 ) , signals : [ ] , description : 'Segment F' } ,
61+ { name : 'G' , ...pinXY ( 5 ) , signals : [ ] , description : 'Segment G' } ,
62+ { name : 'DP' , ...pinXY ( 3 ) , signals : [ ] , description : 'Decimal Point' } ,
63+ { name : 'DIG1' , ...pinXY ( 14 ) , signals : [ ] , description : 'Digit 1 Common' } ,
64+ { name : 'DIG2' , ...pinXY ( 11 ) , signals : [ ] , description : 'Digit 2 Common' } ,
65+ { name : 'DIG3' , ...pinXY ( 10 ) , signals : [ ] , description : 'Digit 3 Common' } ,
66+ { name : 'DIG4' , ...pinXY ( 6 ) , signals : [ ] , description : 'Digit 4 Common' } ,
67+ { name : 'COM' , ...pinXY ( 7 ) , signals : [ ] , description : 'Common pin' } ,
68+ { name : 'CLN' , ...pinXY ( 8 ) , signals : [ ] , description : 'Colon' } ,
69+ ] ;
70+
71+ case 2 :
72+ // Pinout based on CL5621C model
73+ return [
74+ { name : 'DIG1' , ...pinXY ( 8 ) , signals : [ ] , description : 'Digit 1 Common' } ,
75+ { name : 'DIG2' , ...pinXY ( 7 ) , signals : [ ] , description : 'Digit 2 Common' } ,
76+ { name : 'A' , ...pinXY ( 10 ) , signals : [ ] , description : 'Segment A' } ,
77+ { name : 'B' , ...pinXY ( 9 ) , signals : [ ] , description : 'Segment B' } ,
78+ { name : 'C' , ...pinXY ( 1 ) , signals : [ ] , description : 'Segment C' } ,
79+ { name : 'D' , ...pinXY ( 4 ) , signals : [ ] , description : 'Segment D' } ,
80+ { name : 'E' , ...pinXY ( 3 ) , signals : [ ] , description : 'Segment E' } ,
81+ { name : 'F' , ...pinXY ( 6 ) , signals : [ ] , description : 'Segment F' } ,
82+ { name : 'G' , ...pinXY ( 5 ) , signals : [ ] , description : 'Segment G' } ,
83+ { name : 'DP' , ...pinXY ( 2 ) , signals : [ ] , description : 'Decimal Point' } ,
84+ ] ;
85+
86+ case 1 :
87+ default :
88+ // Pinout based on 5611BH model
89+ return [
90+ { name : 'COM.1' , ...pinXY ( 3 ) , signals : [ ] , description : 'Common' } ,
91+ { name : 'COM.2' , ...pinXY ( 8 ) , signals : [ ] , description : 'Common' } ,
92+ { name : 'A' , ...pinXY ( 7 ) , signals : [ ] , description : 'Segment A' } ,
93+ { name : 'B' , ...pinXY ( 6 ) , signals : [ ] , description : 'Segment B' } ,
94+ { name : 'C' , ...pinXY ( 4 ) , signals : [ ] , description : 'Segment C' } ,
95+ { name : 'D' , ...pinXY ( 2 ) , signals : [ ] , description : 'Segment D' } ,
96+ { name : 'E' , ...pinXY ( 1 ) , signals : [ ] , description : 'Segment E' } ,
97+ { name : 'F' , ...pinXY ( 9 ) , signals : [ ] , description : 'Segment F' } ,
98+ { name : 'G' , ...pinXY ( 10 ) , signals : [ ] , description : 'Segment G' } ,
99+ { name : 'DP' , ...pinXY ( 5 ) , signals : [ ] , description : 'Decimal Point' } ,
100+ ] ;
101+ }
102+ }
103+
8104 static get styles ( ) {
9105 return css `
10106 polygon {
@@ -15,28 +111,89 @@ export class SevenSegmentElement extends LitElement {
15111 ` ;
16112 }
17113
114+ get pinPositions ( ) {
115+ const { digits } = this ;
116+ const numPins = digits === 4 ? 14 : 10 ;
117+ const cols = Math . ceil ( numPins / 2 ) ;
118+ return {
119+ startX : ( 12.55 * digits - cols * 2.54 ) / 2 ,
120+ bottomY : this . pins === 'extend' ? 21 : 17 ,
121+ cols,
122+ } ;
123+ }
124+
125+ private get yOffset ( ) {
126+ return this . pins === 'extend' ? 2 : 0 ;
127+ }
128+
129+ renderDigit ( x : number , startIndex : number ) {
130+ const fill = ( index : number ) => ( this . values [ startIndex + index ] ? this . color : this . offColor ) ;
131+ return svg `
132+ < g transform ="skewX(-8) translate(${ x } , ${ this . yOffset + 2.4 } ) scale(0.81) ">
133+ < polygon points ="2 0 8 0 9 1 8 2 2 2 1 1 " fill ="${ fill ( 0 ) } " />
134+ < polygon points ="10 2 10 8 9 9 8 8 8 2 9 1 " fill ="${ fill ( 1 ) } " />
135+ < polygon points ="10 10 10 16 9 17 8 16 8 10 9 9 " fill ="${ fill ( 2 ) } " />
136+ < polygon points ="8 18 2 18 1 17 2 16 8 16 9 17 " fill ="${ fill ( 3 ) } " />
137+ < polygon points ="0 16 0 10 1 9 2 10 2 16 1 17 " fill ="${ fill ( 4 ) } " />
138+ < polygon points ="0 8 0 2 1 1 2 2 2 8 1 9 " fill =${ fill ( 5 ) } / >
139+ < polygon points ="2 8 8 8 9 9 8 10 2 10 1 9 " fill =${ fill ( 6 ) } / >
140+ </ g >
141+ < circle cx ="${ x + 7.4 } " cy ="${ this . yOffset + 16 } " r ="0.89 " fill ="${ fill ( 7 ) } " />
142+ ` ;
143+ }
144+
145+ renderColon ( ) {
146+ const { yOffset } = this ;
147+ const colonPosition = 1.5 + 12.7 * Math . round ( this . digits / 2 ) ;
148+ const colonFill = this . colonValue ? this . color : this . offColor ;
149+ return svg `
150+ < g transform ="skewX(-8) " fill ="${ colonFill } ">
151+ < circle cx ="${ colonPosition } " cy ="${ yOffset + 5.75 } " r ="0.89 " />
152+ < circle cx ="${ colonPosition } " cy ="${ yOffset + 13.25 } " r ="0.89 " />
153+ </ g >
154+ ` ;
155+ }
156+
157+ renderPins ( ) {
158+ const { cols, bottomY, startX : x } = this . pinPositions ;
159+ return svg `
160+ < g fill ="url(#pin-pattern) " transform ="translate(${ x } , 0) ">
161+ < rect height ="2 " width =${ cols * 2.54 } / >
162+ < rect height ="2 " width =${ cols * 2.54 } transform ="translate(0, ${ bottomY } )" />
163+ </ g >
164+ ` ;
165+ }
166+
18167 render ( ) {
19- const { color, values } = this ;
20- const fill = ( index : number ) => ( values [ index ] ? color : '#ddd' ) ;
168+ const { digits, colon, pins, yOffset } = this ;
169+ const width = 12.55 * digits ;
170+ const height = pins === 'extend' ? 23 : 19 ;
171+ const digitShapes = [ ] ;
172+ for ( let i = 0 ; i < digits ; i ++ ) {
173+ digitShapes . push ( this . renderDigit ( 3.5 + i * 12.7 , i * 8 ) ) ;
174+ }
21175 return html `
22- < svg
23- width ="12mm "
24- height ="18.5mm "
25- version ="1.1 "
26- viewBox ="0 0 12 18.5 "
27- xmlns ="http://www.w3.org/2000/svg "
28- >
29- < g transform ="skewX(-8) translate(2, 0) ">
30- < polygon points ="2 0 8 0 9 1 8 2 2 2 1 1 " fill ="${ fill ( 0 ) } " />
31- < polygon points ="10 2 10 8 9 9 8 8 8 2 9 1 " fill ="${ fill ( 1 ) } " />
32- < polygon points ="10 10 10 16 9 17 8 16 8 10 9 9 " fill ="${ fill ( 2 ) } " />
33- < polygon points ="8 18 2 18 1 17 2 16 8 16 9 17 " fill ="${ fill ( 3 ) } " />
34- < polygon points ="0 16 0 10 1 9 2 10 2 16 1 17 " fill ="${ fill ( 4 ) } " />
35- < polygon points ="0 8 0 2 1 1 2 2 2 8 1 9 " fill =${ fill ( 5 ) } / >
36- < polygon points ="2 8 8 8 9 9 8 10 2 10 1 9 " fill =${ fill ( 6 ) } / >
37- </ g >
38- < circle cx ="11 " cy ="17 " r ="1.1 " fill ="${ fill ( 7 ) } " />
39- </ svg >
176+ < div style ="position:relative ">
177+ < svg
178+ width ="${ width } mm "
179+ height ="${ height } mm "
180+ version ="1.1 "
181+ viewBox ="0 0 ${ width } ${ height } "
182+ xmlns ="http://www.w3.org/2000/svg "
183+ >
184+ < defs >
185+ < pattern id ="pin-pattern " height ="2 " width ="2.54 " patternUnits ="userSpaceOnUse ">
186+ ${ pins === 'extend'
187+ ? svg `< rect x ="1.02 " y ="0 " height ="2 " width ="0.5 " fill ="#aaa " /> `
188+ : svg `< circle cx ="1.27 " cy ="1 " r =0.5 fill ="#aaa " /> ` }
189+ </ pattern >
190+ </ defs >
191+ < rect x ="0 " y ="${ yOffset } " width ="${ width } " height ="19 " />
192+ ${ digitShapes } <!-- -->
193+ ${ colon ? this . renderColon ( ) : null } <!-- -->
194+ ${ pins !== 'none' ? this . renderPins ( ) : null }
195+ </ svg >
196+ </ div >
40197 ` ;
41198 }
42199}
0 commit comments