Compare commits

...

4 Commits

Author SHA1 Message Date
152a09b0c4 center image properly 2021-07-07 15:55:15 -07:00
b17ce14775 resize image wrapper 2021-07-07 15:46:56 -07:00
7e6adc996e refactored compass structure and code. 2021-07-07 13:32:28 -07:00
e7acf64b34 changes 2021-07-01 15:57:32 -07:00
7 changed files with 145 additions and 182 deletions

View File

@ -34,7 +34,7 @@
"git-rev-sync": "^1.4.0", "git-rev-sync": "^1.4.0",
"glob": ">= 3.0.0", "glob": ">= 3.0.0",
"html-loader": "^0.5.5", "html-loader": "^0.5.5",
"html2canvas": "^1.0.0-alpha.12", "html2canvas": "^1.0.0-rc.7",
"imports-loader": "^0.8.0", "imports-loader": "^0.8.0",
"istanbul-instrumenter-loader": "^3.0.1", "istanbul-instrumenter-loader": "^3.0.1",
"jasmine-core": "^3.1.0", "jasmine-core": "^3.1.0",

View File

@ -23,23 +23,20 @@
<template> <template>
<div <div
class="c-compass" class="c-compass"
:style="`width: ${ sizedImageDimensions.width }px; height: ${ sizedImageDimensions.height }px`" :style="`width: 100%; height: 100%`"
> >
<CompassHUD <CompassHUD
v-if="hasCameraFieldOfView"
:sun-heading="sunHeading" :sun-heading="sunHeading"
:camera-angle-of-view="cameraAngleOfView" :camera-angle-of-view="cameraAngleOfView"
:camera-pan="cameraPan" :camera-pan="cameraPan"
/> />
<CompassRose <CompassRose
v-if="hasCameraFieldOfView"
:heading="heading"
:sized-image-width="sizedImageDimensions.width"
:sun-heading="sunHeading"
:camera-angle-of-view="cameraAngleOfView" :camera-angle-of-view="cameraAngleOfView"
:camera-pan="cameraPan" :camera-pan="cameraPan"
:lock-compass="lockCompass" :compass-rose-sizing-classes="compassRoseSizingClasses"
@toggle-lock-compass="toggleLockCompass" :heading="heading"
:sized-image-dimensions="sizedImageDimensions"
:sun-heading="sunHeading"
/> />
</div> </div>
</template> </template>
@ -56,42 +53,20 @@ export default {
CompassRose CompassRose
}, },
props: { props: {
containerWidth: { compassRoseSizingClasses: {
type: Number, type: String,
required: true
},
containerHeight: {
type: Number,
required: true
},
naturalAspectRatio: {
type: Number,
required: true required: true
}, },
image: { image: {
type: Object, type: Object,
required: true required: true
}, },
lockCompass: { sizedImageDimensions: {
type: Boolean, type: Object,
required: true required: true
} }
}, },
computed: { 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() { hasCameraFieldOfView() {
return this.cameraPan !== undefined && this.cameraAngleOfView > 0; return this.cameraPan !== undefined && this.cameraAngleOfView > 0;
}, },
@ -110,11 +85,6 @@ export default {
cameraAngleOfView() { cameraAngleOfView() {
return CAMERA_ANGLE_OF_VIEW; return CAMERA_ANGLE_OF_VIEW;
} }
},
methods: {
toggleLockCompass() {
this.$emit('toggle-lock-compass');
}
} }
}; };
</script> </script>

View File

@ -104,7 +104,10 @@ export default {
}, },
cameraPan: { cameraPan: {
type: Number, type: Number,
required: true required: true,
default() {
return 0;
}
} }
}, },
computed: { computed: {

View File

@ -25,22 +25,41 @@
class="w-direction-rose" class="w-direction-rose"
:class="compassRoseSizingClasses" :class="compassRoseSizingClasses"
> >
<div <div ref="directionRose"
class="c-direction-rose" class="c-direction-rose"
@click="toggleLockCompass" @click="toggleLockCompass"
> >
<div <div
class="c-nsew" class="c-nsew"
:style="compassRoseStyle" :style="compassRoseStyle"
> >
<svg </div>
class="c-nsew__minor-ticks"
viewBox="0 0 100 100" <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"
> >
<rect <rect
class="c-nsew__tick c-tick-ne" class="c-nsew__tick c-tick-ne"
x="49" x="49"
y="0" y="0"
fill="red"
width="2" width="2"
height="5" height="5"
/> />
@ -65,91 +84,14 @@
width="5" width="5"
height="2" height="2"
/> />
<path fill="gray"
d="M50, 50
L30,8
A40 40 0 0 1 70,8
Z
"
/>
</svg> </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> </div>
</div> </div>
@ -157,16 +99,20 @@
<script> <script>
import { rotate } from './utils'; import { rotate } from './utils';
import { throttle } from 'lodash';
export default { export default {
props: { props: {
sizedImageWidth: { compassRoseSizingClasses: {
type: Number, type: String,
required: true required: true
}, },
heading: { heading: {
type: Number, type: Number,
required: true required: true,
default() {
return 0;
}
}, },
sunHeading: { sunHeading: {
type: Number, type: Number,
@ -178,26 +124,22 @@ export default {
}, },
cameraPan: { cameraPan: {
type: Number, type: Number,
required: true required: true,
default() {
return 0;
}
}, },
lockCompass: { sizedImageDimensions: {
type: Boolean, type: Object,
required: true required: true
} }
}, },
data() {
return {
lockCompass: true
};
},
computed: { 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() { compassRoseStyle() {
return { transform: `rotate(${ this.north }deg)` }; return { transform: `rotate(${ this.north }deg)` };
}, },
@ -273,9 +215,29 @@ export default {
}; };
} }
}, },
watch: {
sizedImageDimensions() {
this.debounceResizeSvg();
}
},
mounted() {
this.debounceResizeSvg = throttle(this.resizeSvg, 100);
this.$nextTick(() => {
this.debounceResizeSvg();
});
},
methods: { 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() { toggleLockCompass() {
this.$emit('toggle-lock-compass'); this.lockCompass = !this.lockCompass;
} }
} }
}; };

