1// Copyright 2022 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15import { LitElement, html, css, unsafeCSS } from "lit";
16
17import { PROJECTION } from "./Map.js";
18
19export class Orientation extends LitElement {
20  static styles = css`
21    :host {
22      transform-style: preserve-3d;
23      transform: ${unsafeCSS(PROJECTION.toString())};
24      perspective-origin: center;
25      display: flex;
26      position: relative;
27    }
28
29    .axis {
30      position: absolute;
31      left: 50%;
32      width: 3px;
33      height: 50%;
34      transform-origin: bottom center;
35      background: currentColor;
36    }
37
38    .z {
39      color: blue;
40    }
41
42    .x {
43      color: green;
44    }
45
46    .y {
47      color: red;
48    }
49
50    .circle {
51      position: absolute;
52      left: 17.5%;
53      top: 17.5%;
54      height: 65%;
55      width: 65%;
56      opacity: 0.3;
57    }
58
59    .value {
60      color: yellow;
61    }
62
63    .arrow::after {
64      content: "";
65      display: block;
66      border-left: 2px solid currentColor;
67      border-top: 2px solid currentColor;
68      width: 10px;
69      height: 10px;
70      transform: rotate(45deg) translate(0, -2px);
71      transform-origin: top left;
72    }
73  `;
74
75  static properties = {
76    yaw: { type: Number },
77    pitch: { type: Number },
78    roll: { type: Number },
79  };
80
81  constructor() {
82    super();
83    this.yaw = 0;
84    this.pitch = 0;
85    this.roll = 0;
86  }
87
88  render() {
89    const a = (0.5 / Math.PI) * 360 * 4;
90
91    const { yaw, pitch } = this;
92
93    return html`
94      <div class="axis arrow x" style="transform: rotateZ(-180deg)"></div>
95      <div class="axis arrow y" style="transform: rotateZ(-90deg)"></div>
96      <div class="axis arrow z" style="transform: rotateX(-90deg)"></div>
97      <svg
98        viewBox="${-a / 2} ${-a / 2} ${a} ${a}"
99        class="circle"
100        style="transform: rotateZ(90deg) rotateX(${yaw < 0 ? 0 : 180}deg)"
101      >
102        <circle
103          r="${a / 4}"
104          stroke-width="${a / 2}"
105          stroke-dasharray="${Math.abs(yaw)} 360"
106          stroke="blue"
107          fill="none"
108        />
109      </svg>
110      <svg
111        viewBox="${-a / 2} ${-a / 2} ${a} ${a}"
112        class="circle"
113        style="transform: rotateZ(${90 - yaw}deg) rotateX(${Math.sign(pitch) *
114        90}deg)"
115      >
116        <circle
117          r="${a / 4}"
118          stroke-width="${a / 2}"
119          stroke-dasharray="${Math.abs(pitch)} 360"
120          stroke="red"
121          fill="none"
122        />
123      </svg>
124      <div
125        class="axis value"
126        style="transform: rotateZ(${180 -
127        yaw}deg) rotateX(${-pitch}deg) rotateY(90deg)"
128      ></div>
129      <div
130        class="axis value"
131        style="transform: rotateZ(${180 - yaw}deg) rotateX(${-pitch}deg)"
132      ></div>
133    `;
134  }
135}
136customElements.define("pika-orientation", Orientation);
137