Fixed zoom in real-time mode

This commit is contained in:
Henry 2016-10-11 12:45:18 -07:00
parent b384e84872
commit 02c543fddc
5 changed files with 120 additions and 53 deletions

View File

@ -120,7 +120,7 @@
<input class="time-conductor-zoom flex-elem" type="range"
ng-model="currentZoom"
ng-mouseUp="tcController.zoomStop(currentZoom)"
ng-change="tcController.zoom(currentZoom)"
ng-change="tcController.zoomDrag(currentZoom)"
min="0.01"
step="0.01"
max="0.99" />

View File

@ -61,11 +61,13 @@ define(
ConductorAxisController.prototype.destroy = function () {
this.conductor.off('timeSystem', this.changeTimeSystem);
this.conductor.off('bounds', this.setScale);
this.conductorViewService.off("zoom", this.onZoom);
this.conductorViewService.off("zoom-stop", this.onZoomStop)
};
ConductorAxisController.prototype.changeBounds = function (bounds) {
this.bounds = bounds;
if (this.initialized) {
if (this.initialized && !this.zooming) {
this.setScale();
}
};
@ -147,17 +149,25 @@ define(
this.scope.$on("$destroy", this.destroy);
this.conductorViewService.on("zoom", this.zoom);
this.conductorViewService.on("zoom", this.onZoom);
this.conductorViewService.on("zoom-stop", this.onZoomStop);
};
ConductorAxisController.prototype.panStop = function () {
//resync view bounds with time conductor bounds
this.conductor.bounds(this.bounds);
this.conductorViewService.emit("pan-stop");
this.conductor.bounds(this.bounds);
};
ConductorAxisController.prototype.zoom = function (bounds) {
this.changeBounds(bounds);
ConductorAxisController.prototype.onZoom = function (zoom) {
this.zooming = true;
this.bounds = zoom.bounds;
this.setScale();
};
ConductorAxisController.prototype.onZoomStop = function (zoom) {
this.zooming = false;
};
ConductorAxisController.prototype.pan = function (delta) {

View File

@ -53,7 +53,7 @@ define(
//Set the initial state of the view based on current time conductor
this.initializeScope();
this.conductor.on('bounds', this.setFormFromBounds);
this.conductor.on('bounds', this.changeBounds);
this.conductor.on('timeSystem', this.changeTimeSystem);
// If no mode selected, select fixed as the default
@ -98,9 +98,9 @@ define(
// Watch scope for selection of mode or time system by user
this.$scope.$watch('modeModel.selectedKey', this.setMode);
this.conductorViewService.on('pan', this.pan);
this.conductorViewService.on('pan-stop', this.panStop);
this.conductorViewService.on('pan', this.onPan);
this.conductorViewService.on('pan-stop', this.onPanStop);
this.$scope.$on('$destroy', this.destroy);
};
@ -108,17 +108,27 @@ define(
TimeConductorController.prototype.destroy = function () {
this.conductor.off('bounds', this.setFormFromBounds);
this.conductor.off('timeSystem', this.changeTimeSystem);
this.conductorViewService.off('pan', this.onPan);
this.conductorViewService.off('pan-stop', this.onPanStop);
};
TimeConductorController.prototype.pan = function (bounds) {
TimeConductorController.prototype.onPan = function (bounds) {
this.$scope.panning = true;
this.setFormFromBounds(bounds);
this.$scope.boundsModel.start = bounds.start;
this.$scope.boundsModel.end = bounds.end;
};
TimeConductorController.prototype.panStop = function () {
TimeConductorController.prototype.onPanStop = function () {
this.$scope.panning = false;
};
TimeConductorController.prototype.changeBounds = function (bounds) {
if (!this.$scope.zooming && !this.$scope.panning) {
this.setFormFromBounds(bounds);
}
};
/**
* Called when the bounds change in the time conductor. Synchronizes
* the bounds values in the time conductor with those in the form
@ -126,18 +136,20 @@ define(
* @private
*/
TimeConductorController.prototype.setFormFromBounds = function (bounds) {
this.$scope.boundsModel.start = bounds.start;
this.$scope.boundsModel.end = bounds.end;
if (!this.$scope.zooming && ! this.$scope.panning) {
this.$scope.boundsModel.start = bounds.start;
this.$scope.boundsModel.end = bounds.end;
this.$scope.currentZoom = this.toSliderValue(bounds.end - bounds.start);
this.toTimeUnits(bounds.end - bounds.start);
this.$scope.currentZoom = this.toSliderValue(bounds.end - bounds.start);
this.toTimeUnits(bounds.end - bounds.start);
if (!this.pendingUpdate) {
this.pendingUpdate = true;
this.$window.requestAnimationFrame(function () {
this.pendingUpdate = false;
this.$scope.$digest();
}.bind(this));
if (!this.pendingUpdate) {
this.pendingUpdate = true;
this.$window.requestAnimationFrame(function () {
this.pendingUpdate = false;
this.$scope.$digest();
}.bind(this));
}
}
};
@ -267,30 +279,37 @@ define(
}
};
TimeConductorController.prototype.toTimeSpan = function (sliderValue) {
var center = this.$scope.boundsModel.start +
((this.$scope.boundsModel.end - this.$scope.boundsModel.start) / 2);
var zoomDefaults = this.conductor.timeSystem().defaults().zoom;
var timeSpan = Math.pow((1 - sliderValue), 4) * (zoomDefaults.min - zoomDefaults.max);
return {start: center - timeSpan / 2, end: center + timeSpan / 2};
};
TimeConductorController.prototype.toTimeUnits = function (timeSpan) {
if (this.conductor.timeSystem()) {
var timeFormat = this.formatService.getFormat(this.conductor.timeSystem().formats()[0]);
this.$scope.timeUnits = timeFormat.timeUnits && timeFormat.timeUnits(timeSpan);
}
}
TimeConductorController.prototype.zoom = function(sliderValue) {
var bounds = this.toTimeSpan(sliderValue);
this.setFormFromBounds(bounds);
this.conductorViewService.emit("zoom", bounds);
};
TimeConductorController.prototype.zoomStop = function (sliderValue) {
var bounds = this.toTimeSpan(sliderValue);
this.conductor.bounds(bounds);
TimeConductorController.prototype.zoomDrag = function(sliderValue) {
var zoomDefaults = this.conductor.timeSystem().defaults().zoom;
var timeSpan = Math.pow((1 - sliderValue), 4) * (zoomDefaults.min - zoomDefaults.max);
var zoom = this.conductorViewService.zoom(timeSpan);
this.$scope.boundsModel.start = zoom.bounds.start;
this.$scope.boundsModel.end = zoom.bounds.end;
this.toTimeUnits(zoom.bounds.end - zoom.bounds.start);
if (zoom.deltas) {
this.setFormFromDeltas(zoom.deltas);
}
this.$scope.zooming = true;
};
TimeConductorController.prototype.zoomStop = function () {
this.updateBoundsFromForm(this.$scope.boundsModel);
this.updateDeltasFromForm(this.$scope.boundsModel);
this.$scope.zooming = false;
this.conductorViewService.emit('zoom-stop');
};
return TimeConductorController;

View File

@ -176,26 +176,58 @@ define(
* @returns {TimeSystemDeltas}
*/
TimeConductorMode.prototype.deltas = function (deltas) {
if (arguments.length !== 0) {
var oldEnd = this.conductor.bounds().end;
if (this.dlts && this.dlts.end !== undefined) {
//Calculate the previous raw end value (without delta)
oldEnd = oldEnd - this.dlts.end;
}
if (arguments.length !== 0 && this.metadata().key!=='fixed') {
var bounds = this.calculateBoundsFromDeltas(deltas);
this.dlts = deltas;
var newBounds = {
start: oldEnd - this.dlts.start,
end: oldEnd + this.dlts.end
};
this.conductor.bounds(newBounds);
this.conductor.bounds(bounds);
}
return this.dlts;
};
TimeConductorMode.prototype.calculateBoundsFromDeltas = function (deltas) {
var oldEnd = this.conductor.bounds().end;
if (this.dlts && this.dlts.end !== undefined) {
//Calculate the previous raw end value (without delta)
oldEnd = oldEnd - this.dlts.end;
}
var bounds = {
start: oldEnd - deltas.start,
end: oldEnd + deltas.end
};
return bounds;
};
/**
* Performs zoom calculation. Will calculate new bounds and deltas
* based on desired timeSpan
* @param timeSpan
*/
TimeConductorMode.prototype.calculateZoom = function (timeSpan) {
var zoom = {};
// If a tick source is defined, then the concept of 'now' is
// important. Calculate zoom based on 'now'.
if (this.tickSource()){
zoom.deltas = {
start: timeSpan,
end: this.dlts.end
};
zoom.bounds = this.calculateBoundsFromDeltas(zoom.deltas);
// Calculate bounds based on deltas;
} else {
var bounds = this.conductor.bounds();
var center = bounds.start + ((bounds.end - bounds.start)) / 2;
bounds.start = center - timeSpan / 2;
bounds.end = center + timeSpan / 2;
zoom.bounds = bounds;
}
return zoom;
};
return TimeConductorMode;
}
);

View File

@ -203,6 +203,12 @@ define(
return this.currentMode.availableTimeSystems();
};
TimeConductorViewService.prototype.zoom = function (timeSpan) {
var zoom = this.currentMode.calculateZoom(timeSpan);
this.emit("zoom", zoom);
return zoom;
};
return TimeConductorViewService;
}
);