Hier<\/A> ist ein cooles kleines Tutorial zu requestAnimationFrame.<\/P><\/P>
Wenn du mit 3D-Karten arbeitest, arbeitest du mit Animationen. Du musst dich nicht um die Details kümmern, aber wenn du etwas tun möchtest, um mit einer 3D-Karte synchron zu bleiben, solltest du dich mit requestAnimationFrame vertraut machen.<\/P>
<\/P>
Scheduler kann dabei helfen.<\/P>
<\/P>
In meinem alten Beispiel habe ich noch auf setInterval<\/SPAN> zurückgegriffen, also hier ist, wie ich alles mit Scheduler machen würde.<\/P><\/P>require([\n "esri\/Map",\n "esri\/views\/SceneView",\n "esri\/core\/watchUtils",\n "esri\/core\/Scheduler",\n "dojo\/on",\n \/\/_ Widget items\n 'dojo\/_base\/declare',\n 'dojo\/dom-class',\n 'dijit\/_WidgetBase',\n 'dijit\/_TemplatedMixin',\n "dojo\/domReady!"\n], function (Map, SceneView, watchUtils, Scheduler, on, declare, domClass, _WidgetBase, _TemplatedMixin){\n\n var template = '' +\n '<div>'+\n ' <input class=\"camera-slider\" data-dojo-attach-point=\"slider\"'+\n ' type=\"range\" min=\"1\" max=\"1\" step=\"1\" value=\"1\">'+\n ' <a href=\"javascript:void(0)\" data-dojo-attach-point=\"reverseBtn\"'+\n ' data-dojo-attach-event=\"click:playReverse\"'+\n ' title=\"Ansichten rückwärts abspielen\"'+\n ' class=\"btn btn-info btn-fab btn-raised mdi-av-fast-rewind\"><\\/a>'+\n ' <a href=\"javascript:void(0)\" data-dojo-attach-point=\"playBtn\"'+\n ' data-dojo-attach-event=\"click:play\"'+\n ' title=\"Ansichten abspielen\"'+\n ' class=\"btn btn-info btn-fab btn-raised mdi-av-play-arrow\"><\\/a>'+\n ' <a href=\"javascript:void(0)\" data-dojo-attach-point=\"stopBtn\"'+\n ' data-dojo-attach-event=\"click:stop\"'+\n ' title=\"Aufnahme der Ansicht pausieren\"'+\n ' class=\"btn btn-info btn-fab btn-raised mdi-av-pause\"><\\/a>'+\n '<\\/div>';\n\n var CameraRecorder = declare([_WidgetBase, _TemplatedMixin], { \n templateString: template, \n constructor: function() { \n this.cameras = [null]; \n this.timer = null; \n this.watcher = null; \n this.handler = null; \n this.isPlaying = false; \n }, \n clear: function() { \n  .& nbsp.& nbsp;if (this.watcher) { \n . nbsp.& nbsp.& nbsp.& nbsp.this.watcher.remove(); \n& nbsp.& nbsp;} \n& nbsp.& nbsp;if (this.handler) { \n& nbsp.& nbsp.& nbsp.& nbsp.this.handler.remove(); \ n& nbsp.& nbsp;} \ n& nbsp.& nbsp;if (this.timer) { \ n& nbsp.& nbsp.& nbsp.& nbsp.this.timer.remove(); \ n& nbsp.& nbsp;} \ n& nbsp.& nbsp.this.recordStart(); \ n& nbsp.; }, \ n& nbsp.; recordStart: function() { \ n& nbsp.; if (this.isPlaying || this.isPaused) { \ n& nbsp.; & nbsp.; return ; \ n& nbsp.; } \ n& nbsp.; this.timer = Scheduler.schedule(function() { \ n& nbsp.; & nbsp.; this._cameraWatch(); \ n& nbsp.; & nbsp.; this._sliderWatch(); \ n& nbsp.; }.bind(this)); \ n& nbsp.; }, \ n& nbsp.; play: function() { \ n& nbsp.; if (this.isPlaying) { \ n& nbsp.; & nbsp.; return ; \ n& nbsp.; } \ n& nbsp.; domClass.toggle(this.playBtn, 'btn-info btn-success'); \ n& nbsp.; this._play(false); \ n& nbsp.; }, \ n& nbsp.; stop: function() { \ n& nbsp.; this.isPaused = !this.isPaused ; \ n& nbsp.; domClass.toggle(this.stopBtn , 'btn-info btn-danger'); \ n& nbsp.; if (!this.isPaused) { \ n& nbsp.; & nb sp . this.recordStart(); \ n & nb sp . } \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \ }
}
}.bind(this)});
}
});
var map = new Map({
basemap: "dark-gray"
});
var view = new SceneView({
container: "viewDiv",
map: map,
scale: 240000000
});
var camRecorder = new CameraRecorder(
{ view: view }, document.getElementById('recorder')
);
view.then(function() {
camRecorder.recordStart();
});
});
Was ich hier mache, sind zwei Dinge.
Ich benutze hier Scheduler.schedule(), um einige Methoden für den nächsten Frame zu planen. Dies sind die Methoden, die die Kamera- oder Schieberegleränderungen speichern, um die Ansicht aufzuzeichnen.
Wenn du dann die aufgezeichneten Kameraperspektiven nacheinander abspielst, verwende ich Scheduler.addFrameTask({update: function(){}}), um eine Funktion hinzuzufügen, wenn die Ansicht aktualisiert, also gerendert wird. Es gibt einige interne Lifecycle-Prozesse im addFrameTask, aber ich schieße hier einfach aus der Hüfte, also nehmen wir update als den Punkt, an den man sich anhängen kann.
Wenn du Operationen wie diese, die mit Animation zu tun haben, nicht synchronisierst, bekommst du eine ruckelnde Karte. Mein erster Entwurf dieser App basierte ausschließlich darauf, auf Eigenschaftsänderungen zu achten, aber das hat meine App durcheinandergebracht. Jetzt läuft sie viel flüssiger.
Du kannst dieses