Compare commits
1 Commits
html2canva
...
code-walkt
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea45e7f636 |
@@ -194,6 +194,7 @@
|
||||
['table', 'telemetry.plot.overlay', 'telemetry.plot.stacked'],
|
||||
{indicator: true}
|
||||
));
|
||||
openmct.install(openmct.plugins.CodeWalkthrough);
|
||||
openmct.start();
|
||||
</script>
|
||||
</html>
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
"git-rev-sync": "^1.4.0",
|
||||
"glob": ">= 3.0.0",
|
||||
"html-loader": "^0.5.5",
|
||||
"html2canvas": "^1.0.0-rc.7",
|
||||
"html2canvas": "^1.0.0-alpha.12",
|
||||
"imports-loader": "^0.8.0",
|
||||
"istanbul-instrumenter-loader": "^3.0.1",
|
||||
"jasmine-core": "^3.1.0",
|
||||
|
||||
71
src/plugins/codeWalkthrough/plugin.js
Normal file
71
src/plugins/codeWalkthrough/plugin.js
Normal file
@@ -0,0 +1,71 @@
|
||||
import Vue from 'Vue';
|
||||
|
||||
export default function install(openmct) {
|
||||
openmct.objectViews.addProvider({
|
||||
name: "Latest Data Table",
|
||||
key: "latest-table",
|
||||
cssClass: "icon-packet",
|
||||
description: "A tabular view of telemetry contents.",
|
||||
canView: function () {
|
||||
return true;
|
||||
},
|
||||
view: function (domainObject) {
|
||||
let unsubscribe;
|
||||
|
||||
return {
|
||||
show: function (element) {
|
||||
//element.innerText = 'Hello World!';
|
||||
let telemetryMetadata = openmct.telemetry.getMetadata(domainObject).values();
|
||||
let tableEl = document.createElement('table');
|
||||
let tableHeader = document.createElement('thead');
|
||||
let tableHeaderRow = document.createElement('tr');
|
||||
let tableBody = document.createElement('tbody');
|
||||
|
||||
element.appendChild(tableEl);
|
||||
tableHeader.appendChild(tableHeaderRow);
|
||||
tableEl.appendChild(tableHeader);
|
||||
tableEl.appendChild(tableBody);
|
||||
|
||||
telemetryMetadata.forEach(metadatum => {
|
||||
let tableHeader = document.createElement('td');
|
||||
tableHeader.innerText = metadatum.name;
|
||||
tableHeaderRow.appendChild(tableHeader);
|
||||
});
|
||||
|
||||
openmct.time.on('bounds', (newBounds) => {
|
||||
tableBody.innerHTML = '';
|
||||
requestTelemetry(newBounds);
|
||||
});
|
||||
|
||||
requestTelemetry();
|
||||
|
||||
// unsubscribe = openmct.telemetry.subscribe(domainObject, (datum) => {
|
||||
// addRow(datum);
|
||||
// });
|
||||
|
||||
function addRow(telemetryDatum) {
|
||||
let dataRow = document.createElement('tr');
|
||||
telemetryMetadata.forEach(metadatum => {
|
||||
let tableCell = document.createElement('td');
|
||||
let formatter = openmct.telemetry.getValueFormatter(metadatum);
|
||||
|
||||
tableCell.innerText = formatter.format(telemetryDatum[metadatum.key]);
|
||||
dataRow.appendChild(tableCell);
|
||||
tableBody.appendChild(dataRow);
|
||||
});
|
||||
}
|
||||
|
||||
function requestTelemetry(bounds) {
|
||||
openmct.telemetry.request(domainObject, {bounds}).then(arrayOfTelemetry => {
|
||||
arrayOfTelemetry.forEach(addRow);
|
||||
});
|
||||
}
|
||||
},
|
||||
destroy: function (element) {
|
||||
unsubscribe();
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
@@ -23,20 +23,23 @@
|
||||
<template>
|
||||
<div
|
||||
class="c-compass"
|
||||
:style="`width: 100%; height: 100%`"
|
||||
:style="`width: ${ sizedImageDimensions.width }px; height: ${ sizedImageDimensions.height }px`"
|
||||
>
|
||||
<CompassHUD
|
||||
v-if="hasCameraFieldOfView"
|
||||
:sun-heading="sunHeading"
|
||||
:camera-angle-of-view="cameraAngleOfView"
|
||||
:camera-pan="cameraPan"
|
||||
/>
|
||||
<CompassRose
|
||||
v-if="hasCameraFieldOfView"
|
||||
:heading="heading"
|
||||
:sized-image-width="sizedImageDimensions.width"
|
||||
:sun-heading="sunHeading"
|
||||
:camera-angle-of-view="cameraAngleOfView"
|
||||
:camera-pan="cameraPan"
|
||||
:compass-rose-sizing-classes="compassRoseSizingClasses"
|
||||
:heading="heading"
|
||||
:sized-image-dimensions="sizedImageDimensions"
|
||||
:sun-heading="sunHeading"
|
||||
:lock-compass="lockCompass"
|
||||
@toggle-lock-compass="toggleLockCompass"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -53,20 +56,42 @@ export default {
|
||||
CompassRose
|
||||
},
|
||||
props: {
|
||||
compassRoseSizingClasses: {
|
||||
type: String,
|
||||
containerWidth: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
containerHeight: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
naturalAspectRatio: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
image: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
sizedImageDimensions: {
|
||||
type: Object,
|
||||
lockCompass: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
sizedImageDimensions() {
|
||||
let sizedImageDimensions = {};
|
||||
if ((this.containerWidth / this.containerHeight) > this.naturalAspectRatio) {
|
||||
// container is wider than image
|
||||
sizedImageDimensions.width = this.containerHeight * this.naturalAspectRatio;
|
||||
sizedImageDimensions.height = this.containerHeight;
|
||||
} else {
|
||||
// container is taller than image
|
||||
sizedImageDimensions.width = this.containerWidth;
|
||||
sizedImageDimensions.height = this.containerWidth * this.naturalAspectRatio;
|
||||
}
|
||||
|
||||
return sizedImageDimensions;
|
||||
},
|
||||
hasCameraFieldOfView() {
|
||||
return this.cameraPan !== undefined && this.cameraAngleOfView > 0;
|
||||
},
|
||||
@@ -85,6 +110,11 @@ export default {
|
||||
cameraAngleOfView() {
|
||||
return CAMERA_ANGLE_OF_VIEW;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toggleLockCompass() {
|
||||
this.$emit('toggle-lock-compass');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -104,10 +104,7 @@ export default {
|
||||
},
|
||||
cameraPan: {
|
||||
type: Number,
|
||||
required: true,
|
||||
default() {
|
||||
return 0;
|
||||
}
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
@@ -25,41 +25,22 @@
|
||||
class="w-direction-rose"
|
||||
:class="compassRoseSizingClasses"
|
||||
>
|
||||
<div ref="directionRose"
|
||||
class="c-direction-rose"
|
||||
@click="toggleLockCompass"
|
||||
<div
|
||||
class="c-direction-rose"
|
||||
@click="toggleLockCompass"
|
||||
>
|
||||
<div
|
||||
class="c-nsew"
|
||||
:style="compassRoseStyle"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="hasHeading"
|
||||
class="c-spacecraft-body"
|
||||
:style="headingStyle"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="hasSunHeading"
|
||||
class="c-sun"
|
||||
:style="sunHeadingStyle"
|
||||
></div>
|
||||
|
||||
<div ref="camField"
|
||||
class="c-cam-field"
|
||||
:style="cameraPanStyle"
|
||||
>
|
||||
<svg ref="camFieldSVG"
|
||||
viewBox="0 0 100 100"
|
||||
<svg
|
||||
class="c-nsew__minor-ticks"
|
||||
viewBox="0 0 100 100"
|
||||
>
|
||||
<rect
|
||||
class="c-nsew__tick c-tick-ne"
|
||||
x="49"
|
||||
y="0"
|
||||
fill="red"
|
||||
width="2"
|
||||
height="5"
|
||||
/>
|
||||
@@ -84,14 +65,91 @@
|
||||
width="5"
|
||||
height="2"
|
||||
/>
|
||||
<path fill="gray"
|
||||
d="M50, 50
|
||||
L30,8
|
||||
A40 40 0 0 1 70,8
|
||||
Z
|
||||
"
|
||||
/>
|
||||
|
||||
</svg>
|
||||
|
||||
<svg
|
||||
class="c-nsew__ticks"
|
||||
viewBox="0 0 100 100"
|
||||
>
|
||||
<polygon
|
||||
class="c-nsew__tick c-tick-n"
|
||||
points="50,0 60,10 40,10"
|
||||
/>
|
||||
<rect
|
||||
class="c-nsew__tick c-tick-e"
|
||||
x="95"
|
||||
y="49"
|
||||
width="5"
|
||||
height="2"
|
||||
/>
|
||||
<rect
|
||||
class="c-nsew__tick c-tick-w"
|
||||
x="0"
|
||||
y="49"
|
||||
width="5"
|
||||
height="2"
|
||||
/>
|
||||
<rect
|
||||
class="c-nsew__tick c-tick-s"
|
||||
x="49"
|
||||
y="95"
|
||||
width="2"
|
||||
height="5"
|
||||
/>
|
||||
|
||||
<text
|
||||
class="c-nsew__label c-label-n"
|
||||
text-anchor="middle"
|
||||
:transform="northTextTransform"
|
||||
>N</text>
|
||||
<text
|
||||
class="c-nsew__label c-label-e"
|
||||
text-anchor="middle"
|
||||
:transform="eastTextTransform"
|
||||
>E</text>
|
||||
<text
|
||||
class="c-nsew__label c-label-w"
|
||||
text-anchor="middle"
|
||||
:transform="southTextTransform"
|
||||
>W</text>
|
||||
<text
|
||||
class="c-nsew__label c-label-s"
|
||||
text-anchor="middle"
|
||||
:transform="westTextTransform"
|
||||
>S</text>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="hasHeading"
|
||||
class="c-spacecraft-body"
|
||||
:style="headingStyle"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="hasSunHeading"
|
||||
class="c-sun"
|
||||
:style="sunHeadingStyle"
|
||||
></div>
|
||||
|
||||
<div
|
||||
class="c-cam-field"
|
||||
:style="cameraPanStyle"
|
||||
>
|
||||
<div class="cam-field-half cam-field-half-l">
|
||||
<div
|
||||
class="cam-field-area"
|
||||
:style="cameraFOVStyleLeftHalf"
|
||||
></div>
|
||||
</div>
|
||||
<div class="cam-field-half cam-field-half-r">
|
||||
<div
|
||||
class="cam-field-area"
|
||||
:style="cameraFOVStyleRightHalf"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -99,20 +157,16 @@
|
||||
|
||||
<script>
|
||||
import { rotate } from './utils';
|
||||
import { throttle } from 'lodash';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
compassRoseSizingClasses: {
|
||||
type: String,
|
||||
sizedImageWidth: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
heading: {
|
||||
type: Number,
|
||||
required: true,
|
||||
default() {
|
||||
return 0;
|
||||
}
|
||||
required: true
|
||||
},
|
||||
sunHeading: {
|
||||
type: Number,
|
||||
@@ -124,22 +178,26 @@ export default {
|
||||
},
|
||||
cameraPan: {
|
||||
type: Number,
|
||||
required: true,
|
||||
default() {
|
||||
return 0;
|
||||
}
|
||||
required: true
|
||||
},
|
||||
sizedImageDimensions: {
|
||||
type: Object,
|
||||
lockCompass: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
lockCompass: true
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
compassRoseSizingClasses() {
|
||||
let compassRoseSizingClasses = '';
|
||||
if (this.sizedImageWidth < 300) {
|
||||
compassRoseSizingClasses = '--rose-small --rose-min';
|
||||
} else if (this.sizedImageWidth < 500) {
|
||||
compassRoseSizingClasses = '--rose-small';
|
||||
} else if (this.sizedImageWidth > 1000) {
|
||||
compassRoseSizingClasses = '--rose-max';
|
||||
}
|
||||
|
||||
return compassRoseSizingClasses;
|
||||
},
|
||||
compassRoseStyle() {
|
||||
return { transform: `rotate(${ this.north }deg)` };
|
||||
},
|
||||
@@ -215,29 +273,9 @@ export default {
|
||||
};
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
sizedImageDimensions() {
|
||||
this.debounceResizeSvg();
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.debounceResizeSvg = throttle(this.resizeSvg, 100);
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.debounceResizeSvg();
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
resizeSvg() {
|
||||
const svg = this.$refs.camFieldSVG;
|
||||
svg.setAttribute('width', this.$refs.camField.clientWidth);
|
||||
svg.setAttribute('height', this.$refs.camField.clientHeight);
|
||||
},
|
||||
rotateSVG() {
|
||||
this.$refs.camField.style.transform = "rotate(45deg)";
|
||||
},
|
||||
toggleLockCompass() {
|
||||
this.lockCompass = !this.lockCompass;
|
||||
this.$emit('toggle-lock-compass');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -12,8 +12,9 @@ $elemBg: rgba(black, 0.7);
|
||||
.c-compass {
|
||||
pointer-events: none; // This allows the image element to receive a browser-level context click
|
||||
position: absolute;
|
||||
left: 0%;
|
||||
top: 0%;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 1;
|
||||
@include userSelectNone;
|
||||
}
|
||||
@@ -120,6 +121,7 @@ $elemBg: rgba(black, 0.7);
|
||||
/***************************** CAMERA FIELD ANGLE */
|
||||
.c-cam-field {
|
||||
$color: white;
|
||||
opacity: 0.3;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
|
||||
@@ -55,33 +55,28 @@
|
||||
></a>
|
||||
</span>
|
||||
</div>
|
||||
<div ref="imageBG"
|
||||
class="c-imagery__main-image__bg"
|
||||
<div class="c-imagery__main-image__bg"
|
||||
:class="{'paused unnsynced': isPaused,'stale':false }"
|
||||
>
|
||||
<div class="image-wrapper"
|
||||
:style="{
|
||||
'width': `${sizedImageDimensions.width}px`,
|
||||
'height': `${sizedImageDimensions.height}px`
|
||||
}"
|
||||
<img
|
||||
ref="focusedImage"
|
||||
class="c-imagery__main-image__image js-imageryView-image"
|
||||
:src="imageUrl"
|
||||
:style="{
|
||||
'filter': `brightness(${filters.brightness}%) contrast(${filters.contrast}%)`
|
||||
}"
|
||||
:data-openmct-image-timestamp="time"
|
||||
:data-openmct-object-keystring="keyString"
|
||||
>
|
||||
<img ref="focusedImage"
|
||||
class="c-imagery__main-image__image js-imageryView-image"
|
||||
:src="imageUrl"
|
||||
:style="{
|
||||
'filter': `brightness(${filters.brightness}%) contrast(${filters.contrast}%)`
|
||||
}"
|
||||
:data-openmct-image-timestamp="time"
|
||||
:data-openmct-object-keystring="keyString"
|
||||
>
|
||||
<Compass
|
||||
v-if="shouldDisplayCompass"
|
||||
:compass-rose-sizing-classes="compassRoseSizingClasses"
|
||||
:image="focusedImage"
|
||||
:natural-aspect-ratio="focusedImageNaturalAspectRatio"
|
||||
:sized-image-dimensions="sizedImageDimensions"
|
||||
/>
|
||||
</div>
|
||||
<Compass
|
||||
v-if="shouldDisplayCompass"
|
||||
:container-width="imageContainerWidth"
|
||||
:container-height="imageContainerHeight"
|
||||
:natural-aspect-ratio="focusedImageNaturalAspectRatio"
|
||||
:image="focusedImage"
|
||||
:lock-compass="lockCompass"
|
||||
@toggle-lock-compass="toggleLockCompass"
|
||||
/>
|
||||
</div>
|
||||
<div class="c-local-controls c-local-controls--show-on-hover c-imagery__prev-next-buttons">
|
||||
<button class="c-nav c-nav--prev"
|
||||
@@ -229,18 +224,6 @@ export default {
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
compassRoseSizingClasses() {
|
||||
let compassRoseSizingClasses = '';
|
||||
if (this.sizedImageDimensions.width < 300) {
|
||||
compassRoseSizingClasses = '--rose-small --rose-min';
|
||||
} else if (this.sizedImageDimensions.width < 500) {
|
||||
compassRoseSizingClasses = '--rose-small';
|
||||
} else if (this.sizedImageDimensions.width > 1000) {
|
||||
compassRoseSizingClasses = '--rose-max';
|
||||
}
|
||||
|
||||
return compassRoseSizingClasses;
|
||||
},
|
||||
time() {
|
||||
return this.formatTime(this.focusedImage);
|
||||
},
|
||||
@@ -364,20 +347,6 @@ export default {
|
||||
}
|
||||
|
||||
return isFresh;
|
||||
},
|
||||
sizedImageDimensions() {
|
||||
let sizedImageDimensions = {};
|
||||
if ((this.imageContainerWidth / this.imageContainerHeight) > this.focusedImageNaturalAspectRatio) {
|
||||
// container is wider than image
|
||||
sizedImageDimensions.width = this.imageContainerHeight * this.focusedImageNaturalAspectRatio;
|
||||
sizedImageDimensions.height = this.imageContainerHeight;
|
||||
} else {
|
||||
// container is taller than image
|
||||
sizedImageDimensions.width = this.imageContainerWidth;
|
||||
sizedImageDimensions.height = this.imageContainerWidth * this.focusedImageNaturalAspectRatio;
|
||||
}
|
||||
|
||||
return sizedImageDimensions;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -426,7 +395,7 @@ export default {
|
||||
_.debounce(this.resizeImageContainer, 400);
|
||||
|
||||
this.imageContainerResizeObserver = new ResizeObserver(this.resizeImageContainer);
|
||||
this.imageContainerResizeObserver.observe(this.$refs.imageBG);
|
||||
this.imageContainerResizeObserver.observe(this.$refs.focusedImage);
|
||||
|
||||
// For adjusting scroll bar size and position when resizing thumbs wrapper
|
||||
this.handleScroll = _.debounce(this.handleScroll, SCROLL_LATENCY);
|
||||
@@ -864,12 +833,12 @@ export default {
|
||||
}, { once: true });
|
||||
},
|
||||
resizeImageContainer() {
|
||||
if (this.$refs.imageBG.clientWidth !== this.imageContainerWidth) {
|
||||
this.imageContainerWidth = this.$refs.imageBG.clientWidth;
|
||||
if (this.$refs.focusedImage.clientWidth !== this.imageContainerWidth) {
|
||||
this.imageContainerWidth = this.$refs.focusedImage.clientWidth;
|
||||
}
|
||||
|
||||
if (this.$refs.imageBG.clientHeight !== this.imageContainerHeight) {
|
||||
this.imageContainerHeight = this.$refs.imageBG.clientHeight;
|
||||
if (this.$refs.focusedImage.clientHeight !== this.imageContainerHeight) {
|
||||
this.imageContainerHeight = this.$refs.focusedImage.clientHeight;
|
||||
}
|
||||
},
|
||||
handleThumbWindowResizeStart() {
|
||||
@@ -889,6 +858,9 @@ export default {
|
||||
this.$nextTick(() => {
|
||||
this.resizingWindow = false;
|
||||
});
|
||||
},
|
||||
toggleLockCompass() {
|
||||
this.lockCompass = !this.lockCompass;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -22,9 +22,6 @@
|
||||
&__bg {
|
||||
background-color: $colorPlotBg;
|
||||
border: 1px solid transparent;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1 1 auto;
|
||||
height: 0;
|
||||
|
||||
@@ -36,6 +33,7 @@
|
||||
&__image {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,8 @@ define([
|
||||
'./interceptors/plugin',
|
||||
'./performanceIndicator/plugin',
|
||||
'./CouchDBSearchFolder/plugin',
|
||||
'./timeline/plugin'
|
||||
'./timeline/plugin',
|
||||
'./codeWalkthrough/plugin'
|
||||
], function (
|
||||
_,
|
||||
UTCTimeSystem,
|
||||
@@ -111,7 +112,8 @@ define([
|
||||
ObjectInterceptors,
|
||||
PerformanceIndicator,
|
||||
CouchDBSearchFolder,
|
||||
Timeline
|
||||
Timeline,
|
||||
codeWalkthroughPlugin
|
||||
) {
|
||||
const bundleMap = {
|
||||
LocalStorage: 'platform/persistence/local',
|
||||
@@ -212,6 +214,7 @@ define([
|
||||
plugins.PerformanceIndicator = PerformanceIndicator.default;
|
||||
plugins.CouchDBSearchFolder = CouchDBSearchFolder.default;
|
||||
plugins.Timeline = Timeline.default;
|
||||
plugins.CodeWalkthrough = codeWalkthroughPlugin.default;
|
||||
|
||||
return plugins;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user