Retour à la documentation
/**
* @class spw.widgets.SpwTimeTravel
*/
define([
"dojo/_base/declare", "spw/api/SpwBaseTemplatedWidget", "dojo/text!./templates/SpwTimeTravel.html",
"dojo/i18n!./nls/SpwTimeTravel", "dijit/form/HorizontalSlider", "dijit/form/HorizontalRuleLabels",
"dijit/form/HorizontalRule", "dojo/_base/array", "dojo/on", "dojo/_base/lang", "dojo/dom-construct",
"dijit/Dialog", "dojo/dom-style", "dojo/dom-class", "dojo/dom-geometry",
"dijit/layout/ContentPane", "dijit/form/Button"
],
function(declare, SpwBaseTemplatedWidget, template, labels, HorizontalSlider, HorizontalRuleLabels,
HorizontalRule, array, on, lang, domConstruct, Dialog, domStyle, domClass, domGeom) {
return declare("spw.widgets.SpwTimeTravel", [SpwBaseTemplatedWidget], {
templateString: template,
labels: labels,
// basemap selected
basemap: null,
service: null,
// mapservices for the basemap
services: [],
// selectedservice (the most opaque)
selectedService: null,
spwViewer: null,
// slider elements
horizontalRule: null,
horizontalRuleLabels: null,
slider: null,
// pause/play information
startValue: 0,
isPlaying: false,
stepPlaying: 1,
playingSpeed: 300,
// widget options
widgetId: "SpwTimeTravelBaseMapId",
widgetTitle: labels.widgetTitle,
position: "panel-light",
bottom: "15px",
right: "15px",
minimum: 0,
maximum: 100,
constructor: function() {
this.inherited(arguments);
},
getTimer: function(){
return this.basemap || this.service;
},
postCreate: function() {
this.inherited(arguments);
// without basemap...we can't do more
if (!this.getTimer()) {
return;
}
// handle play/pause click
this.own(
on(this.playNode, 'click', lang.hitch(this, this.pausePlayClicked))
);
// get alpha start value
var step = 1 / this.getTimer().services.length;
this.offset = step / 2;
this.startValue = this.offset;
this.minimum = this.offset * 100;
this.maximum = (1 - this.offset) * 100;
// get map services
if(this.basemap){
this.services = array.map(this.getTimer().services, lang.hitch(this, function(s, i) {
if (s.selected && this.startValue === this.offset) {
this.startValue = (i * step) + ((1 - (s.alphaTimer == null ? 1 : Math.abs(s.alphaTimer))) * step);
if (i > 0 || s.alphaTimer == null || s.alphaTimer >= 0) {
this.startValue += this.offset;
}
if (this.startValue > 1) {
this.startValue = 1;
}
}
return this.spwViewer.get('spwMap').getMapServiceById(s.serviceId);
}));
} else {
this.services = this.getTimer().mapServices;
}
// build slider
var timerCount = this.services.length;
array.forEach(this.services, lang.hitch(this, function(s, idx) {
var li = domConstruct.create('li', {
'class': 'imgHolder',
style: 'width: ' + (100 / this.services.length) + '%'
}, this.labelsList);
var icon = s.imagePath || 'noRuleIcon.png';
var img = domConstruct.create('div', {
//src: this.imagesPath + icon,
'class': 'img',
'style': 'background-image: url(\'' + icon + '\');'
}, li);
var handleClick = lang.hitch(this, function() {
var value = (idx * step);
value = (value * 100) + this.offset;
this.slider.set('value', this.correctValue(value));
});
var span = domConstruct.create('span', {
innerHTML: s.ruleLabel,
style: 'cursor: ' + (s.metadataUrl ? 'pointer' : 'default')
}, li);
this.own(on(img, 'click', handleClick), on(span, 'click', lang.hitch(this, handleClick/*this.handleOnMetadataClick*/, s)));
li.img = img;
s.ruleLi = li;
}));
this.slider = new HorizontalSlider({
name: "slider",
value: 0,
minimum: this.minimum,
maximum: this.maximum,
discreteValues: 100,
intermediateChanges: true,
style: "margin: 0 auto; width: " + (100 - (100 / this.services.length)) + "%;"
// style: "margin: 0 auto; width: 100%;"
}, this.sliderNode);
// handle slider value changes
this.own(
on(this.slider, 'change', lang.hitch(this, this.setAlpha))
);
this.offset *= 100;
// if startValue != slider value, we can set it and event will be triggered
if (this.startValue !== this.slider.get('value')) {
this.slider.set('value', this.correctValue(this.startValue * 100));
}
// if not, we have to call setAlpha manually
else {
this.setAlpha(this.startValue * 100);
}
},
correctValue: function(v) {
if (v < this.minimum) {
return this.minimum;
}
if (v > this.maximum) {
return this.maximum;
}
return v;
},
/**
* Handle pause/play action
*/
pausePlayClicked: function() {
// function called every XXX ms
function playing() {
// if is paused
if (!this.isPlaying) {
// enable slider and change image
this.slider.set('disabled', false);
domClass.remove(this.playNode, 'pause');
return;
}
// get new value
var newVal = this.slider.get('value') + this.stepPlaying;
var maxReached = false;
// if max reached, stop playing
if (newVal >= this.slider.get('maximum')) {
newVal = this.slider.get('maximum');
this.isPlaying = false;
}
this.slider.set('value', this.correctValue(newVal));
// next call
this.timeOutId = setTimeout(lang.hitch(this, playing), this.playingSpeed);
}
// pause if currently playing
if (this.isPlaying) {
this.isPlaying = false;
}
else {
// reset slider value if max reached
if (this.slider.get('value') === this.slider.get('maximum')) {
this.slider.set('value', this.slider.get('minimum'));
}
domClass.add(this.playNode, 'pause');
// disable slider and start playing
this.slider.set('disabled', true);
this.isPlaying = true;
this.timeOutId = setTimeout(lang.hitch(this, playing), this.playingSpeed);
}
},
setAlpha: function(value) {
if (!this.services || !this.services.length) {
return;
}
// get data to compute alphas for each service
var delta = 100;
var nbrOfLayers = this.services.length;
var stepSize = delta / nbrOfLayers;
var stepNumber = (value + this.offset) / stepSize;
var stepNumberRounded = Math.round(stepNumber);
var isAfter = stepNumberRounded <= stepNumber;
stepNumberRounded -= 1;
if (stepNumberRounded < 0) {
stepNumberRounded = 0;
isAfter = false;
}
else if (stepNumberRounded >= this.services.length) {
stepNumberRounded = this.services.length - 1;
isAfter = true;
}
for(var i = 0; i < this.services.length; i++) {
if(i === stepNumberRounded) {
// keep alpha value so BaseMapChooser can use it when global alpha is modified
var first = this.services[i].alphaTimer = isAfter ? (-stepNumber + i + 2) : (i - stepNumber);
/*if (first < 0) {
first = this.services[i].alphaTimer = 0;
}
else */if (first > 1) {
first = this.services[i].alphaTimer = first - 1;
}
this.selectedService = this.services[i];
this.services[i].set('alpha', Math.abs(this.services[i].alphaTimer * this.getTimer().alpha));
var idxBefore = i - 1;
if (!isAfter && idxBefore >= 0) {
var before = this.services[idxBefore].alphaTimer = 1 - Math.abs(first);
this.services[idxBefore].set('alpha', Math.abs(this.services[idxBefore].alphaTimer * this.getTimer().alpha));
this.setScaleImg(this.services[idxBefore].ruleLi.img, 1 + Math.abs(before / 4));
}
var idxAfter = i + 1;
if (isAfter && idxAfter < this.services.length) {
var after = this.services[idxAfter].alphaTimer = 1 - Math.abs(first);
if (after < 0) {
after = this.services[idxAfter].alphaTimer = 0;
}
this.services[idxAfter].set('alpha', this.services[idxAfter].alphaTimer * this.getTimer().alpha);
i += 1;
domClass.remove(this.services[idxAfter].ruleLi, 'selected');
this.setScaleImg(this.services[idxAfter].ruleLi.img, 1 + (after / 4));
}
// show description and disable metadata button is necessary
this.descriptionNode.innerHTML = this.selectedService.description ? this.selectedService.description : this.labels.noDescription;
domStyle.set(this.metadataButton.domNode, 'display', this.selectedService.metadataUrl ? '' : 'none');
this.metadataButton.set('disabled', !this.selectedService.metadataUrl);
domClass.add(this.selectedService.ruleLi, 'selected');
this.setScaleImg(this.selectedService.ruleLi.img, 1 + Math.abs(first / 4));
}
else {
this.services[i].alphaTimer = 0;
this.services[i].set('alpha', 0);
domClass.remove(this.services[i].ruleLi, 'selected');
this.setScaleImg(this.services[i].ruleLi.img, 1);
}
}
},
setScaleImg: function(node, value) {
domStyle.set(node, '-webkit-transform', 'scale(' + value + ')');
domStyle.set(node, '-moz-transform', 'scale(' + value + ')');
domStyle.set(node, '-ms-transform', 'scale(' + value + ')');
domStyle.set(node, '-o-transform', 'scale(' + value + ')');
domStyle.set(node, 'transform', 'scale(' + value + ')');
},
handleOnMetadataClick: function(service) {
if (service instanceof Event) {
service = this.selectedService;
}
if (service && service.metadataUrl) {
if(service.metadataPopup){
var width = service.metadataPopup.width != null ? service.metadataPopup.width : "750px";
var height = service.metadataPopup.height != null ? service.metadataPopup.height : "800px";
new Dialog({
title: "",
content: "<iframe width=\""+width+"\" height=\""+height+"\" src=\""+service.metadataUrl+"\"></iframe>"
}).show();
}
else {
window.open(service.metadataUrl, '_blank');
}
}
}
});
});