|
| 1 | +import { customElement, html, LitElement, property } from 'lit-element'; |
| 2 | +import { ElementPin } from '.'; |
| 3 | + |
| 4 | +@customElement('wokwi-rgb-led') |
| 5 | +export class RGBLedElement extends LitElement { |
| 6 | + @property() ledRed = 0; |
| 7 | + @property() ledGreen = 0; |
| 8 | + @property() ledBlue = 0; |
| 9 | + |
| 10 | + readonly pinInfo: ElementPin[] = [ |
| 11 | + { name: 'R', x: 8.5, y: 44, signals: [] }, |
| 12 | + { name: 'COM', x: 17.5, y: 54, signals: [] }, |
| 13 | + { name: 'G', x: 26.4, y: 48, signals: [] }, |
| 14 | + { name: 'B', x: 35.7, y: 43, signals: [] }, |
| 15 | + ]; |
| 16 | + |
| 17 | + render() { |
| 18 | + const { ledRed, ledGreen, ledBlue } = this; |
| 19 | + const brightness = Math.max(ledRed, ledGreen, ledBlue); |
| 20 | + const opacity = brightness ? 0.2 + brightness * 0.6 : 0; |
| 21 | + |
| 22 | + return html` |
| 23 | + <?xml version="1.0" encoding="UTF-8"?> |
| 24 | + <svg |
| 25 | + width="42.129" |
| 26 | + height="72.582" |
| 27 | + version="1.2" |
| 28 | + viewBox="-17 -10 37.3425 57.5115" |
| 29 | + xmlns="http://www.w3.org/2000/svg" |
| 30 | + > |
| 31 | + <!-- LED Legs --> |
| 32 | + <g fill="none" stroke="#9D9999" stroke-linecap="round" stroke-width=".89px"> |
| 33 | + <path d="m3.3863 15.334 3.0611 13.971" /> |
| 34 | + <path d="m7.2753 13.972 5.9987 4.0518 1.1777 6.5679" stroke-linejoin="round" /> |
| 35 | + <path d="m-4.3793 14.184-5.0755 5.6592-0.10206 6.1694" stroke-linejoin="round" /> |
| 36 | + <path d="m-1.1952 15.607-0.33725 19.49" /> |
| 37 | + </g> |
| 38 | +
|
| 39 | + <!-- LED Body --> |
| 40 | + <path |
| 41 | + d="m8.3435 5.65v-5.9126c0-3.9132-3.168-7.0884-7.0855-7.0884-3.9125 0-7.0877 3.1694-7.0877 7.0884v13.649c1.4738 1.651 4.0968 2.7526 7.0877 2.7526 4.6195 0 8.3686-2.6179 8.3686-5.8594v-1.5235c-7.4e-4 -1.1426-0.47444-2.2039-1.283-3.1061z" |
| 42 | + opacity=".3" |
| 43 | + /> |
| 44 | + <path |
| 45 | + d="m8.3435 5.65v-5.9126c0-3.9132-3.168-7.0884-7.0855-7.0884-3.9125 0-7.0877 3.1694-7.0877 7.0884v13.649c1.4738 1.651 4.0968 2.7526 7.0877 2.7526 4.6195 0 8.3686-2.6179 8.3686-5.8594v-1.5235c-7.4e-4 -1.1426-0.47444-2.2039-1.283-3.1061z" |
| 46 | + fill="#e6e6e6" |
| 47 | + opacity=".5" |
| 48 | + /> |
| 49 | + <path |
| 50 | + d="m8.3435 5.65v3.1054c0 2.7389-3.1658 4.9651-7.0855 4.9651-3.9125 2e-5 -7.0877-2.219-7.0877-4.9651v4.6296c1.4738 1.6517 4.0968 2.7526 7.0877 2.7526 4.6195 0 8.3686-2.6179 8.3686-5.8586l-4e-5 -1.5235c-7e-4 -1.1419-0.4744-2.2032-1.283-3.1054z" |
| 51 | + fill="#d1d1d1" |
| 52 | + opacity=".9" |
| 53 | + /> |
| 54 | + <g transform="translate(-5.8295 -7.351)"> |
| 55 | + <path |
| 56 | + d="m14.173 13.001v3.1054c0 2.7389-3.1658 4.9651-7.0855 4.9651-3.9125 2e-5 -7.0877-2.219-7.0877-4.9651v4.6296c1.4738 1.6517 4.0968 2.7526 7.0877 2.7526 4.6195 0 8.3686-2.6179 8.3686-5.8586l-4e-5 -1.5235c-7e-4 -1.1419-0.4744-2.2032-1.283-3.1054z" |
| 57 | + opacity=".7" |
| 58 | + /> |
| 59 | + <path |
| 60 | + d="m14.173 13.001v3.1054c0 2.7389-3.1658 4.9651-7.0855 4.9651-3.9125 2e-5 -7.0877-2.219-7.0877-4.9651v3.1054c1.4738 1.6502 4.0968 2.7526 7.0877 2.7526 4.6195 0 8.3686-2.6179 8.3686-5.8586-7.4e-4 -1.1412-0.47444-2.2025-1.283-3.1047z" |
| 61 | + opacity=".25" |
| 62 | + /> |
| 63 | + <ellipse cx="7.0877" cy="16.106" rx="7.087" ry="4.9608" opacity=".25" /> |
| 64 | + </g> |
| 65 | + <polygon |
| 66 | + transform="translate(-5.8295 -7.351)" |
| 67 | + points="3.1961 13.095 6.0156 13.095 10.012 8.8049 3.407 8.8049 2.2032 9.648 2.2032 16.107 3.1961 16.107" |
| 68 | + fill="#666" |
| 69 | + /> |
| 70 | + <polygon |
| 71 | + transform="translate(-5.8295 -7.351)" |
| 72 | + points="11.06 13.095 11.06 16.107 11.974 16.107 11.974 8.5241 10.778 8.5241 11.215 9.0338 7.4117 13.095" |
| 73 | + fill="#666" |
| 74 | + /> |
| 75 | + <path |
| 76 | + d="m8.3435 5.65v-5.9126c0-3.9132-3.168-7.0884-7.0855-7.0884-3.9125 0-7.0877 3.1694-7.0877 7.0884v13.649c1.4738 1.651 4.0968 2.7526 7.0877 2.7526 4.6195 0 8.3686-2.6179 8.3686-5.8594v-1.5235c-7.4e-4 -1.1426-0.47444-2.2039-1.283-3.1061z" |
| 77 | + fill="white" |
| 78 | + opacity=".65" |
| 79 | + /> |
| 80 | + <g transform="translate(-5.8295 -7.351)" fill="#fff"> |
| 81 | + <path |
| 82 | + d="m10.388 3.7541 1.4364-0.2736c-0.84168-1.1318-2.0822-1.9577-3.5417-2.2385l0.25416 1.0807c0.76388 0.27072 1.4068 0.78048 1.8511 1.4314z" |
| 83 | + opacity=".5" |
| 84 | + /> |
| 85 | + <path |
| 86 | + d="m0.76824 19.926v1.5199c0.64872 0.5292 1.4335 0.97632 2.3076 1.3169v-1.525c-0.8784-0.33624-1.6567-0.78194-2.3076-1.3118z" |
| 87 | + opacity=".5" |
| 88 | + /> |
| 89 | + <path |
| 90 | + d="m11.073 20.21c-0.2556 0.1224-0.52992 0.22968-0.80568 0.32976-0.05832 0.01944-0.11736 0.04032-0.17784 0.05832-0.56376 0.17928-1.1614 0.31896-1.795 0.39456-0.07488 0.0094-0.1512 0.01872-0.22464 0.01944-0.3204 0.03024-0.64368 0.05832-0.97056 0.05832-0.14832 0-0.30744-0.01512-0.4716-0.02376-1.2002-0.05688-2.3306-0.31464-3.2976-0.73944l-2e-5 -8.3895v-4.8254c0-1.471 0.84816-2.7295 2.0736-3.3494l-0.02232-0.05328-1.2478-1.512c-1.6697 1.003-2.79 2.8224-2.79 4.9118v11.905c-0.04968-0.04968-0.30816-0.30888-0.48024-0.52992l-0.30744 0.6876c1.4011 1.4818 3.8088 2.4617 6.5426 2.4617 1.6798 0 3.2371-0.37368 4.5115-1.0022l-0.52704-0.40896-0.01006 0.0072z" |
| 91 | + opacity=".5" |
| 92 | + /> |
| 93 | + </g> |
| 94 | +
|
| 95 | + <filter id="ledFilter" x="-0.8" y="-0.8" height="5.2" width="5.8"> |
| 96 | + <feGaussianBlur stdDeviation="4" /> |
| 97 | + </filter> |
| 98 | + <filter id="ledFilterRed" x="-0.8" y="-0.8" height="5.2" width="5.8"> |
| 99 | + <feGaussianBlur stdDeviation="${ledRed * 3}" /> |
| 100 | + </filter> |
| 101 | + <filter id="ledFilterGreen" x="-0.8" y="-0.8" height="5.2" width="5.8"> |
| 102 | + <feGaussianBlur stdDeviation="${ledGreen * 3}" /> |
| 103 | + </filter> |
| 104 | + <filter id="ledFilterBlue" x="-0.8" y="-0.8" height="5.2" width="5.8"> |
| 105 | + <feGaussianBlur stdDeviation="${ledBlue * 3}" /> |
| 106 | + </filter> |
| 107 | +
|
| 108 | + <circle |
| 109 | + cx="1.7" |
| 110 | + cy="3" |
| 111 | + r="${ledRed * 5 + 2}" |
| 112 | + fill="rgb(255, 0, 0)" |
| 113 | + opacity="${Math.min(ledRed * 20, 0.3)}" |
| 114 | + filter="url(#ledFilterRed)" |
| 115 | + /> |
| 116 | + <circle |
| 117 | + cx="2.7" |
| 118 | + cy="5" |
| 119 | + r="${ledGreen * 5 + 2}" |
| 120 | + fill="rgb(0, 255, 0)" |
| 121 | + opacity="${Math.min(ledGreen * 20, 0.3)}" |
| 122 | + filter="url(#ledFilterGreen)" |
| 123 | + /> |
| 124 | + <circle |
| 125 | + cx="0.7" |
| 126 | + cy="5" |
| 127 | + r="${ledBlue * 5 + 2}" |
| 128 | + fill="rgb(1,85,253)" |
| 129 | + opacity="${Math.min(ledBlue * 20, 0.3)}" |
| 130 | + filter="url(#ledFilterBlue)" |
| 131 | + /> |
| 132 | +
|
| 133 | + <circle |
| 134 | + cx="1.7" |
| 135 | + cy="4" |
| 136 | + r="10" |
| 137 | + fill="rgb(${ledRed * 255}, ${ledGreen * 255 + ledBlue * 90}, ${ledBlue * 255})" |
| 138 | + filter="url(#ledFilter)" |
| 139 | + opacity="${opacity}" |
| 140 | + /> |
| 141 | +
|
| 142 | + <!-- Grey hollow around the LED --> |
| 143 | + <circle |
| 144 | + cx="1.7" |
| 145 | + cy="4" |
| 146 | + r="13" |
| 147 | + stroke="#666" |
| 148 | + stroke-width="1" |
| 149 | + fill="none" |
| 150 | + filter="url(#ledFilter)" |
| 151 | + opacity="${opacity}" |
| 152 | + /> |
| 153 | + </svg> |
| 154 | + `; |
| 155 | + } |
| 156 | +} |
0 commit comments