diff --git a/src/essence/Ancillary/TimeUI.css b/src/essence/Ancillary/TimeUI.css
index 05f33818b..ca02e41d3 100644
--- a/src/essence/Ancillary/TimeUI.css
+++ b/src/essence/Ancillary/TimeUI.css
@@ -101,9 +101,10 @@
}
#mmgisTimeUITimelineSlider .rangeBar {
background: var(--color-h);
- height: 2px;
+ height: 4px;
opacity: 0.75;
pointer-events: none;
+ margin-top: -1px;
}
#mmgisTimeUITimelineSlider .rangeSlider {
height: 0px;
@@ -230,22 +231,39 @@
background: var(--color-a-5);
width: 80px;
}
+#mmgisTimeUIStepWithinBeyondDropdown {
+ background: var(--color-a-5);
+ width: 110px;
+}
#mmgisTimeUIStepDropdown {
+ background: var(--color-a-5);
width: 80px;
}
#mmgisTimeUIRateDropdown {
- width: 60px;
+ background: var(--color-a-5);
+ width: 110px;
}
#mmgisTimeUIModeDropdown .dropy__title i,
+#mmgisTimeUIStepWithinBeyondDropdown .dropy__title i,
#mmgisTimeUIStepDropdown .dropy__title i,
#mmgisTimeUIRateDropdown .dropy__title i {
color: var(--color-a5);
}
-#mmgisTimeUIModeDropdown .dropy__title span,
+#mmgisTimeUIStepDropdown .dropy__title i,
+#mmgisTimeUIStepWithinBeyondDropdown .dropy__title i,
+#mmgisTimeUIRateDropdown .dropy__title i {
+ line-height: 15px;
+}
+#mmgisTimeUIModeDropdown .dropy__title span {
+ font-size: 12px;
+ padding: 14px 0px 14px 12px;
+ color: var(--color-a5);
+}
+#mmgisTimeUIStepWithinBeyondDropdown .dropy__title span,
#mmgisTimeUIStepDropdown .dropy__title span,
#mmgisTimeUIRateDropdown .dropy__title span {
font-size: 12px;
- padding: 14px 0px 14px 12px;
+ padding: 9px 0px 7px 12px;
color: var(--color-a5);
}
#mmgisTimeUIModeDropdown .dropy__title span {
@@ -254,6 +272,7 @@
}
#mmgisTimeUIModeDropdown li a,
+#mmgisTimeUIStepWithinBeyondDropdown li a,
#mmgisTimeUIStepDropdown li a,
#mmgisTimeUIRateDropdown li a {
font-size: 13px;
@@ -269,3 +288,99 @@
#mmgisTimeUIEndWrapperFake {
right: 0;
}
+
+#mmgisTimeUIFitTime,
+#mmgisTimeUIFitWindow,
+#mmgisTimeUIPresent {
+ color: var(--color-a5);
+ transition: color 0.2s ease-out;
+}
+
+#mmgisTimeUIFitTime:hover,
+#mmgisTimeUIFitWindow:hover,
+#mmgisTimeUIPresent:hover {
+ color: var(--color-a7);
+}
+
+#mmgisTimeUIPlayTrigger {
+ margin: 0;
+ width: 40px;
+ height: 40px;
+ line-height: 40px;
+ color: var(--color-a5);
+}
+
+#timeUIPlayPopover {
+ display: none;
+ background: var(--color-a);
+ box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.4);
+ width: 160px;
+ border-top: 1px solid var(--color-a1);
+ border-bottom: 1px solid var(--color-a1);
+ transition: left 0.2s ease-out;
+}
+
+#mmgisTimeUIPopoverBottom {
+ display: flex;
+ justify-content: space-between;
+}
+
+#mmgisTimeUIStepWithinBeyond,
+#mmgisTimeUIStep,
+#mmgisTimeUIRate {
+ display: flex;
+ justify-content: space-between;
+ height: 30px;
+ padding-left: 8px;
+ border-bottom: 1px solid var(--color-a1);
+}
+#mmgisTimeUIStepWithinBeyond > div:first-child,
+#mmgisTimeUIStep > div:first-child,
+#mmgisTimeUIRate > div:first-child {
+ line-height: 30px;
+ font-size: 13px;
+ color: var(--color-a6);
+}
+#mmgisTimeUIPlay {
+ width: 100%;
+ background: var(--color-a1);
+}
+#mmgisTimeUIBottomPrevious {
+ width: 50%;
+ margin-right: 2.5px;
+ background: var(--color-a1);
+}
+#mmgisTimeUIBottomNext {
+ width: 50%;
+ margin-left: 2.5px;
+ background: var(--color-a1);
+}
+#mmgisTimeUIPlay:hover,
+#mmgisTimeUIBottomPrevious:hover,
+#mmgisTimeUIBottomNext:hover {
+ background: var(--color-a2);
+}
+
+#timeUIPlayPopover input[type='number'] {
+ background: var(--color-a-5);
+ width: 30px;
+ color: #ccc;
+ text-align: right;
+ padding: 0px 5px;
+ border: 0px solid rgba(255, 255, 255, 0);
+ border-right: 1px solid var(--color-a1);
+}
+
+#mmgisTimeUITimelinePlayExtent {
+ opacity: 0;
+ height: 100%;
+ position: absolute;
+ background: #601a2e;
+ transition: opacity 0.2s ease-out;
+}
+#mmgisTimeUITimelineExtent {
+ height: 100%;
+ position: absolute;
+ background: rgb(96, 78, 26, 0.7);
+ transition: opacity 0.2s ease-out;
+}
diff --git a/src/essence/Ancillary/TimeUI.js b/src/essence/Ancillary/TimeUI.js
index 941c9d88b..16e400a29 100644
--- a/src/essence/Ancillary/TimeUI.js
+++ b/src/essence/Ancillary/TimeUI.js
@@ -22,14 +22,14 @@ import './TimeUI.css'
const FORMAT = 'MM/DD/yyyy, hh:mm:ss A'
const MS = {
- decade: 315576000000,
- year: 31557600000,
- month: 2629800000,
- week: 604800000,
- day: 86400000,
- hour: 3600000,
- minute: 60000,
second: 1000,
+ minute: 60000,
+ hour: 3600000,
+ day: 86400000,
+ week: 604800000,
+ month: 2629800000,
+ year: 31557600000,
+ decade: 315576000000,
}
const TimeUI = {
@@ -43,19 +43,23 @@ const TimeUI = {
_timelineEndTimestamp: null,
now: false,
numFrames: 24,
+ durationIndex: 0,
+ stepWithinBeyondIndex: 0,
intervalIndex: 6,
- intervalValues: [100, 250, 500, 1000, 2000, 3000, 4000, 5000, 10000, 20000],
+ intervalValues: [
+ 100, 250, 500, 1000, 2000, 4000, 6000, 8000, 10000, 15000, 20000,
+ ],
intervalNames: [
- '.1s',
- '.25s',
- '0.5s',
- '1s',
- '2s',
- '3s',
- '4s',
- '5s',
- '10s',
- '20s',
+ '.1 seconds',
+ '.25 seconds',
+ '0.5 seconds',
+ '1 second',
+ '2 seconds',
+ '4 seconds',
+ '6 seconds',
+ '8 seconds',
+ '10 seconds',
+ '15 seconds',
],
stepIndex: 3,
modes: ['Range', 'Point'],
@@ -73,18 +77,10 @@ const TimeUI = {
`
`,
- ``,
- ``,
- ``,
- `
`,
- ``,
- ``,
- `
`,
+ `
`,
+ ``,
`
`,
`
`,
- `
`,
`
`,
``,
`
`,
@@ -96,6 +92,8 @@ const TimeUI = {
``,
`
`,
`
`,
+ `
`,
+ `
`,
`
`,
`
`,
`
`,
@@ -110,6 +108,12 @@ const TimeUI = {
`
`,
`
`,
``,
+ `
`,
+ ``,
+ `
`,
+ `
`,
+ ``,
+ `
`,
`
`,
``,
`
`,
@@ -123,11 +127,49 @@ const TimeUI = {
`
`
].join('\n')
+ // prettier-ignore
+ const playPopoverMarkup = [
+ ``,
+ `
`,
+ `
`,
+ `
`,
+
+ `
`,
+ `
`,
+ ``,
+ `
`,
+ `
`,
+ ``,
+ `
`,
+ `
`,
+ ``,
+ `
`,
+ `
`,
+ `
`,
+ ].join('\n')
+
d3.select('#splitscreens')
.append('div')
.attr('id', 'timeUI')
.html(markup)
+ d3.select('body')
+ .append('div')
+ .attr('id', 'timeUIPlayPopover_global')
+ .html(playPopoverMarkup)
+
TimeUI.attachEvents()
return TimeUI
@@ -155,12 +197,56 @@ const TimeUI = {
}
return { dateString, additionalSeconds }
},
+ alignPopovers(e) {
+ if (e == null) {
+ let bcr = $(`#mmgisTimeUIPlayTrigger`)
+ .get(0)
+ .getBoundingClientRect()
+ $(`#timeUIPlayPopover`).css({
+ position: 'fixed',
+ left: bcr.left,
+ right: bcr.right,
+ bottom: 40,
+ })
+ } else {
+ setTimeout(() => {
+ TimeUI.alignPopovers()
+ }, 200)
+ }
+ },
attachEvents: function (timeChange) {
TimeUI._startingModeIndex = TimeUI.modeIndex
// Set modeIndex to 1/Point if a deeplink had an endtime but no starttime
if (L_.FUTURES.startTime == null && L_.FUTURES.endTime != null)
TimeUI._startingModeIndex = 1
+ document.addEventListener('toolChange', TimeUI.alignPopovers)
+
+ // Popovers
+ $(`#mmgisTimeUIPlayTrigger`).on('click', () => {
+ const pop = $(`#timeUIPlayPopover`)
+ const willOpen = pop.css('display') === 'none'
+
+ pop.css({
+ display: willOpen ? 'block' : 'none',
+ })
+ $(`#mmgisTimeUIPlayTrigger`).css({
+ color: willOpen ? 'var(--color-c)' : 'var(--color-a5)',
+ })
+ if (willOpen) {
+ $('#mmgisTimeUIPlayTrigger > i')
+ .removeClass('mdi-movie')
+ .addClass('mdi-movie-open')
+ TimeUI._popoverPlayOpen = true
+ TimeUI.alignPopovers()
+ } else {
+ $('#mmgisTimeUIPlayTrigger > i')
+ .removeClass('mdi-movie-open')
+ .addClass('mdi-movie')
+ TimeUI._popoverPlayOpen = false
+ }
+ })
+
// Timeline pan and zoom
// zoom
$('#mmgisTimeUITimelineInner').on('wheel', function (e) {
@@ -196,24 +282,23 @@ const TimeUI = {
})
// pan
- $('#mmgisTimeUITimelineInner').on('mousedown', function () {
+ $('#mmgisTimeUITimelineInner').on('mousedown', function (e) {
if (TimeUI.play) {
TimeUI._timelineDragging = false
return
}
TimeUI._timelineDragging = true
$('#mmgisTimeUITimelineSlider').css({ pointerEvents: 'none' })
- $('#mmgisTimeUITimelineInner').on('mousemove', TimeUI._timelineDrag)
+ TimeUI._lastDragPageX = e.originalEvent.pageX
+ $('body').on('mousemove', TimeUI._timelineDrag)
})
$('body').on('mouseup', function () {
if (TimeUI._timelineDragging === true) {
$('#mmgisTimeUITimelineSlider').css({
pointerEvents: 'inherit',
})
- $('#mmgisTimeUITimelineInner').off(
- 'mousemove',
- TimeUI._timelineDrag
- )
+ $('#mmgisTimeUITimelineInner').off('body', TimeUI._timelineDrag)
+ TimeUI._lastDragPageX = 0
TimeUI._timelineDragging = false
}
})
@@ -332,18 +417,24 @@ const TimeUI = {
placement: 'top',
theme: 'blue',
})
+ tippy('#mmgisTimeUIPlayTrigger', {
+ content: 'Play',
+ placement: 'top',
+ theme: 'blue',
+ })
+
tippy('#mmgisTimeUIPlay', {
content: 'Play / Pause',
placement: 'top',
theme: 'blue',
})
- tippy('#mmgisTimeUIStep', {
- content: 'Step Size',
+ tippy('#mmgisTimeUIFitTime', {
+ content: 'Fit Time to Time-Window',
placement: 'top',
theme: 'blue',
})
- tippy('#mmgisTimeUIRate', {
- content: 'Step Duration',
+ tippy('#mmgisTimeUIFitWindow', {
+ content: 'Fit Time-Window to Time',
placement: 'top',
theme: 'blue',
})
@@ -367,10 +458,37 @@ const TimeUI = {
Dropy.init($('#mmgisTimeUIModeDropdown'), TimeUI.changeMode)
+ // Step WithinBeyond dropdown
+ $('#mmgisTimeUIStepWithinBeyondDropdown').html(
+ Dropy.construct(
+ ['Playback', 'Shift'],
+ 'Mode',
+ TimeUI.stepWithinBeyondIndex,
+ {
+ openUp: true,
+ dark: true,
+ }
+ )
+ )
+ Dropy.init($('#mmgisTimeUIStepWithinBeyondDropdown'), function (idx) {
+ TimeUI.stepWithinBeyondIndex = idx
+ if (idx === 0) {
+ $('#mmgisTimeUIPlay').css('display', 'block')
+ $('#mmgisTimeUIRate').css('display', 'flex')
+ $('#mmgisTimeUIBottomPrevious').css('display', 'none')
+ $('#mmgisTimeUIBottomNext').css('display', 'none')
+ } else if (idx === 1) {
+ $('#mmgisTimeUIPlay').css('display', 'none')
+ $('#mmgisTimeUIRate').css('display', 'none')
+ $('#mmgisTimeUIBottomPrevious').css('display', 'block')
+ $('#mmgisTimeUIBottomNext').css('display', 'block')
+ }
+ TimeUI._refreshIntervals()
+ })
// Step dropdown
$('#mmgisTimeUIStepDropdown').html(
Dropy.construct(
- Object.keys(MS).map((k) => k.capitalizeFirstLetter()),
+ Object.keys(MS).map((k) => `${k.capitalizeFirstLetter()}`),
'Step',
TimeUI.stepIndex,
{
@@ -400,6 +518,39 @@ const TimeUI = {
TimeUI._refreshIntervals()
})
+ // Interval Duration dropdown
+ $('#mmgisTimeUIIntervalDurationDropdown').html(
+ Dropy.construct(
+ Object.keys(MS).map((k) => `1 ${k.capitalizeFirstLetter()}`),
+ 'Step',
+ TimeUI.stepIndex,
+ {
+ openUp: true,
+ dark: true,
+ }
+ )
+ )
+ Dropy.init($('#mmgisTimeUIIntervalDurationDropdown'), function (idx) {
+ TimeUI.stepIndex = idx
+ TimeUI._refreshIntervals()
+ })
+ // Interval Step dropdown
+ $('#mmgisTimeUIIntervalStepDropdown').html(
+ Dropy.construct(
+ TimeUI.intervalNames,
+ 'Rate',
+ TimeUI.intervalIndex,
+ {
+ openUp: true,
+ dark: true,
+ }
+ )
+ )
+ Dropy.init($('#mmgisTimeUIIntervalStepDropdown'), function (idx) {
+ TimeUI.intervalIndex = idx
+ TimeUI._refreshIntervals()
+ })
+
let dateAddSec = null
// Initial end
@@ -565,6 +716,10 @@ const TimeUI = {
TimeUI.startTempus.dates.setValue(parsedStart)
$('#mmgisTimeUIPlay').on('click', TimeUI.togglePlay)
+ $('#mmgisTimeUIBottomPrevious').on('click', TimeUI.stepPrevious)
+ $('#mmgisTimeUIBottomNext').on('click', TimeUI.stepNext)
+ $('#mmgisTimeUIFitTime').on('click', TimeUI.fitTimeToWindow)
+ $('#mmgisTimeUIFitWindow').on('click', TimeUI.fitWindowToTime)
$('#mmgisTimeUIPresent').on('click', TimeUI.toggleTimeNow)
TimeUI._remakeTimeSlider()
@@ -590,6 +745,9 @@ const TimeUI = {
minDate: new Date(0),
},
})
+ TimeUI._savedRangeModeStartTime = TimeUI._startTimestamp
+ TimeUI.updateTimes(TimeUI.removeOffset(0), null, null)
+ $('#mmgisTimeUITimelineExtent').css('opacity', 0)
} else {
$('#mmgisTimeUIStartWrapper').css({ display: 'inherit' })
// Reinforce min date
@@ -598,6 +756,12 @@ const TimeUI = {
minDate: TimeUI.startTempusSavedLastDate,
},
})
+ if (TimeUI._savedRangeModeStartTime != null)
+ TimeUI.updateTimes(
+ TimeUI.removeOffset(TimeUI._savedRangeModeStartTime),
+ null,
+ null
+ )
if (TimeUI._startTimestamp >= TimeUI._endTimestamp) {
const offsetStartDate = new Date(TimeUI._endTimestamp)
const parsedStart = TimeUI.startTempus.dates.parseInput(
@@ -605,22 +769,38 @@ const TimeUI = {
)
TimeUI.startTempus.dates.setValue(parsedStart)
}
+ $('#mmgisTimeUITimelineExtent').css('opacity', 1)
}
TimeUI._remakeTimeSlider(true)
},
- togglePlay(force) {
+ stepPrevious() {
+ TimeUI._loopTime(true)
+ if (TimeUI.modes[TimeUI.modeIndex] === 'Range')
+ TimeUI.fitWindowToTime(true)
+ },
+ stepNext() {
+ TimeUI._loopTime()
+ if (TimeUI.modes[TimeUI.modeIndex] === 'Range')
+ TimeUI.fitWindowToTime(true)
+ },
+ togglePlay(force, butDontActuallyPlay, dontRedrawExtent) {
const mode = TimeUI.modes[TimeUI.modeIndex]
if (TimeUI.play || force === false) {
$('#mmgisTimeUIPlay')
.css('background', '')
- .css('color', 'var(--color-a4)')
+ .css('color', 'var(--color-a5)')
$('#mmgisTimeUIPlay > i')
.removeClass('mdi-pause')
.addClass('mdi-play')
+
+ $('#mmgisTimeUITimelineExtent').css('opacity', 1)
+ $('#mmgisTimeUITimelinePlayExtent').css('opacity', 0)
TimeUI.play = false
// Don't reposition active time on Stop for Point Mode
- if (mode === 'Point') TimeUI._savedPlayEnd = null
+ if (mode === 'Point') {
+ TimeUI._savedPlayEnd = null
+ }
// But do for Range Mode
if (TimeUI._savedPlayEnd != null) {
@@ -639,13 +819,90 @@ const TimeUI = {
TimeUI.play = true
TimeUI._savedPlayEnd = TimeUI.getCurrentTimestamp()
TimeUI.now = false
+
+ if (
+ (dontRedrawExtent !== true ||
+ $('#mmgisTimeUITimelinePlayExtent').css('opacity') !==
+ '1') &&
+ TimeUI.stepWithinBeyondIndex !== 1
+ ) {
+ $('#mmgisTimeUITimelineExtent').css('opacity', 0)
+ if (mode === 'Point') {
+ $('#mmgisTimeUITimelinePlayExtent')
+ .css('opacity', 1)
+ .css('width', `100%`)
+ .css('left', `0px`)
+ } else {
+ const timelineBCR = document
+ .getElementById('mmgisTimeUITimeline')
+ .getBoundingClientRect()
+ const left = F_.linearScale(
+ [
+ TimeUI._timelineStartTimestamp,
+ TimeUI._timelineEndTimestamp,
+ ],
+ [0, timelineBCR.width],
+ TimeUI.removeOffset(TimeUI._startTimestamp)
+ )
+ const right = F_.linearScale(
+ [
+ TimeUI._timelineStartTimestamp,
+ TimeUI._timelineEndTimestamp,
+ ],
+ [0, timelineBCR.width],
+ TimeUI.removeOffset(TimeUI._savedPlayEnd)
+ )
+ $('#mmgisTimeUITimelinePlayExtent')
+ .css('opacity', 1)
+ .css(
+ 'width',
+ `${((right - left) / timelineBCR.width) * 100}%`
+ )
+ .css('left', `${(left / timelineBCR.width) * 100}%`)
+ }
+ }
+
$('#mmgisTimeUIPresent')
.css('background', '')
.css('color', 'var(--color-a4)')
$('#mmgisTimeUIEnd').css('pointer-events', 'inherit')
$('#mmgisTimeUIEndWrapper').css('cursor', 'inherit')
}
- TimeUI._refreshIntervals()
+ if (butDontActuallyPlay !== true) TimeUI._refreshIntervals()
+ },
+ _updateExtentIndicator(forceStartTimestamp, forceEndTimestamp) {
+ if (TimeUI.play) return
+
+ const mode = TimeUI.modes[TimeUI.modeIndex]
+
+ if (mode === 'Point') {
+ } else {
+ const timelineBCR = document
+ .getElementById('mmgisTimeUITimeline')
+ .getBoundingClientRect()
+ const left = F_.linearScale(
+ [TimeUI._timelineStartTimestamp, TimeUI._timelineEndTimestamp],
+ [0, timelineBCR.width],
+ TimeUI.removeOffset(
+ forceStartTimestamp != null
+ ? forceStartTimestamp
+ : TimeUI._startTimestamp
+ )
+ )
+ const right = F_.linearScale(
+ [TimeUI._timelineStartTimestamp, TimeUI._timelineEndTimestamp],
+ [0, timelineBCR.width],
+ TimeUI.removeOffset(
+ forceEndTimestamp != null
+ ? forceEndTimestamp
+ : TimeUI._endTimestamp
+ )
+ )
+ $('#mmgisTimeUITimelineExtent')
+ .css('opacity', 1)
+ .css('width', `${((right - left) / timelineBCR.width) * 100}%`)
+ .css('left', `${(left / timelineBCR.width) * 100}%`)
+ }
},
_refreshIntervals() {
clearInterval(TimeUI.playInterval)
@@ -665,7 +922,7 @@ const TimeUI = {
)
}
},
- _loopTime() {
+ _loopTime(loopBackwards) {
const mode = TimeUI.modes[TimeUI.modeIndex]
const start =
mode === 'Range'
@@ -677,15 +934,93 @@ const TimeUI = {
? TimeUI._endTimestamp
: TimeUI._timelineEndTimestamp
const current = TimeUI.getCurrentTimestamp()
+ const change =
+ (loopBackwards === true ? -1 : 1) *
+ (MS[Object.keys(MS)[TimeUI.stepIndex]] *
+ parseFloat($('#mmgisTimeUIRateInput').val() || 1))
- let next = current + MS[Object.keys(MS)[TimeUI.stepIndex]]
- if (next > end) next = end
- if (current === end) next = start
+ let next = current + change
- if (mode === 'Range') TimeUI.setCurrentTime(next)
- if (mode === 'Point') TimeUI.setCurrentTime(next, null, null, true)
+ if (TimeUI.stepWithinBeyondIndex === 0 || mode === 'Point') {
+ if (mode === 'Point' && TimeUI.play !== true) {
+ // Just push point in time forward
+ TimeUI.updateTimes(null, TimeUI.removeOffset(next), next)
+ } else {
+ // Otherwise, keep within the time window for playback
+ if (next > end) next = end
+ if (current === end) next = start
- TimeUI._remakeTimeSlider(true)
+ if (mode === 'Range') TimeUI.setCurrentTime(next)
+ if (mode === 'Point')
+ TimeUI.setCurrentTime(next, null, null, true)
+ }
+
+ TimeUI._remakeTimeSlider(true)
+ } else {
+ let nextStart = TimeUI._startTimestamp + change
+ TimeUI.updateTimes(
+ TimeUI.removeOffset(nextStart),
+ TimeUI.removeOffset(next),
+ null
+ )
+ }
+ },
+ fitTimeToWindow() {
+ let nextStart
+ let nextEnd
+
+ nextStart =
+ TimeUI._timelineEndTimestamp != null
+ ? TimeUI._timelineStartTimestamp
+ : 0
+ nextEnd =
+ TimeUI._timelineStartTimestamp != null
+ ? TimeUI.addOffset(TimeUI._timelineEndTimestamp)
+ : 100
+
+ TimeUI.updateTimes(nextStart, nextEnd, nextEnd)
+ },
+ fitWindowToTime(fitOnlyIfOutOfRange) {
+ const rangeMode =
+ TimeUI.modes[TimeUI.modeIndex] === 'Range' ? true : false
+
+ let nextStart
+ let nextEnd
+ if (rangeMode) {
+ // Match window edges exactly with time range
+ nextStart = TimeUI.removeOffset(TimeUI._startTimestamp)
+ nextEnd = TimeUI.removeOffset(TimeUI.getCurrentTimestamp())
+ } else {
+ // Adjust window such that Point is in its center
+ const existingMin =
+ TimeUI._timelineEndTimestamp != null
+ ? TimeUI._timelineStartTimestamp
+ : 0
+ const existingMax =
+ TimeUI._timelineStartTimestamp != null
+ ? TimeUI._timelineEndTimestamp
+ : 100
+ const buffer = parseInt((existingMax - existingMin) / 2)
+
+ nextStart = TimeUI.removeOffset(
+ TimeUI.getCurrentTimestamp() - buffer
+ )
+ nextEnd = TimeUI.removeOffset(TimeUI.getCurrentTimestamp() + buffer)
+ }
+ if (fitOnlyIfOutOfRange === true) {
+ if (TimeUI._timelineStartTimestamp < nextStart) {
+ nextStart = null
+ }
+ if (TimeUI._timelineEndTimestamp > nextEnd) {
+ nextEnd = null
+ }
+ }
+
+ TimeUI._drawTimeLine(nextStart, nextEnd)
+
+ clearTimeout(TimeUI._panHistoTimeout)
+ $('#mmgisTimeUITimelineHisto').empty()
+ TimeUI._makeHistogram()
},
toggleTimeNow(force) {
if ((!TimeUI.now && typeof force != 'boolean') || force === true) {
@@ -725,6 +1060,8 @@ const TimeUI = {
)
return
+ TimeUI._updateExtentIndicator()
+
TimeUI.timeSlider = new RangeSliderPips({
target: document.querySelector('#mmgisTimeUITimelineSlider'),
props: {
@@ -761,6 +1098,7 @@ const TimeUI = {
TimeUI._savedPlayEnd = null
TimeUI.togglePlay(false)
}
+ TimeUI._updateExtentIndicator()
})
TimeUI.timeSlider.$on('change', (e) => {
let idx = 0
@@ -776,6 +1114,9 @@ const TimeUI = {
.utc(TimeUI.removeOffset(offsetNowDate))
.format(FORMAT)
)
+ TimeUI._updateExtentIndicator(
+ moment.utc(TimeUI.removeOffset(offsetNowDate))
+ )
}
if (e.detail.activeHandle === idx + 1) {
$('#mmgisTimeUIEndWrapperFake').css('display', 'block')
@@ -784,6 +1125,10 @@ const TimeUI = {
.utc(TimeUI.removeOffset(offsetNowDate))
.format(FORMAT)
)
+ TimeUI._updateExtentIndicator(
+ null,
+ moment.utc(TimeUI.removeOffset(offsetNowDate))
+ )
}
})
TimeUI.timeSlider.$on('stop', (e) => {
@@ -809,6 +1154,7 @@ const TimeUI = {
)
TimeUI.endTempus.dates.setValue(parsedNow)
}
+ TimeUI._updateExtentIndicator()
})
if ($('#toggleTimeUI').hasClass('active') && ignoreHistogram !== true)
@@ -865,6 +1211,7 @@ const TimeUI = {
const starttimeISO = new Date(
TimeUI._timelineStartTimestamp
).toISOString()
+
const endtimeISO = new Date(TimeUI._timelineEndTimestamp).toISOString()
const NUM_BINS = Math.max(
@@ -993,9 +1340,7 @@ const TimeUI = {
let parsedEnd = null
if (end != null) {
date = new Date(end)
- offsetEndDate = new Date(
- date.getTime() + date.getTimezoneOffset() * 60000
- )
+ offsetEndDate = TimeUI.addOffset(date)
parsedEnd = TimeUI.endTempus.dates.parseInput(
new Date(offsetEndDate)
)
@@ -1127,7 +1472,7 @@ const TimeUI = {
if (TimeUI.play) {
const date = new Date(TimeUI._timeSliderTimestamp)
const offsetNowDate = new Date(
- date.getTime() + date.getTimezoneOffset() * 60000
+ date.getTime() // + date.getTimezoneOffset() * 60000 Not needed
)
const parsedNow = TimeUI.endTempus.dates.parseInput(
new Date(offsetNowDate)
@@ -1152,16 +1497,20 @@ const TimeUI = {
? TimeUI.removeOffset(TimeUI._startTimestamp)
: 0
).toISOString(),
- new Date(
- TimeUI.removeOffset(TimeUI._endTimestamp)
- ).toISOString(),
+ // use currentTime as endTime if in playmode
+ TimeUI.play === true
+ ? new Date(TimeUI.getCurrentTimestamp(true)).toISOString()
+ : new Date(
+ TimeUI.removeOffset(TimeUI._endTimestamp)
+ ).toISOString(),
new Date(TimeUI.getCurrentTimestamp(true)).toISOString()
)
}
},
_timelineDrag: function (e) {
if (TimeUI._timelineDragging === true) {
- const dx = e.originalEvent.movementX / 1.5
+ const nextPageX = e.originalEvent.pageX
+ const dx = nextPageX - TimeUI._lastDragPageX
const width = document
.getElementById('mmgisTimeUITimelineInner')
.getBoundingClientRect().width
@@ -1180,6 +1529,8 @@ const TimeUI = {
TimeUI._panHistoTimeout = setTimeout(() => {
TimeUI._makeHistogram()
}, 3000)
+
+ TimeUI._lastDragPageX = nextPageX
}
},
_drawTimeLine(forceStart, forceEnd) {
diff --git a/src/essence/Basics/Layers_/Layers_.js b/src/essence/Basics/Layers_/Layers_.js
index a6d8bde28..c59da5a33 100644
--- a/src/essence/Basics/Layers_/Layers_.js
+++ b/src/essence/Basics/Layers_/Layers_.js
@@ -3585,7 +3585,7 @@ async function parseConfig(configData, urlOnLayers) {
if (
L_.configData.projection &&
L_.configData.projection.resunitsperpixel &&
- L_.configData.projection.reszoomlevel
+ L_.configData.projection.reszoomlevel != null
) {
var baseRes =
L_.configData.projection.resunitsperpixel *
diff --git a/src/essence/Tools/Draw/DrawTool_Templater.js b/src/essence/Tools/Draw/DrawTool_Templater.js
index c3caa203d..da4c15cea 100644
--- a/src/essence/Tools/Draw/DrawTool_Templater.js
+++ b/src/essence/Tools/Draw/DrawTool_Templater.js
@@ -239,15 +239,21 @@ const DrawTool_Templater = {
$(`#drawToolTemplater_setTimeStart`).on('click', () => {
L_.TimeControl_.setTime(
- properties[startTime],
+ L_.TimeControl_.timeUI.removeOffset(
+ new Date(properties[startTime]).getTime()
+ ),
L_.TimeControl_.getEndTime()
)
+ L_.TimeControl_.timeUI.fitWindowToTime()
})
$(`#drawToolTemplater_setTimeEnd`).on('click', () => {
L_.TimeControl_.setTime(
L_.TimeControl_.getStartTime(),
- properties[endTime]
+ L_.TimeControl_.timeUI.removeOffset(
+ new Date(properties[endTime]).getTime()
+ )
)
+ L_.TimeControl_.timeUI.fitWindowToTime()
})
return {