1import {css, html, LitElement} from 'lit'; 2import {customElement, property} from 'lit/decorators.js'; 3import {styleMap} from 'lit/directives/style-map.js'; 4 5import {Device, Notifiable, SimulationInfo, simulationState,} from './device-observer.js'; 6 7@customElement('ns-device-map') 8export class DeviceMap extends LitElement implements Notifiable { 9 /** 10 * List of devices currently on the netsim. 11 */ 12 @property() deviceData: Device[] = []; 13 14 /** 15 * Index of the background image displayed. 16 */ 17 @property() imageIdx = 0; 18 19 /** 20 * Number of images available for the background. 21 */ 22 @property() numImages = 3; 23 24 @property({type: Boolean, reflect: true}) isometric: boolean = false; 25 26 connectedCallback() { 27 super.connectedCallback(); // eslint-disable-line 28 simulationState.registerObserver(this); 29 window.addEventListener('map-button-clicked', this.onChangeMap); 30 window.addEventListener( 31 'isometric-button-clicked', this.handleIsometricView); 32 } 33 34 disconnectedCallback() { 35 window.removeEventListener( 36 'isometric-button-clicked', this.handleIsometricView); 37 window.removeEventListener('map-button-clicked', this.onChangeMap); 38 simulationState.removeObserver(this); 39 super.disconnectedCallback(); // eslint-disable-line 40 } 41 42 static styles = css` 43 #dropzone { 44 margin-left: 200px; 45 margin-right: 200px; 46 transition: transform 2s, top 2s; 47 transform-style: preserve-3d; 48 } 49 50 .box { 51 position: relative; 52 width: 1000px; //40vw; 53 height: 1000px; //40vh; 54 border: solid 1px rgb(198, 210, 255); 55 margin: 2.5em auto; 56 } 57 58 .pattern0 { 59 background-image: url(./assets/grid-background.svg); 60 } 61 62 .pattern1 { 63 background-image: url(./assets/polar-background.svg); 64 background-size: 1150px 1150px; 65 background-position: center; 66 } 67 68 .pattern2 { 69 background-image: url(./assets/hexagonal-background.png); 70 background-size: 1175px 1175px; 71 background-position: center; 72 } 73 74 .container { 75 display: flex; 76 width: 100%; 77 } 78 79 .contentA { 80 flex: 2; 81 } 82 83 .contentB { 84 flex: 2; 85 } 86 87 ns-device-dragzone { 88 transform-style: inherit; 89 } 90 `; 91 92 onNotify(data: SimulationInfo): void { 93 this.deviceData = data.devices; 94 this.requestUpdate(); 95 } 96 97 private onChangeMap = () => { 98 this.imageIdx = (this.imageIdx + 1) % this.numImages; 99 }; 100 101 private handleIsometricView = () => { 102 this.isometric = !this.isometric; 103 }; 104 105 render() { 106 const rainbow = [ 107 'red', 108 'orange', 109 'yellow', 110 'green', 111 'blue', 112 'indigo', 113 'purple', 114 ]; 115 const viewStyle = this.isometric ? 116 `perspective(200rem) rotateX(60deg) rotateY(0deg) rotateZ(0deg) scale3d(0.8,0.8,0.8); top: 250px` : 117 'none; top: 0px;'; 118 119 return html` 120 <ns-device-dropzone role="widget" tabindex="0" aria-label="Device map"> 121 <div id="dropzone" class="box pattern${this.imageIdx}"> 122 ${ 123 this.deviceData.map( 124 (device, idx) => html` 125 ${ 126 device.visible === true ? 127 html` 128 <ns-device-dragzone 129 .action=${'move'} 130 style=${styleMap({ 131 position: 'absolute', 132 left: `${device.position.x * 100}px`, 133 top: `${device.position.y * 100}px`, 134 })} 135 > 136 <ns-cube-sprite 137 id=${device.name} 138 .color=${rainbow[idx % rainbow.length]} 139 .size=${'30px'} 140 .controls=${true} 141 yaw=${device.orientation.yaw} 142 pitch=${device.orientation.pitch} 143 roll=${device.orientation.roll} 144 posZ=${device.position.z * 100} 145 role="widget" 146 tabindex="1" 147 aria-label="${device.name} on Device Map, Position: ${ 148 Math.round(device.position.x * 100)}, ${ 149 Math.round(device.position.y * 100)}, ${ 150 Math.round( 151 device.position.z * 100)}, Orientation: yaw: ${ 152 device.orientation.yaw}, pitch: ${ 153 device.orientation.pitch}, roll: ${ 154 device.orientation.roll}" 155 aria-live="polite" 156 ></ns-cube-sprite> 157 </ns-device-dragzone> 158 ` : 159 html``} 160 `)} 161 </div> 162 <style> 163 #dropzone { 164 transform: ${viewStyle}; 165 } 166 </style> 167 </ns-device-dropzone> 168 `; 169 } 170} 171