View File

@ -12,9 +12,8 @@ $elemBg: rgba(black, 0.7);
.c-compass { .c-compass {
pointer-events: none; // This allows the image element to receive a browser-level context click pointer-events: none; // This allows the image element to receive a browser-level context click
position: absolute; position: absolute;
left: 50%; left: 0%;
top: 50%; top: 0%;
transform: translate(-50%, -50%);
z-index: 1; z-index: 1;
@include userSelectNone; @include userSelectNone;
} }
@ -121,7 +120,6 @@ $elemBg: rgba(black, 0.7);
/***************************** CAMERA FIELD ANGLE */ /***************************** CAMERA FIELD ANGLE */
.c-cam-field { .c-cam-field {
$color: white; $color: white;
opacity: 0.3;
top: 0; top: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;

View File

@ -55,28 +55,33 @@
></a> ></a>
</span> </span>
</div> </div>
<div class="c-imagery__main-image__bg" <div ref="imageBG"
class="c-imagery__main-image__bg"
:class="{'paused unnsynced': isPaused,'stale':false }" :class="{'paused unnsynced': isPaused,'stale':false }"
> >
<img <div class="image-wrapper"
ref="focusedImage" :style="{
class="c-imagery__main-image__image js-imageryView-image" 'width': `${sizedImageDimensions.width}px`,
:src="imageUrl" 'height': `${sizedImageDimensions.height}px`
:style="{ }"
'filter': `brightness(${filters.brightness}%) contrast(${filters.contrast}%)`
}"
:data-openmct-image-timestamp="time"
:data-openmct-object-keystring="keyString"
> >
<Compass <img ref="focusedImage"
v-if="shouldDisplayCompass" class="c-imagery__main-image__image js-imageryView-image"
:container-width="imageContainerWidth" :src="imageUrl"
:container-height="imageContainerHeight" :style="{
:natural-aspect-ratio="focusedImageNaturalAspectRatio" 'filter': `brightness(${filters.brightness}%) contrast(${filters.contrast}%)`
:image="focusedImage" }"
:lock-compass="lockCompass" :data-openmct-image-timestamp="time"
@toggle-lock-compass="toggleLockCompass" :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>
</div> </div>
<div class="c-local-controls c-local-controls--show-on-hover c-imagery__prev-next-buttons"> <div class="c-local-controls c-local-controls--show-on-hover c-imagery__prev-next-buttons">
<button class="c-nav c-nav--prev" <button class="c-nav c-nav--prev"
@ -224,6 +229,18 @@ export default {
}; };
}, },
computed: { 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() { time() {
return this.formatTime(this.focusedImage); return this.formatTime(this.focusedImage);
}, },
@ -347,6 +364,20 @@ export default {
} }
return isFresh; 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: { watch: {
@ -395,7 +426,7 @@ export default {
_.debounce(this.resizeImageContainer, 400); _.debounce(this.resizeImageContainer, 400);
this.imageContainerResizeObserver = new ResizeObserver(this.resizeImageContainer); this.imageContainerResizeObserver = new ResizeObserver(this.resizeImageContainer);
this.imageContainerResizeObserver.observe(this.$refs.focusedImage); this.imageContainerResizeObserver.observe(this.$refs.imageBG);
// For adjusting scroll bar size and position when resizing thumbs wrapper // For adjusting scroll bar size and position when resizing thumbs wrapper
this.handleScroll = _.debounce(this.handleScroll, SCROLL_LATENCY); this.handleScroll = _.debounce(this.handleScroll, SCROLL_LATENCY);
@ -833,12 +864,12 @@ export default {
}, { once: true }); }, { once: true });
}, },
resizeImageContainer() { resizeImageContainer() {
if (this.$refs.focusedImage.clientWidth !== this.imageContainerWidth) { if (this.$refs.imageBG.clientWidth !== this.imageContainerWidth) {
this.imageContainerWidth = this.$refs.focusedImage.clientWidth; this.imageContainerWidth = this.$refs.imageBG.clientWidth;
} }
if (this.$refs.focusedImage.clientHeight !== this.imageContainerHeight) { if (this.$refs.imageBG.clientHeight !== this.imageContainerHeight) {
this.imageContainerHeight = this.$refs.focusedImage.clientHeight; this.imageContainerHeight = this.$refs.imageBG.clientHeight;
} }
}, },
handleThumbWindowResizeStart() { handleThumbWindowResizeStart() {
@ -858,9 +889,6 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.resizingWindow = false; this.resizingWindow = false;
}); });
},
toggleLockCompass() {
this.lockCompass = !this.lockCompass;
} }
} }
}; };

View File

@ -22,6 +22,9 @@
&__bg { &__bg {
background-color: $colorPlotBg; background-color: $colorPlotBg;
border: 1px solid transparent; border: 1px solid transparent;
display: flex;
align-items: center;
justify-content: center;
flex: 1 1 auto; flex: 1 1 auto;
height: 0; height: 0;
@ -33,7 +36,6 @@
&__image { &__image {
height: 100%; height: 100%;
width: 100%; width: 100%;
object-fit: contain;
} }
} }