diff --git a/src/plugins/imagery/ImageryViewProvider.js b/src/plugins/imagery/ImageryViewProvider.js index aeb7555d77..1419990027 100644 --- a/src/plugins/imagery/ImageryViewProvider.js +++ b/src/plugins/imagery/ImageryViewProvider.js @@ -1,3 +1,25 @@ +/***************************************************************************** + * Open MCT, Copyright (c) 2014-2021, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ + import ImageryViewLayout from './components/ImageryViewLayout.vue'; import Vue from 'vue'; diff --git a/src/plugins/imagery/components/Compass/Compass.vue b/src/plugins/imagery/components/Compass/Compass.vue new file mode 100644 index 0000000000..9080b38b84 --- /dev/null +++ b/src/plugins/imagery/components/Compass/Compass.vue @@ -0,0 +1,131 @@ +/***************************************************************************** + * Open MCT, Copyright (c) 2014-2021, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ + + + + diff --git a/src/plugins/imagery/components/Compass/CompassHUD.vue b/src/plugins/imagery/components/Compass/CompassHUD.vue new file mode 100644 index 0000000000..b3a66e090f --- /dev/null +++ b/src/plugins/imagery/components/Compass/CompassHUD.vue @@ -0,0 +1,145 @@ +/***************************************************************************** + * Open MCT, Copyright (c) 2014-2021, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ + + + + diff --git a/src/plugins/imagery/components/Compass/CompassRose.vue b/src/plugins/imagery/components/Compass/CompassRose.vue new file mode 100644 index 0000000000..3a09db17c9 --- /dev/null +++ b/src/plugins/imagery/components/Compass/CompassRose.vue @@ -0,0 +1,263 @@ +/***************************************************************************** + * Open MCT, Copyright (c) 2014-2021, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ + + + + diff --git a/src/plugins/imagery/components/Compass/compass.scss b/src/plugins/imagery/components/Compass/compass.scss new file mode 100644 index 0000000000..424d0b2fca --- /dev/null +++ b/src/plugins/imagery/components/Compass/compass.scss @@ -0,0 +1,214 @@ +/***************************** THEME/UI CONSTANTS AND MIXINS */ +$interfaceKeyColor: #00B9C5; +$elemBg: rgba(black, 0.7); + +@mixin sun($position: 'circle closest-side') { + $color: #ff9900; + $gradEdgePerc: 60%; + background: radial-gradient(#{$position}, $color, $color $gradEdgePerc, rgba($color, 0.4) $gradEdgePerc + 5%, transparent); + +} + +.c-compass { + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + z-index: 1; + @include userSelectNone; +} + +/***************************** COMPASS HUD */ +.c-hud { + // To be placed within a imagery view, in the bounding box of the image + $m: 1px; + $padTB: 2px; + $padLR: $padTB; + color: $interfaceKeyColor; + font-size: 0.8em; + position: absolute; + top: $m; right: $m; left: $m; + height: 18px; + + svg, div { + position: absolute; + } + + &__display { + height: 30px; + pointer-events: all; + position: absolute; + top: 0; + right: 0; + left: 0; + } + + &__range { + border: 1px solid $interfaceKeyColor; + border-top-color: transparent; + position: absolute; + top: 50%; right: $padLR; bottom: $padTB; left: $padLR; + } + + [class*="__dir"] { + // NSEW + display: inline-block; + font-weight: bold; + text-shadow: 0 1px 2px black; + top: 50%; + transform: translate(-50%,-50%); + z-index: 2; + } + + [class*="__dir--sub"] { + font-weight: normal; + opacity: 0.5; + } + + &__sun { + $s: 10px; + @include sun('circle farthest-side at bottom'); + bottom: $padTB + 2px; + height: $s; width: $s*2; + opacity: 0.8; + transform: translateX(-50%); + z-index: 1; + } + +} + +/***************************** COMPASS DIRECTIONS */ +.c-nsew { + $color: $interfaceKeyColor; + $inset: 7%; + $tickHeightPerc: 15%; + text-shadow: black 0 0 10px; + top: $inset; right: $inset; bottom: $inset; left: $inset; + z-index: 3; + + &__tick, + &__label { + fill: $color; + } + + &__minor-ticks { + opacity: 0.5; + transform-origin: center; + transform: rotate(45deg); + } + + &__label { + dominant-baseline: central; + font-size: 0.8em; + font-weight: bold; + } + + .c-label-n { + font-size: 1.1em; + } +} + +/***************************** CAMERA FIELD ANGLE */ +.c-cam-field { + $color: white; + opacity: 0.2; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 2; + + .cam-field-half { + top: 0; + right: 0; + bottom: 0; + left: 0; + + .cam-field-area { + background: $color; + top: -30%; + right: 0; + bottom: -30%; + left: 0; + } + + // clip-paths overlap a bit to avoid a gap between halves + &-l { + clip-path: polygon(0 0, 50.5% 0, 50.5% 100%, 0 100%); + .cam-field-area { + transform-origin: left center; + } + } + + &-r { + clip-path: polygon(49.5% 0, 100% 0, 100% 100%, 49.5% 100%); + .cam-field-area { + transform-origin: right center; + } + } + } +} + +/***************************** SPACECRAFT BODY */ +.c-spacecraft-body { + $color: $interfaceKeyColor; + $s: 30%; + background: $color; + border-radius: 3px; + height: $s; width: $s; + left: 50%; top: 50%; + opacity: 0.4; + transform-origin: center top; + + &:before { + // Direction arrow + $color: rgba(black, 0.5); + $arwPointerY: 60%; + $arwBodyOffset: 25%; + background: $color; + content: ''; + display: block; + position: absolute; + top: 10%; right: 20%; bottom: 50%; left: 20%; + clip-path: polygon(50% 0, 100% $arwPointerY, 100%-$arwBodyOffset $arwPointerY, 100%-$arwBodyOffset 100%, $arwBodyOffset 100%, $arwBodyOffset $arwPointerY, 0 $arwPointerY); + } +} + +/***************************** DIRECTION ROSE */ +.c-direction-rose { + $d: 100px; + $c2: rgba(white, 0.1); + background: $elemBg; + background-image: radial-gradient(circle closest-side, transparent, transparent 80%, $c2); + width: $d; + height: $d; + transform-origin: 0 0; + position: absolute; + bottom: 10px; left: 10px; + clip-path: circle(50% at 50% 50%); + border-radius: 100%; + + svg, div { + position: absolute; + } + + // Sun + .c-sun { + top: 0; + right: 0; + bottom: 0; + left: 0; + + &:before { + $s: 35%; + @include sun(); + content: ''; + display: block; + position: absolute; + opacity: 0.7; + top: 0; left: 50%; + height:$s; width: $s; + transform: translate(-50%, -60%); + } + } +} diff --git a/src/plugins/imagery/components/Compass/pluginSpec.js b/src/plugins/imagery/components/Compass/pluginSpec.js new file mode 100644 index 0000000000..72b7d53b4d --- /dev/null +++ b/src/plugins/imagery/components/Compass/pluginSpec.js @@ -0,0 +1,84 @@ +/***************************************************************************** + * Open MCT, Copyright (c) 2014-2020, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ +import Compass from './Compass.vue'; +import Vue from 'vue'; + +const COMPASS_ROSE_CLASS = '.c-direction-rose'; +const COMPASS_HUD_CLASS = '.c-compass__hud'; + +describe("The Compass component", () => { + let app; + let instance; + + beforeEach(() => { + let imageDatum = { + heading: 100, + roll: 90, + pitch: 90, + cameraTilt: 100, + cameraPan: 90, + sunAngle: 30 + }; + let propsData = { + containerWidth: 600, + containerHeight: 600, + naturalAspectRatio: 0.9, + image: imageDatum + }; + + app = new Vue({ + components: { Compass }, + data() { + return propsData; + }, + template: `` + }); + instance = app.$mount(); + + }); + + afterAll(() => { + app.$destroy(); + }); + + describe("when a heading value exists on the image", () => { + + it("should display a compass rose", () => { + let compassRoseElement = instance.$el.querySelector(COMPASS_ROSE_CLASS + ); + + expect(compassRoseElement).toBeDefined(); + }); + + it("should display a compass HUD", () => { + let compassHUDElement = instance.$el.querySelector(COMPASS_HUD_CLASS); + + expect(compassHUDElement).toBeDefined(); + }); + + }); + +}); diff --git a/src/plugins/imagery/components/Compass/utils.js b/src/plugins/imagery/components/Compass/utils.js new file mode 100644 index 0000000000..67e82f5db8 --- /dev/null +++ b/src/plugins/imagery/components/Compass/utils.js @@ -0,0 +1,33 @@ +export function rotate(direction, ...rotations) { + const rotation = rotations.reduce((a, b) => a + b, 0); + + return normalizeCompassDirection(direction + rotation); +} + +export function normalizeCompassDirection(degrees) { + const base = degrees % 360; + + return base >= 0 ? base : 360 + base; +} + +export function inRange(degrees, [min, max]) { + return min > max + ? (degrees >= min && degrees < 360) || (degrees <= max && degrees >= 0) + : degrees >= min && degrees <= max; +} + +export function percentOfRange(degrees, [min, max]) { + let distance = degrees; + let minRange = min; + let maxRange = max; + + if (min > max) { + if (distance < max) { + distance += 360; + } + + maxRange += 360; + } + + return (distance - minRange) / (maxRange - minRange); +} diff --git a/src/plugins/imagery/components/ImageryViewLayout.vue b/src/plugins/imagery/components/ImageryViewLayout.vue index 3891af88b0..15a2d59ab0 100644 --- a/src/plugins/imagery/components/ImageryViewLayout.vue +++ b/src/plugins/imagery/components/ImageryViewLayout.vue @@ -1,3 +1,25 @@ +/***************************************************************************** + * Open MCT, Copyright (c) 2014-2021, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ +