diff --git a/src/plugins/imagery/components/ImageryView.vue b/src/plugins/imagery/components/ImageryView.vue
index 84942c1ee9..4eb987cc73 100644
--- a/src/plugins/imagery/components/ImageryView.vue
+++ b/src/plugins/imagery/components/ImageryView.vue
@@ -25,7 +25,7 @@
tabindex="0"
class="c-imagery"
@keyup="arrowUpHandler"
- @keydown="arrowDownHandler"
+ @keydown.prevent="arrowDownHandler"
@mouseover="focusElement"
>
@@ -165,6 +165,9 @@
@@ -192,6 +195,7 @@
import eventHelpers from '../lib/eventHelpers';
import _ from 'lodash';
import moment from 'moment';
+import Vue from 'vue';
import RelatedTelemetry from './RelatedTelemetry/RelatedTelemetry';
import Compass from './Compass/Compass.vue';
@@ -289,7 +293,8 @@ export default {
pan: undefined,
animateZoom: true,
imagePanned: false,
- forceShowThumbnails: false
+ forceShowThumbnails: false,
+ animateThumbScroll: false
};
},
computed: {
@@ -393,6 +398,12 @@ export default {
return disabled;
},
+ isComposedInLayout() {
+ return (
+ this.currentView?.objectPath
+ && !this.openmct.router.isNavigatedObject(this.currentView.objectPath)
+ );
+ },
focusedImage() {
return this.imageHistory[this.focusedImageIndex];
},
@@ -542,7 +553,7 @@ export default {
},
watch: {
imageHistory: {
- handler(newHistory, _oldHistory) {
+ async handler(newHistory, oldHistory) {
const newSize = newHistory.length;
let imageIndex = newSize > 0 ? newSize - 1 : undefined;
if (this.focusedImageTimestamp !== undefined) {
@@ -570,10 +581,13 @@ export default {
if (!this.isPaused) {
this.setFocusedImage(imageIndex);
- this.scrollToRight();
- } else {
- this.scrollToFocused();
}
+
+ await this.scrollHandler();
+ if (oldHistory?.length > 0) {
+ this.animateThumbScroll = true;
+ }
+
},
deep: true
},
@@ -584,7 +598,7 @@ export default {
this.getImageNaturalDimensions();
},
bounds() {
- this.scrollToFocused();
+ this.scrollHandler();
},
isFixed(newValue) {
const isRealTime = !newValue;
@@ -848,6 +862,13 @@ export default {
const disableScroll = scrollWidth > Math.ceil(scrollLeft + clientWidth);
this.autoScroll = !disableScroll;
},
+ handlePauseButton(newState) {
+ this.paused(newState);
+ if (newState) {
+ // need to set the focused index or the paused focus will drift
+ this.thumbnailClicked(this.focusedImageIndex);
+ }
+ },
paused(state) {
this.isPaused = Boolean(state);
@@ -855,7 +876,7 @@ export default {
this.previousFocusedImage = null;
this.setFocusedImage(this.nextImageIndex);
this.autoScroll = true;
- this.scrollToRight();
+ this.scrollHandler();
}
},
scrollToFocused() {
@@ -865,28 +886,43 @@ export default {
}
let domThumb = thumbsWrapper.children[this.focusedImageIndex];
-
- if (domThumb) {
- domThumb.scrollIntoView({
- behavior: 'smooth',
- block: 'center',
- inline: 'center'
- });
- }
- },
- scrollToRight(type) {
- if (type !== 'reset' && (this.isPaused || !this.$refs.thumbsWrapper || !this.autoScroll)) {
+ if (!domThumb) {
return;
}
- const scrollWidth = this.$refs.thumbsWrapper.scrollWidth || 0;
+ // separate scrollTo function had to be implemented since scrollIntoView
+ // caused undesirable behavior in layouts
+ // and could not simply be scoped to the parent element
+ if (this.isComposedInLayout) {
+ const wrapperWidth = this.$refs.thumbsWrapper.clientWidth ?? 0;
+ this.$refs.thumbsWrapper.scrollLeft = (
+ domThumb.offsetLeft - (wrapperWidth - domThumb.clientWidth) / 2);
+
+ return;
+ }
+
+ domThumb.scrollIntoView({
+ behavior: 'smooth',
+ block: 'center',
+ inline: 'center'
+ });
+ },
+ async scrollToRight() {
+
+ const scrollWidth = this.$refs?.thumbsWrapper?.scrollWidth ?? 0;
if (!scrollWidth) {
return;
}
- this.$nextTick(() => {
- this.$refs.thumbsWrapper.scrollLeft = scrollWidth;
- });
+ await Vue.nextTick();
+ this.$refs.thumbsWrapper.scrollLeft = scrollWidth;
+ },
+ scrollHandler() {
+ if (this.isPaused) {
+ return this.scrollToFocused();
+ } else if (this.autoScroll) {
+ return this.scrollToRight();
+ }
},
matchIndexOfPreviousImage(previous, imageHistory) {
// match logic uses a composite of url and time to account
@@ -1087,7 +1123,7 @@ export default {
this.setSizedImageDimensions();
this.setImageViewport();
this.calculateViewHeight();
- this.scrollToFocused();
+ this.scrollHandler();
},
setSizedImageDimensions() {
this.focusedImageNaturalAspectRatio = this.$refs.focusedImage.naturalWidth / this.$refs.focusedImage.naturalHeight;
@@ -1122,9 +1158,7 @@ export default {
this.handleThumbWindowResizeEnded();
},
handleThumbWindowResizeEnded() {
- if (!this.isPaused) {
- this.scrollToRight('reset');
- }
+ this.scrollHandler();
this.calculateViewHeight();
@@ -1137,7 +1171,6 @@ export default {
},
wheelZoom(e) {
e.preventDefault();
-
this.$refs.imageControls.wheelZoom(e);
},
startPan(e) {
diff --git a/src/plugins/imagery/components/imagery-view.scss b/src/plugins/imagery/components/imagery-view.scss
index b90234f9e7..ee0713244b 100644
--- a/src/plugins/imagery/components/imagery-view.scss
+++ b/src/plugins/imagery/components/imagery-view.scss
@@ -194,6 +194,9 @@
overflow-y: hidden;
margin-bottom: 1px;
padding-bottom: $interiorMarginSm;
+ &.animate-scroll {
+ scroll-behavior: smooth;
+ }
}
&__auto-scroll-resume-button {
diff --git a/src/plugins/imagery/pluginSpec.js b/src/plugins/imagery/pluginSpec.js
index 634639160e..15a81b09e3 100644
--- a/src/plugins/imagery/pluginSpec.js
+++ b/src/plugins/imagery/pluginSpec.js
@@ -481,19 +481,16 @@ describe("The Imagery View Layouts", () => {
});
});
});
- it ('scrollToRight is called when clicking on auto scroll button', (done) => {
- Vue.nextTick(() => {
- // use spyon to spy the scroll function
- spyOn(imageryView._getInstance().$refs.ImageryContainer, 'scrollToRight');
- imageryView._getInstance().$refs.ImageryContainer.autoScroll = false;
- Vue.nextTick(() => {
- parent.querySelector('.c-imagery__auto-scroll-resume-button').click();
- expect(imageryView._getInstance().$refs.ImageryContainer.scrollToRight).toHaveBeenCalledWith('reset');
- done();
- });
- });
+ it ('scrollToRight is called when clicking on auto scroll button', async () => {
+ await Vue.nextTick();
+ // use spyon to spy the scroll function
+ spyOn(imageryView._getInstance().$refs.ImageryContainer, 'scrollHandler');
+ imageryView._getInstance().$refs.ImageryContainer.autoScroll = false;
+ await Vue.nextTick();
+ parent.querySelector('.c-imagery__auto-scroll-resume-button').click();
+ expect(imageryView._getInstance().$refs.ImageryContainer.scrollHandler);
});
- xit('should change the image zoom factor when using the zoom buttons', async (done) => {
+ xit('should change the image zoom factor when using the zoom buttons', async () => {
await Vue.nextTick();
let imageSizeBefore;
let imageSizeAfter;
@@ -512,7 +509,6 @@ describe("The Imagery View Layouts", () => {
imageSizeAfter = parent.querySelector('.c-imagery_main-image_background-image').getBoundingClientRect();
expect(imageSizeAfter.height).toBeLessThan(imageSizeBefore.height);
expect(imageSizeAfter.width).toBeLessThan(imageSizeBefore.width);
- done();
});
xit('should reset the zoom factor on the image when clicking the zoom button', async (done) => {
await Vue.nextTick();