34 - Image Pan and Zoom (#4736)
This commit is contained in:
@@ -29,59 +29,78 @@
|
||||
@mouseover="focusElement"
|
||||
>
|
||||
<div class="c-imagery__main-image-wrapper has-local-controls">
|
||||
<div class="h-local-controls h-local-controls--overlay-content c-local-controls--show-on-hover c-image-controls__controls">
|
||||
<span
|
||||
class="c-image-controls__sliders"
|
||||
draggable="true"
|
||||
@dragstart="startDrag"
|
||||
>
|
||||
<div class="c-image-controls__slider-wrapper icon-brightness">
|
||||
<input
|
||||
v-model="filters.brightness"
|
||||
type="range"
|
||||
min="0"
|
||||
max="500"
|
||||
>
|
||||
</div>
|
||||
<div class="c-image-controls__slider-wrapper icon-contrast">
|
||||
<input
|
||||
v-model="filters.contrast"
|
||||
type="range"
|
||||
min="0"
|
||||
max="500"
|
||||
>
|
||||
</div>
|
||||
</span>
|
||||
<span class="t-reset-btn-holder c-imagery__lc__reset-btn c-image-controls__btn-reset">
|
||||
<a
|
||||
class="s-icon-button icon-reset t-btn-reset"
|
||||
@click="filters={brightness: 100, contrast: 100}"
|
||||
></a>
|
||||
</span>
|
||||
</div>
|
||||
<ImageControls
|
||||
ref="imageControls"
|
||||
:zoom-factor="zoomFactor"
|
||||
:image-url="imageUrl"
|
||||
@resetImage="resetImage"
|
||||
@panZoomUpdated="handlePanZoomUpdate"
|
||||
@filtersUpdated="setFilters"
|
||||
@cursorsUpdated="setCursorStates"
|
||||
@startPan="startPan"
|
||||
/>
|
||||
|
||||
<div
|
||||
ref="imageBG"
|
||||
class="c-imagery__main-image__bg"
|
||||
:class="{'paused unnsynced': isPaused && !isFixed,'stale':false }"
|
||||
:class="{
|
||||
'paused unnsynced': isPaused && !isFixed,
|
||||
'stale': false,
|
||||
'pannable': cursorStates.isPannable,
|
||||
'cursor-zoom-in': cursorStates.showCursorZoomIn,
|
||||
'cursor-zoom-out': cursorStates.showCursorZoomOut
|
||||
}"
|
||||
@click="expand"
|
||||
>
|
||||
<div
|
||||
v-if="zoomFactor > 1"
|
||||
class="c-imagery__hints"
|
||||
>Alt-drag to pan</div>
|
||||
<div
|
||||
ref="focusedImageWrapper"
|
||||
class="image-wrapper"
|
||||
:style="{
|
||||
'width': `${sizedImageDimensions.width}px`,
|
||||
'height': `${sizedImageDimensions.height}px`
|
||||
'width': `${sizedImageWidth}px`,
|
||||
'height': `${sizedImageHeight}px`
|
||||
}"
|
||||
@mousedown="handlePanZoomClick"
|
||||
>
|
||||
<img
|
||||
ref="focusedImage"
|
||||
class="c-imagery__main-image__image js-imageryView-image"
|
||||
class="c-imagery__main-image__image js-imageryView-image "
|
||||
:src="imageUrl"
|
||||
:draggable="!isSelectable"
|
||||
:style="{
|
||||
'filter': `brightness(${filters.brightness}%) contrast(${filters.contrast}%)`
|
||||
}"
|
||||
:data-openmct-image-timestamp="time"
|
||||
:data-openmct-object-keystring="keyString"
|
||||
>
|
||||
<div
|
||||
v-if="imageUrl"
|
||||
ref="focusedImageElement"
|
||||
class="c-imagery__main-image__background-image"
|
||||
:draggable="!isSelectable"
|
||||
:style="{
|
||||
'filter': `brightness(${filters.brightness}%) contrast(${filters.contrast}%)`,
|
||||
'background-image':
|
||||
`${imageUrl ? (
|
||||
`url(${imageUrl}),
|
||||
repeating-linear-gradient(
|
||||
45deg,
|
||||
transparent,
|
||||
transparent 4px,
|
||||
rgba(125,125,125,.2) 4px,
|
||||
rgba(125,125,125,.2) 8px
|
||||
)`
|
||||
) : ''}`,
|
||||
'transform': `scale(${zoomFactor}) translate(${imageTranslateX}px, ${imageTranslateY}px)`,
|
||||
'transition': `${!pan && animateZoom ? 'transform 250ms ease-in' : 'initial'}`,
|
||||
'width': `${sizedImageWidth}px`,
|
||||
'height': `${sizedImageHeight}px`,
|
||||
|
||||
}"
|
||||
></div>
|
||||
<Compass
|
||||
v-if="shouldDisplayCompass"
|
||||
:compass-rose-sizing-classes="compassRoseSizingClasses"
|
||||
@@ -134,7 +153,7 @@
|
||||
v-if="!isFixed"
|
||||
class="c-button icon-pause pause-play"
|
||||
:class="{'is-paused': isPaused}"
|
||||
@click="paused(!isPaused, 'button')"
|
||||
@click="paused(!isPaused)"
|
||||
></button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -156,7 +175,7 @@
|
||||
:key="image.url + image.time"
|
||||
class="c-imagery__thumb c-thumb"
|
||||
:class="{ selected: focusedImageIndex === index && isPaused }"
|
||||
@click="setFocusedImage(index, thumbnailClick)"
|
||||
@click="thumbnailClicked(index)"
|
||||
>
|
||||
<a
|
||||
href=""
|
||||
@@ -182,12 +201,13 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import eventHelpers from '../lib/eventHelpers';
|
||||
import _ from 'lodash';
|
||||
import moment from 'moment';
|
||||
|
||||
import RelatedTelemetry from './RelatedTelemetry/RelatedTelemetry';
|
||||
import Compass from './Compass/Compass.vue';
|
||||
|
||||
import ImageControls from './ImageControls.vue';
|
||||
import imageryData from "../../imagery/mixins/imageryData";
|
||||
|
||||
const REFRESH_CSS_MS = 500;
|
||||
@@ -207,9 +227,12 @@ const ARROW_LEFT = 37;
|
||||
|
||||
const SCROLL_LATENCY = 250;
|
||||
|
||||
const ZOOM_SCALE_DEFAULT = 1;
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Compass
|
||||
Compass,
|
||||
ImageControls
|
||||
},
|
||||
mixins: [imageryData],
|
||||
inject: ['openmct', 'domainObject', 'objectPath', 'currentView'],
|
||||
@@ -232,10 +255,6 @@ export default {
|
||||
timeSystem: timeSystem,
|
||||
keyString: undefined,
|
||||
autoScroll: true,
|
||||
filters: {
|
||||
brightness: 100,
|
||||
contrast: 100
|
||||
},
|
||||
thumbnailClick: THUMBNAIL_CLICKED,
|
||||
isPaused: false,
|
||||
refreshCSS: false,
|
||||
@@ -247,19 +266,37 @@ export default {
|
||||
focusedImageNaturalAspectRatio: undefined,
|
||||
imageContainerWidth: undefined,
|
||||
imageContainerHeight: undefined,
|
||||
sizedImageWidth: 0,
|
||||
sizedImageHeight: 0,
|
||||
lockCompass: true,
|
||||
resizingWindow: false,
|
||||
timeContext: undefined
|
||||
timeContext: undefined,
|
||||
zoomFactor: ZOOM_SCALE_DEFAULT,
|
||||
filters: {
|
||||
brightness: 100,
|
||||
contrast: 100
|
||||
},
|
||||
cursorStates: {
|
||||
isPannable: false,
|
||||
showCursorZoomIn: false,
|
||||
showCursorZoomOut: false,
|
||||
modifierKeyPressed: false
|
||||
},
|
||||
imageTranslateX: 0,
|
||||
imageTranslateY: 0,
|
||||
pan: undefined,
|
||||
animateZoom: true,
|
||||
imagePanned: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
compassRoseSizingClasses() {
|
||||
let compassRoseSizingClasses = '';
|
||||
if (this.sizedImageDimensions.width < 300) {
|
||||
if (this.sizedImageWidth < 300) {
|
||||
compassRoseSizingClasses = '--rose-small --rose-min';
|
||||
} else if (this.sizedImageDimensions.width < 500) {
|
||||
} else if (this.sizedImageWidth < 500) {
|
||||
compassRoseSizingClasses = '--rose-small';
|
||||
} else if (this.sizedImageDimensions.width > 1000) {
|
||||
} else if (this.sizedImageWidth > 1000) {
|
||||
compassRoseSizingClasses = '--rose-max';
|
||||
}
|
||||
|
||||
@@ -328,10 +365,18 @@ export default {
|
||||
return result;
|
||||
},
|
||||
shouldDisplayCompass() {
|
||||
return this.focusedImage !== undefined
|
||||
const imageHeightAndWidth = this.sizedImageHeight !== 0
|
||||
&& this.sizedImageWidth !== 0;
|
||||
|
||||
const display = this.focusedImage !== undefined
|
||||
&& this.focusedImageNaturalAspectRatio !== undefined
|
||||
&& this.imageContainerWidth !== undefined
|
||||
&& this.imageContainerHeight !== undefined;
|
||||
&& this.imageContainerHeight !== undefined
|
||||
&& imageHeightAndWidth
|
||||
&& this.zoomFactor === 1
|
||||
&& this.imagePanned !== true;
|
||||
|
||||
return display;
|
||||
},
|
||||
isSpacecraftPositionFresh() {
|
||||
let isFresh = undefined;
|
||||
@@ -393,20 +438,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;
|
||||
},
|
||||
isFixed() {
|
||||
let clock;
|
||||
if (this.timeContext) {
|
||||
@@ -416,6 +447,16 @@ export default {
|
||||
}
|
||||
|
||||
return clock === undefined;
|
||||
},
|
||||
isSelectable() {
|
||||
return true;
|
||||
|
||||
},
|
||||
sizedImageDimensions() {
|
||||
return {
|
||||
width: this.sizedImageWidth,
|
||||
height: this.sizedImageHeight
|
||||
};
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -424,16 +465,35 @@ export default {
|
||||
const newSize = newHistory.length;
|
||||
let imageIndex;
|
||||
if (this.focusedImageTimestamp !== undefined) {
|
||||
const foundImageIndex = this.imageHistory.findIndex(image => {
|
||||
return image.time === this.focusedImageTimestamp;
|
||||
});
|
||||
imageIndex = foundImageIndex > -1 ? foundImageIndex : newSize - 1;
|
||||
const foundImageIndex = newHistory.findIndex(img => img.time === this.focusedImageTimestamp);
|
||||
imageIndex = foundImageIndex > -1
|
||||
? foundImageIndex
|
||||
: newSize - 1;
|
||||
} else {
|
||||
imageIndex = newSize > 0 ? newSize - 1 : undefined;
|
||||
imageIndex = newSize > 0
|
||||
? newSize - 1
|
||||
: undefined;
|
||||
}
|
||||
|
||||
this.setFocusedImage(imageIndex, false);
|
||||
this.scrollToRight();
|
||||
this.nextImageIndex = imageIndex;
|
||||
|
||||
if (this.previousFocusedImage && newHistory.length) {
|
||||
const matchIndex = this.matchIndexOfPreviousImage(
|
||||
this.previousFocusedImage,
|
||||
newHistory
|
||||
);
|
||||
|
||||
if (matchIndex > -1) {
|
||||
this.setFocusedImage(matchIndex);
|
||||
} else {
|
||||
this.paused();
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.isPaused) {
|
||||
this.setFocusedImage(imageIndex);
|
||||
this.scrollToRight();
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
@@ -445,6 +505,10 @@ export default {
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
eventHelpers.extend(this);
|
||||
this.focusedImageWrapper = this.$refs.focusedImageWrapper;
|
||||
this.focusedImageElement = this.$refs.focusedImageElement;
|
||||
|
||||
//We only need to use this till the user focuses an image manually
|
||||
if (this.focusedImageTimestamp !== undefined) {
|
||||
this.isPaused = true;
|
||||
@@ -485,6 +549,7 @@ export default {
|
||||
this.thumbWrapperResizeObserver.observe(this.$refs.thumbsWrapper);
|
||||
}
|
||||
|
||||
this.listenTo(this.focusedImageWrapper, 'wheel', this.wheelZoom, this);
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.stopFollowingTimeContext();
|
||||
@@ -509,6 +574,9 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.stopListening(this.focusedImageWrapper, 'wheel', this.wheelZoom, this);
|
||||
|
||||
},
|
||||
methods: {
|
||||
setTimeContext() {
|
||||
@@ -525,6 +593,11 @@ export default {
|
||||
}
|
||||
},
|
||||
expand() {
|
||||
// check for modifier keys so it doesnt interfere with the layout
|
||||
if (this.cursorStates.modifierKeyPressed) {
|
||||
return;
|
||||
}
|
||||
|
||||
const actionCollection = this.openmct.actions.getActionsCollection(this.objectPath, this.currentView);
|
||||
const visibleActions = actionCollection.getVisibleActions();
|
||||
const viewLargeAction = visibleActions
|
||||
@@ -630,6 +703,7 @@ export default {
|
||||
focusElement() {
|
||||
this.$el.focus();
|
||||
},
|
||||
|
||||
handleScroll() {
|
||||
const thumbsWrapper = this.$refs.thumbsWrapper;
|
||||
if (!thumbsWrapper || this.resizingWindow) {
|
||||
@@ -640,20 +714,15 @@ export default {
|
||||
const disableScroll = scrollWidth > Math.ceil(scrollLeft + clientWidth);
|
||||
this.autoScroll = !disableScroll;
|
||||
},
|
||||
paused(state, type) {
|
||||
this.isPaused = state;
|
||||
paused(state) {
|
||||
this.isPaused = Boolean(state);
|
||||
|
||||
if (type === 'button') {
|
||||
this.setFocusedImage(this.imageHistory.length - 1);
|
||||
}
|
||||
|
||||
if (this.nextImageIndex) {
|
||||
if (!state) {
|
||||
this.previousFocusedImage = null;
|
||||
this.setFocusedImage(this.nextImageIndex);
|
||||
delete this.nextImageIndex;
|
||||
this.autoScroll = true;
|
||||
this.scrollToRight();
|
||||
}
|
||||
|
||||
this.autoScroll = true;
|
||||
this.scrollToRight();
|
||||
},
|
||||
scrollToFocused() {
|
||||
const thumbsWrapper = this.$refs.thumbsWrapper;
|
||||
@@ -692,51 +761,24 @@ export default {
|
||||
&& x.time === previous.time
|
||||
));
|
||||
},
|
||||
setFocusedImage(index, thumbnailClick = false) {
|
||||
let focusedIndex = index;
|
||||
thumbnailClicked(index) {
|
||||
this.setFocusedImage(index);
|
||||
this.paused(true);
|
||||
|
||||
this.setPreviousFocusedImage(index);
|
||||
},
|
||||
setPreviousFocusedImage(index) {
|
||||
this.focusedImageTimestamp = undefined;
|
||||
this.previousFocusedImage = this.imageHistory[index]
|
||||
? JSON.parse(JSON.stringify(this.imageHistory[index]))
|
||||
: undefined;
|
||||
},
|
||||
setFocusedImage(index) {
|
||||
if (!(Number.isInteger(index) && index > -1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (thumbnailClick) {
|
||||
//We use the props till the user changes what they want to see
|
||||
this.focusedImageTimestamp = undefined;
|
||||
//set the previousFocusedImage when a user chooses an image
|
||||
this.previousFocusedImage = this.imageHistory[focusedIndex] ? JSON.parse(JSON.stringify(this.imageHistory[focusedIndex])) : undefined;
|
||||
}
|
||||
|
||||
if (this.previousFocusedImage) {
|
||||
// determine if the previous image exists in the new bounds of imageHistory
|
||||
if (!thumbnailClick) {
|
||||
const matchIndex = this.matchIndexOfPreviousImage(
|
||||
this.previousFocusedImage,
|
||||
this.imageHistory
|
||||
);
|
||||
focusedIndex = matchIndex > -1 ? matchIndex : this.imageHistory.length - 1;
|
||||
}
|
||||
|
||||
if (!(this.isPaused || thumbnailClick)
|
||||
|| focusedIndex === this.imageHistory.length - 1) {
|
||||
delete this.previousFocusedImage;
|
||||
}
|
||||
}
|
||||
|
||||
this.focusedImageIndex = focusedIndex;
|
||||
|
||||
//TODO: do we even need this anymore?
|
||||
if (this.isPaused && !thumbnailClick && this.focusedImageTimestamp === undefined) {
|
||||
this.nextImageIndex = focusedIndex;
|
||||
//this could happen if bounds changes
|
||||
if (this.focusedImageIndex > this.imageHistory.length - 1) {
|
||||
this.focusedImageIndex = focusedIndex;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (thumbnailClick && !this.isPaused) {
|
||||
this.paused(true);
|
||||
}
|
||||
this.focusedImageIndex = index;
|
||||
},
|
||||
trackDuration() {
|
||||
if (this.canTrackDuration) {
|
||||
@@ -774,7 +816,7 @@ export default {
|
||||
|
||||
let index = this.focusedImageIndex;
|
||||
|
||||
this.setFocusedImage(++index, THUMBNAIL_CLICKED);
|
||||
this.thumbnailClicked(++index);
|
||||
if (index === this.imageHistory.length - 1) {
|
||||
this.paused(false);
|
||||
}
|
||||
@@ -787,14 +829,50 @@ export default {
|
||||
let index = this.focusedImageIndex;
|
||||
|
||||
if (index === this.imageHistory.length - 1) {
|
||||
this.setFocusedImage(this.imageHistory.length - 2, THUMBNAIL_CLICKED);
|
||||
this.thumbnailClicked(this.imageHistory.length - 2);
|
||||
} else {
|
||||
this.setFocusedImage(--index, THUMBNAIL_CLICKED);
|
||||
this.thumbnailClicked(--index);
|
||||
}
|
||||
},
|
||||
startDrag(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
resetImage() {
|
||||
this.imagePanned = false;
|
||||
this.zoomFactor = ZOOM_SCALE_DEFAULT;
|
||||
this.imageTranslateX = 0;
|
||||
this.imageTranslateY = 0;
|
||||
},
|
||||
handlePanZoomUpdate({ newScaleFactor, screenClientX, screenClientY }) {
|
||||
if (!this.isPaused) {
|
||||
this.paused(true);
|
||||
}
|
||||
|
||||
if (!(screenClientX || screenClientY)) {
|
||||
return this.updatePanZoom(newScaleFactor, 0, 0);
|
||||
}
|
||||
|
||||
// handle mouse events
|
||||
const imageRect = this.focusedImageWrapper.getBoundingClientRect();
|
||||
const imageContainerX = screenClientX - imageRect.left;
|
||||
const imageContainerY = screenClientY - imageRect.top;
|
||||
const offsetFromCenterX = (imageRect.width / 2) - imageContainerX;
|
||||
const offsetFromCenterY = (imageRect.height / 2) - imageContainerY;
|
||||
|
||||
this.updatePanZoom(newScaleFactor, offsetFromCenterX, offsetFromCenterY);
|
||||
},
|
||||
updatePanZoom(newScaleFactor, offsetFromCenterX, offsetFromCenterY) {
|
||||
const currentScale = this.zoomFactor;
|
||||
const previousTranslateX = this.imageTranslateX;
|
||||
const previousTranslateY = this.imageTranslateY;
|
||||
|
||||
const offsetXInOriginalScale = offsetFromCenterX / currentScale;
|
||||
const offsetYInOriginalScale = offsetFromCenterY / currentScale;
|
||||
const translateX = offsetXInOriginalScale + previousTranslateX;
|
||||
const translateY = offsetYInOriginalScale + previousTranslateY;
|
||||
this.imageTranslateX = translateX;
|
||||
this.imageTranslateY = translateY;
|
||||
this.zoomFactor = newScaleFactor;
|
||||
},
|
||||
handlePanZoomClick(e) {
|
||||
this.$refs.imageControls.handlePanZoomClick(e);
|
||||
},
|
||||
arrowDownHandler(event) {
|
||||
let key = event.keyCode;
|
||||
@@ -857,7 +935,7 @@ export default {
|
||||
|
||||
// TODO - should probably cache this
|
||||
img.addEventListener('load', () => {
|
||||
this.focusedImageNaturalAspectRatio = img.naturalWidth / img.naturalHeight;
|
||||
this.setSizedImageDimensions();
|
||||
}, { once: true });
|
||||
},
|
||||
resizeImageContainer() {
|
||||
@@ -872,6 +950,21 @@ export default {
|
||||
if (this.$refs.imageBG.clientHeight !== this.imageContainerHeight) {
|
||||
this.imageContainerHeight = this.$refs.imageBG.clientHeight;
|
||||
}
|
||||
|
||||
this.setSizedImageDimensions();
|
||||
},
|
||||
setSizedImageDimensions() {
|
||||
this.focusedImageNaturalAspectRatio = this.$refs.focusedImage.naturalWidth / this.$refs.focusedImage.naturalHeight;
|
||||
|
||||
if ((this.imageContainerWidth / this.imageContainerHeight) > this.focusedImageNaturalAspectRatio) {
|
||||
// container is wider than image
|
||||
this.sizedImageWidth = this.imageContainerHeight * this.focusedImageNaturalAspectRatio;
|
||||
this.sizedImageHeight = this.imageContainerHeight;
|
||||
} else {
|
||||
// container is taller than image
|
||||
this.sizedImageWidth = this.imageContainerWidth;
|
||||
this.sizedImageHeight = this.imageContainerWidth / this.focusedImageNaturalAspectRatio;
|
||||
}
|
||||
},
|
||||
handleThumbWindowResizeStart() {
|
||||
if (!this.autoScroll) {
|
||||
@@ -890,6 +983,73 @@ export default {
|
||||
this.$nextTick(() => {
|
||||
this.resizingWindow = false;
|
||||
});
|
||||
},
|
||||
// debounced method
|
||||
clearWheelZoom() {
|
||||
this.$refs.imageControls.clearWheelZoom();
|
||||
},
|
||||
wheelZoom(e) {
|
||||
e.preventDefault();
|
||||
if (!this.isPaused) {
|
||||
this.paused(true);
|
||||
}
|
||||
|
||||
this.$refs.imageControls.wheelZoom(e);
|
||||
},
|
||||
startPan(e) {
|
||||
e.preventDefault();
|
||||
if (!this.pan && this.zoomFactor > 1) {
|
||||
this.animateZoom = false;
|
||||
this.imagePanned = true;
|
||||
this.pan = {
|
||||
x: e.clientX,
|
||||
y: e.clientY
|
||||
};
|
||||
this.listenTo(window, 'mouseup', this.onMouseUp, this);
|
||||
this.listenTo(window, 'mousemove', this.trackMousePosition, this);
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
trackMousePosition(e) {
|
||||
if (!e.altKey) {
|
||||
return this.onMouseUp(e);
|
||||
}
|
||||
|
||||
this.updatePan(e);
|
||||
e.preventDefault();
|
||||
|
||||
},
|
||||
updatePan(e) {
|
||||
if (!this.pan) {
|
||||
return;
|
||||
}
|
||||
|
||||
const dX = e.clientX - this.pan.x;
|
||||
const dY = e.clientY - this.pan.y;
|
||||
this.pan = {
|
||||
x: e.clientX,
|
||||
y: e.clientY
|
||||
};
|
||||
this.updatePanZoom(this.zoomFactor, dX, dY);
|
||||
},
|
||||
endPan() {
|
||||
this.pan = undefined;
|
||||
this.animateZoom = true;
|
||||
},
|
||||
onMouseUp(event) {
|
||||
this.stopListening(window, 'mouseup', this.onMouseUp, this);
|
||||
this.stopListening(window, 'mousemove', this.trackMousePosition, this);
|
||||
|
||||
if (this.pan) {
|
||||
return this.endPan(event);
|
||||
}
|
||||
},
|
||||
setFilters(filtersObj) {
|
||||
this.filters = filtersObj;
|
||||
},
|
||||
setCursorStates(states) {
|
||||
this.cursorStates = states;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user