i have set up an animationLayer as described in the docs. most things work fine, but there is one issue:
when waking the watch up (onExitSleep, by hand motion or button) the last frame of the animation is diplayed for a fraction, before the animation starts paying.
weirdly enoguh, this does not happen when swiping to the watch face (onShow) from another menu. then the animation starts correctly with the first frame.
as my animation is an appear-style animation that start with a black screen, it is a bit jarring to have "final" image shown first, then disappear again and appear again.
this does not happen in the device simulator (using settings > lowPowerMode), but on the actual watch, a venu 2 the wrong frame is there.
i already tried several approaches:
- changing order of function calls -> no effect at all
- hiding the animationLayer, then showing it later on -> very inconsistent
- clearing the animation layer dc -> not allowed
how can this be avoided / what could be an issue causing this?
for reference, this is the watch face:
https://apps.garmin.com/en-US/apps/4d2a8dec-609e-479d-990a-4ae6a563fee4
code:
//! Responds to animation events class AnimationDelegate extends WatchUi.AnimationDelegate { private var _view as PentagramView; //! Constructor //! @param view The watch face view public function initialize(view as PentagramView) { _view = view; WatchUi.AnimationDelegate.initialize(); } //! Handle an animation event //! @param event The animation event //! @param options A dictionary of animation options public function onAnimationEvent( event as AnimationEvent, options as Dictionary ) as Void { // call stop once the animation has played fully if (event == WatchUi.ANIMATION_EVENT_COMPLETE || event == WatchUi.ANIMATION_EVENT_CANCELED) { _view.stop(); //stop the watch face manually, but is this needed? it doesnt loop if we dont do it... } } } class PentagramView extends WatchUi.WatchFace { private var _animationLayer as AnimationLayer; private var _drawLayer as Layer; private var _drawLayerArea as Array<Number>; private var _width as Number; private var _font as FontResource?; private var _fontSml as FontResource?; private var _isAwake as Boolean?; private var _smallDisplay as Boolean?; //called when the watch face intializes function initialize() { WatchFace.initialize(); var settings = System.getDeviceSettings(); _width = settings.screenWidth; // draw layer will be full screen _drawLayerArea = [ 0, 0, settings.screenWidth, settings.screenHeight, ] as Array<Number>; // create animation Layer _animationLayer = new WatchUi.AnimationLayer( $.Rez.Drawables.pentagramU, null ); // create draw layer _drawLayer = new WatchUi.Layer({ :locX => _drawLayerArea[0], :locY => _drawLayerArea[1], :width => _drawLayerArea[2], :height => _drawLayerArea[3], }); _smallDisplay = _width < 360; _isAwake = true; } // Load your resources here function onLayout(dc as Dc) as Void { setLayout(Rez.Layouts.WatchFace(dc)); _font = WatchUi.loadResource($.Rez.Fonts.id_font_bmpfontLrg) as FontResource; _fontSml = WatchUi.loadResource($.Rez.Fonts.id_font_bmpfontSml) as FontResource; // clear the whole screen with solid color dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_BLACK); dc.clear(); // add the layers to the view addLayer(_animationLayer); addLayer(_drawLayer); } // Called when this View is brought to the foreground. Restore // the state of this View and prepare it to be shown. This includes // loading resources into memory. function onShow() as Void { play(); } // Update the view function onUpdate(dc as Dc) as Void { if(!_isAwake){ // clear the whole screen with solid color dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_BLACK); dc.clear(); } // Update the entire draw layer updateWatchOverlay(true); } // Called when this View is removed from the screen. Save the // state of this View here. This includes freeing resources from // memory. function onHide() as Void { // invoke default View.onHide() which will stop all animations View.onHide(); } // The user has just looked at their watch. Timers and animations may be started here. function onExitSleep() as Void { _isAwake = true; //self.requestUpdate(); //this does not help. _animationLayer.setVisible(true); play(); } // Terminate any active timers and prepare for slow updates. function onEnterSleep() as Void { // animation playback will be stopped by system after entering sleep mode //also hide the animation layer _isAwake = false; stop(); //do we need to stop? does not seem to make a difference _animationLayer.setVisible(false); } //start the animation function play() { _animationLayer.play({ :delegate => new AnimationDelegate(self) }); } //stop the animation function stop() { _animationLayer.stop(); }