• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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