|
| 1 | +import { customElement, html, LitElement, property, svg } from 'lit-element'; |
| 2 | + |
| 3 | +const SPACE_KEY = 32; |
| 4 | + |
| 5 | +@customElement('wokwi-membrane-keypad') |
| 6 | +export class MembraneKeypadElement extends LitElement { |
| 7 | + @property() threeColumns = false; |
| 8 | + |
| 9 | + private pressedKeys = new Set<string>(); |
| 10 | + |
| 11 | + renderKey(text: string, x: number, y: number) { |
| 12 | + return svg`<g |
| 13 | + transform="translate(${x} ${y})" |
| 14 | + tabindex="0" |
| 15 | + @mousedown=${() => this.down(text)} |
| 16 | + @mouseup=${() => this.up(text)} |
| 17 | + @touchstart=${() => this.down(text)} |
| 18 | + @touchend=${() => this.up(text)} |
| 19 | + @keydown=${(e: KeyboardEvent) => e.keyCode === SPACE_KEY && this.down(text)} |
| 20 | + @keyup=${(e: KeyboardEvent) => e.keyCode === SPACE_KEY && this.up(text)} |
| 21 | + > |
| 22 | + <use xlink:href="#key" /> |
| 23 | + <text x="5.6" y="8.1">${text}</text> |
| 24 | + </g>`; |
| 25 | + } |
| 26 | + |
| 27 | + render() { |
| 28 | + const fourColumns = !this.threeColumns; |
| 29 | + const columnWidth = 14.647; |
| 30 | + const width = fourColumns ? 70.336 : 70.336 - columnWidth; |
| 31 | + |
| 32 | + return html` |
| 33 | + <style> |
| 34 | + text { |
| 35 | + fill: #c2e4fd; |
| 36 | + user-select: none; |
| 37 | + } |
| 38 | +
|
| 39 | + g[tabindex] { |
| 40 | + cursor: pointer; |
| 41 | + } |
| 42 | +
|
| 43 | + g[tabindex]:focus { |
| 44 | + fill: #4e50d7; |
| 45 | + stroke: white; |
| 46 | + outline: none; |
| 47 | + } |
| 48 | +
|
| 49 | + g[tabindex]:focus text { |
| 50 | + fill: white; |
| 51 | + stroke: none; |
| 52 | + } |
| 53 | + </style> |
| 54 | +
|
| 55 | + <svg |
| 56 | + width="${width}mm" |
| 57 | + height="76mm" |
| 58 | + version="1.1" |
| 59 | + viewBox="0 0 ${width} 76" |
| 60 | + font-family="sans-serif" |
| 61 | + font-size="8.2px" |
| 62 | + text-anchor="middle" |
| 63 | + xmlns="http://www.w3.org/2000/svg" |
| 64 | + > |
| 65 | + <defs> |
| 66 | + <rect |
| 67 | + id="key" |
| 68 | + width="11.2" |
| 69 | + height="11" |
| 70 | + rx="1.4" |
| 71 | + ry="1.4" |
| 72 | + stroke="#b3c7db" |
| 73 | + stroke-width=".75" |
| 74 | + /> |
| 75 | + </defs> |
| 76 | +
|
| 77 | + <!-- Keypad outline --> |
| 78 | + <rect x="0" y="0" width="${width}" height="76" rx="5" ry="5" fill="#454449" /> |
| 79 | + <rect |
| 80 | + x="2.78" |
| 81 | + y="3.25" |
| 82 | + width="${fourColumns ? 65 : 65 - columnWidth}" |
| 83 | + height="68.6" |
| 84 | + rx="3.5" |
| 85 | + ry="3.5" |
| 86 | + fill="none" |
| 87 | + stroke="#b3c7db" |
| 88 | + stroke-width="1" |
| 89 | + /> |
| 90 | +
|
| 91 | + <!-- Blue keys --> |
| 92 | + <g fill="#4e90d7"> |
| 93 | + <g>${this.renderKey('1', 7, 10.7)}</g> |
| 94 | + <g>${this.renderKey('2', 22, 10.7)}</g> |
| 95 | + <g>${this.renderKey('3', 37, 10.7)}</g> |
| 96 | + <g>${this.renderKey('4', 7, 25)}</g> |
| 97 | + <g>${this.renderKey('5', 22, 25)}</g> |
| 98 | + <g>${this.renderKey('6', 37, 25)}</g> |
| 99 | + <g>${this.renderKey('7', 7, 39.3)}</g> |
| 100 | + <g>${this.renderKey('8', 22, 39.3)}</g> |
| 101 | + <g>${this.renderKey('9', 37, 39.3)}</g> |
| 102 | + <g>${this.renderKey('0', 22, 53.6)}</g> |
| 103 | + </g> |
| 104 | +
|
| 105 | + <!-- Red keys --> |
| 106 | + <g fill="#e94541"> |
| 107 | + <g>${this.renderKey('*', 7, 53.6)}</g> |
| 108 | + <g>${this.renderKey('#', 37, 53.6)}</g> |
| 109 | + ${fourColumns && |
| 110 | + svg` |
| 111 | + <g>${this.renderKey('A', 52, 10.7)}</g> |
| 112 | + <g>${this.renderKey('B', 52, 25)}</g> |
| 113 | + <g>${this.renderKey('C', 52, 39.3)}</g> |
| 114 | + <g>${this.renderKey('D', 52, 53.6)}</g> |
| 115 | + `} |
| 116 | + </g> |
| 117 | + </svg> |
| 118 | + `; |
| 119 | + } |
| 120 | + |
| 121 | + private down(key: string) { |
| 122 | + if (!this.pressedKeys.has(key)) { |
| 123 | + this.pressedKeys.add(key); |
| 124 | + this.dispatchEvent( |
| 125 | + new CustomEvent('button-press', { |
| 126 | + detail: { key } |
| 127 | + }) |
| 128 | + ); |
| 129 | + } |
| 130 | + } |
| 131 | + |
| 132 | + private up(key: string) { |
| 133 | + if (this.pressedKeys.has(key)) { |
| 134 | + this.pressedKeys.delete(key); |
| 135 | + this.dispatchEvent( |
| 136 | + new CustomEvent('button-release', { |
| 137 | + detail: { key } |
| 138 | + }) |
| 139 | + ); |
| 140 | + } |
| 141 | + } |
| 142 | +} |
0 commit comments