1*cf78ab8cSAndroid Build Coastguard Workerimport {css, html, LitElement} from 'lit'; 2*cf78ab8cSAndroid Build Coastguard Workerimport {customElement, property} from 'lit/decorators.js'; 3*cf78ab8cSAndroid Build Coastguard Worker 4*cf78ab8cSAndroid Build Coastguard Workerimport {Notifiable, SimulationInfo, simulationState,} from './device-observer.js'; 5*cf78ab8cSAndroid Build Coastguard Worker 6*cf78ab8cSAndroid Build Coastguard Worker@customElement('ns-cube-sprite') 7*cf78ab8cSAndroid Build Coastguard Workerexport class CubeSprite extends LitElement implements Notifiable { 8*cf78ab8cSAndroid Build Coastguard Worker /** 9*cf78ab8cSAndroid Build Coastguard Worker * the yaw value in orientation for ns-cube-sprite 10*cf78ab8cSAndroid Build Coastguard Worker * unit: deg 11*cf78ab8cSAndroid Build Coastguard Worker */ 12*cf78ab8cSAndroid Build Coastguard Worker @property({type: Number}) yaw = -15; 13*cf78ab8cSAndroid Build Coastguard Worker 14*cf78ab8cSAndroid Build Coastguard Worker /** 15*cf78ab8cSAndroid Build Coastguard Worker * the pitch value in orientation for ns-cube-sprite 16*cf78ab8cSAndroid Build Coastguard Worker * unit: deg 17*cf78ab8cSAndroid Build Coastguard Worker */ 18*cf78ab8cSAndroid Build Coastguard Worker @property({type: Number}) pitch = -15; 19*cf78ab8cSAndroid Build Coastguard Worker 20*cf78ab8cSAndroid Build Coastguard Worker /** 21*cf78ab8cSAndroid Build Coastguard Worker * the roll value in orientation for ns-cube-sprite 22*cf78ab8cSAndroid Build Coastguard Worker * unit: deg 23*cf78ab8cSAndroid Build Coastguard Worker */ 24*cf78ab8cSAndroid Build Coastguard Worker @property({type: Number}) roll = 0; 25*cf78ab8cSAndroid Build Coastguard Worker 26*cf78ab8cSAndroid Build Coastguard Worker /** 27*cf78ab8cSAndroid Build Coastguard Worker * the z value in position for ns-cube-sprite 28*cf78ab8cSAndroid Build Coastguard Worker * unit: cm 29*cf78ab8cSAndroid Build Coastguard Worker */ 30*cf78ab8cSAndroid Build Coastguard Worker @property({type: Number}) posZ = 0; 31*cf78ab8cSAndroid Build Coastguard Worker 32*cf78ab8cSAndroid Build Coastguard Worker /** 33*cf78ab8cSAndroid Build Coastguard Worker * the css value for color 34*cf78ab8cSAndroid Build Coastguard Worker */ 35*cf78ab8cSAndroid Build Coastguard Worker @property({type: css, attribute: 'color'}) color = css`red`; 36*cf78ab8cSAndroid Build Coastguard Worker 37*cf78ab8cSAndroid Build Coastguard Worker /** 38*cf78ab8cSAndroid Build Coastguard Worker * the css value for size 39*cf78ab8cSAndroid Build Coastguard Worker */ 40*cf78ab8cSAndroid Build Coastguard Worker @property({type: css, attribute: 'size'}) size = css`30px`; 41*cf78ab8cSAndroid Build Coastguard Worker 42*cf78ab8cSAndroid Build Coastguard Worker /** 43*cf78ab8cSAndroid Build Coastguard Worker * A Boolean property; if set true, the user would 44*cf78ab8cSAndroid Build Coastguard Worker * be able to control the cube's pitch, yaw, and roll 45*cf78ab8cSAndroid Build Coastguard Worker * with the info panel. 46*cf78ab8cSAndroid Build Coastguard Worker */ 47*cf78ab8cSAndroid Build Coastguard Worker @property({type: Boolean}) controls = false; 48*cf78ab8cSAndroid Build Coastguard Worker 49*cf78ab8cSAndroid Build Coastguard Worker /** 50*cf78ab8cSAndroid Build Coastguard Worker * A Boolean property; if set true, the box is selected 51*cf78ab8cSAndroid Build Coastguard Worker * therefore the outline gets dotted. 52*cf78ab8cSAndroid Build Coastguard Worker */ 53*cf78ab8cSAndroid Build Coastguard Worker @property({type: Boolean}) highlighted = false; 54*cf78ab8cSAndroid Build Coastguard Worker 55*cf78ab8cSAndroid Build Coastguard Worker connectedCallback() { 56*cf78ab8cSAndroid Build Coastguard Worker super.connectedCallback(); // eslint-disable-line 57*cf78ab8cSAndroid Build Coastguard Worker simulationState.registerObserver(this); 58*cf78ab8cSAndroid Build Coastguard Worker window.addEventListener('orientationEvent', this.handleOrientationEvent); 59*cf78ab8cSAndroid Build Coastguard Worker } 60*cf78ab8cSAndroid Build Coastguard Worker 61*cf78ab8cSAndroid Build Coastguard Worker disconnectedCallback() { 62*cf78ab8cSAndroid Build Coastguard Worker window.removeEventListener('orientationEvent', this.handleOrientationEvent); 63*cf78ab8cSAndroid Build Coastguard Worker simulationState.removeObserver(this); 64*cf78ab8cSAndroid Build Coastguard Worker super.disconnectedCallback(); // eslint-disable-line 65*cf78ab8cSAndroid Build Coastguard Worker } 66*cf78ab8cSAndroid Build Coastguard Worker 67*cf78ab8cSAndroid Build Coastguard Worker onNotify(data: SimulationInfo) { 68*cf78ab8cSAndroid Build Coastguard Worker this.highlighted = data.selectedId === this.id; 69*cf78ab8cSAndroid Build Coastguard Worker for (const device of data.devices) { 70*cf78ab8cSAndroid Build Coastguard Worker if (device.name === this.id) { 71*cf78ab8cSAndroid Build Coastguard Worker this.posZ = device.position.z * 100; 72*cf78ab8cSAndroid Build Coastguard Worker return; 73*cf78ab8cSAndroid Build Coastguard Worker } 74*cf78ab8cSAndroid Build Coastguard Worker } 75*cf78ab8cSAndroid Build Coastguard Worker } 76*cf78ab8cSAndroid Build Coastguard Worker 77*cf78ab8cSAndroid Build Coastguard Worker static styles = css` 78*cf78ab8cSAndroid Build Coastguard Worker :host { 79*cf78ab8cSAndroid Build Coastguard Worker /** all sizes are relative to font-size **/ 80*cf78ab8cSAndroid Build Coastguard Worker display: block; 81*cf78ab8cSAndroid Build Coastguard Worker min-height: 1.5em; 82*cf78ab8cSAndroid Build Coastguard Worker min-width: 1.5em; 83*cf78ab8cSAndroid Build Coastguard Worker width: 1em; 84*cf78ab8cSAndroid Build Coastguard Worker /* overflow: hidden; */ 85*cf78ab8cSAndroid Build Coastguard Worker transform-origin: center; 86*cf78ab8cSAndroid Build Coastguard Worker transform-style: preserve-3d; 87*cf78ab8cSAndroid Build Coastguard Worker transform: translateZ(calc(var(--posZ) * 1px)); 88*cf78ab8cSAndroid Build Coastguard Worker cursor: move; 89*cf78ab8cSAndroid Build Coastguard Worker } 90*cf78ab8cSAndroid Build Coastguard Worker 91*cf78ab8cSAndroid Build Coastguard Worker .cube { 92*cf78ab8cSAndroid Build Coastguard Worker transform-style: preserve-3d; 93*cf78ab8cSAndroid Build Coastguard Worker transform: rotateX(calc(var(--yaw) * 1deg)) 94*cf78ab8cSAndroid Build Coastguard Worker rotateY(calc(var(--pitch) * 1deg)) rotateZ(calc(var(--roll) * 1deg)); 95*cf78ab8cSAndroid Build Coastguard Worker position: absolute; 96*cf78ab8cSAndroid Build Coastguard Worker left: 0.25em; 97*cf78ab8cSAndroid Build Coastguard Worker bottom: 0.25em; 98*cf78ab8cSAndroid Build Coastguard Worker width: 1em; 99*cf78ab8cSAndroid Build Coastguard Worker height: 1em; 100*cf78ab8cSAndroid Build Coastguard Worker } 101*cf78ab8cSAndroid Build Coastguard Worker .cube > div { 102*cf78ab8cSAndroid Build Coastguard Worker position: absolute; 103*cf78ab8cSAndroid Build Coastguard Worker background-color: var(--color); 104*cf78ab8cSAndroid Build Coastguard Worker width: 100%; 105*cf78ab8cSAndroid Build Coastguard Worker height: 100%; 106*cf78ab8cSAndroid Build Coastguard Worker box-shadow: 0 0 0.25em #000 inset; 107*cf78ab8cSAndroid Build Coastguard Worker } 108*cf78ab8cSAndroid Build Coastguard Worker .cube > div:nth-child(1) { 109*cf78ab8cSAndroid Build Coastguard Worker transform: translateZ(0.5em); 110*cf78ab8cSAndroid Build Coastguard Worker } 111*cf78ab8cSAndroid Build Coastguard Worker .cube > div:nth-child(2) { 112*cf78ab8cSAndroid Build Coastguard Worker transform: rotateY(180deg) translateZ(0.5em); 113*cf78ab8cSAndroid Build Coastguard Worker } 114*cf78ab8cSAndroid Build Coastguard Worker .cube > div:nth-child(3) { 115*cf78ab8cSAndroid Build Coastguard Worker right: 0; 116*cf78ab8cSAndroid Build Coastguard Worker width: 1em; 117*cf78ab8cSAndroid Build Coastguard Worker transform: rotateY(90deg) translateZ(0.5em); 118*cf78ab8cSAndroid Build Coastguard Worker } 119*cf78ab8cSAndroid Build Coastguard Worker .cube > div:nth-child(4) { 120*cf78ab8cSAndroid Build Coastguard Worker width: 1em; 121*cf78ab8cSAndroid Build Coastguard Worker transform: rotateY(270deg) translateZ(0.5em); 122*cf78ab8cSAndroid Build Coastguard Worker } 123*cf78ab8cSAndroid Build Coastguard Worker .cube > div:nth-child(5) { 124*cf78ab8cSAndroid Build Coastguard Worker bottom: -0.5em; 125*cf78ab8cSAndroid Build Coastguard Worker height: 1em; 126*cf78ab8cSAndroid Build Coastguard Worker transform: rotateX(90deg); 127*cf78ab8cSAndroid Build Coastguard Worker box-shadow: 0 0 0.25em #000 inset, 0 0 0.25em #000; 128*cf78ab8cSAndroid Build Coastguard Worker } 129*cf78ab8cSAndroid Build Coastguard Worker .cube div:nth-child(6) { 130*cf78ab8cSAndroid Build Coastguard Worker height: 1em; 131*cf78ab8cSAndroid Build Coastguard Worker transform: translateY(-0.5em) rotateX(90deg); 132*cf78ab8cSAndroid Build Coastguard Worker overflow: hidden; 133*cf78ab8cSAndroid Build Coastguard Worker } 134*cf78ab8cSAndroid Build Coastguard Worker 135*cf78ab8cSAndroid Build Coastguard Worker .line { 136*cf78ab8cSAndroid Build Coastguard Worker position: absolute; 137*cf78ab8cSAndroid Build Coastguard Worker border-bottom: 5px dashed; 138*cf78ab8cSAndroid Build Coastguard Worker width: calc(var(--posZ) * 1px); 139*cf78ab8cSAndroid Build Coastguard Worker top: 50%; 140*cf78ab8cSAndroid Build Coastguard Worker left: 50%; 141*cf78ab8cSAndroid Build Coastguard Worker transform: rotateY(90deg) rotateX(90deg); 142*cf78ab8cSAndroid Build Coastguard Worker transform-origin: left; 143*cf78ab8cSAndroid Build Coastguard Worker } 144*cf78ab8cSAndroid Build Coastguard Worker 145*cf78ab8cSAndroid Build Coastguard Worker .base { 146*cf78ab8cSAndroid Build Coastguard Worker position: absolute; 147*cf78ab8cSAndroid Build Coastguard Worker border: 5px solid; 148*cf78ab8cSAndroid Build Coastguard Worker border-radius: 50%; 149*cf78ab8cSAndroid Build Coastguard Worker background-color: black; 150*cf78ab8cSAndroid Build Coastguard Worker height: 5px; 151*cf78ab8cSAndroid Build Coastguard Worker width: 5px; 152*cf78ab8cSAndroid Build Coastguard Worker top: 50%; 153*cf78ab8cSAndroid Build Coastguard Worker left: 50%; 154*cf78ab8cSAndroid Build Coastguard Worker transform: translate3d(-50%, -50%, calc(var(--posZ) * -1px)); 155*cf78ab8cSAndroid Build Coastguard Worker } 156*cf78ab8cSAndroid Build Coastguard Worker `; 157*cf78ab8cSAndroid Build Coastguard Worker 158*cf78ab8cSAndroid Build Coastguard Worker private handleOrientationEvent = (e: Event) => { 159*cf78ab8cSAndroid Build Coastguard Worker const {detail} = e as CustomEvent; 160*cf78ab8cSAndroid Build Coastguard Worker if (detail.name === this.id && this.controls) { 161*cf78ab8cSAndroid Build Coastguard Worker if (detail.type === 'yaw') { 162*cf78ab8cSAndroid Build Coastguard Worker this.yaw = detail.value; 163*cf78ab8cSAndroid Build Coastguard Worker } else if (detail.type === 'pitch') { 164*cf78ab8cSAndroid Build Coastguard Worker this.pitch = detail.value; 165*cf78ab8cSAndroid Build Coastguard Worker } else { 166*cf78ab8cSAndroid Build Coastguard Worker this.roll = detail.value; 167*cf78ab8cSAndroid Build Coastguard Worker } 168*cf78ab8cSAndroid Build Coastguard Worker } 169*cf78ab8cSAndroid Build Coastguard Worker }; 170*cf78ab8cSAndroid Build Coastguard Worker 171*cf78ab8cSAndroid Build Coastguard Worker render() { 172*cf78ab8cSAndroid Build Coastguard Worker // TODO(b/255635486): Make cube easily scalable with user input size 173*cf78ab8cSAndroid Build Coastguard Worker return html` 174*cf78ab8cSAndroid Build Coastguard Worker <style> 175*cf78ab8cSAndroid Build Coastguard Worker :host { 176*cf78ab8cSAndroid Build Coastguard Worker font-size: ${this.size}; 177*cf78ab8cSAndroid Build Coastguard Worker --color: ${this.color}; 178*cf78ab8cSAndroid Build Coastguard Worker --yaw: ${this.yaw}; 179*cf78ab8cSAndroid Build Coastguard Worker --pitch: ${this.pitch}; 180*cf78ab8cSAndroid Build Coastguard Worker --roll: ${this.roll}; 181*cf78ab8cSAndroid Build Coastguard Worker --posZ: ${this.controls ? this.posZ : 0}; 182*cf78ab8cSAndroid Build Coastguard Worker } 183*cf78ab8cSAndroid Build Coastguard Worker .cube > div { 184*cf78ab8cSAndroid Build Coastguard Worker outline: ${this.highlighted && this.controls ? css`dashed` : css``}; 185*cf78ab8cSAndroid Build Coastguard Worker } 186*cf78ab8cSAndroid Build Coastguard Worker </style> 187*cf78ab8cSAndroid Build Coastguard Worker <div class="cube"> 188*cf78ab8cSAndroid Build Coastguard Worker <div></div> 189*cf78ab8cSAndroid Build Coastguard Worker <div></div> 190*cf78ab8cSAndroid Build Coastguard Worker <div></div> 191*cf78ab8cSAndroid Build Coastguard Worker <div></div> 192*cf78ab8cSAndroid Build Coastguard Worker <div></div> 193*cf78ab8cSAndroid Build Coastguard Worker <div></div> 194*cf78ab8cSAndroid Build Coastguard Worker </div> 195*cf78ab8cSAndroid Build Coastguard Worker ${ 196*cf78ab8cSAndroid Build Coastguard Worker this.controls ? html` 197*cf78ab8cSAndroid Build Coastguard Worker <div class="line"></div> 198*cf78ab8cSAndroid Build Coastguard Worker <div class="base"></div> 199*cf78ab8cSAndroid Build Coastguard Worker ` : 200*cf78ab8cSAndroid Build Coastguard Worker html``} 201*cf78ab8cSAndroid Build Coastguard Worker `; 202*cf78ab8cSAndroid Build Coastguard Worker } 203*cf78ab8cSAndroid Build Coastguard Worker} 204