ScrollTimelineAnimationTracker.cpp (2452B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "ScrollTimelineAnimationTracker.h" 8 9 #include "mozilla/dom/Document.h" 10 11 namespace mozilla { 12 13 NS_IMPL_CYCLE_COLLECTION(ScrollTimelineAnimationTracker, mPendingSet, mDocument) 14 15 void ScrollTimelineAnimationTracker::TriggerPendingAnimations() { 16 // Sample scroll timelines now to make sure its offsets are up-to-date. 17 // The scroll container may not be ready when creating the scroll timelines, 18 // and we trigger the pending animations after we flush the layout, so we have 19 // to do this here to make sure the current time is up-to-date when triggering 20 // animations. 21 mDocument->TimelinesController().TrySampleScrollTimelines(); 22 23 for (RefPtr<dom::Animation>& animation : 24 ToTArray<AutoTArray<RefPtr<dom::Animation>, 32>>(mPendingSet)) { 25 MOZ_ASSERT(animation->GetTimeline() && 26 !animation->GetTimeline()->IsMonotonicallyIncreasing()); 27 // FIXME: Trigger now may not be correct because the spec says: 28 // If a user agent determines that animation is immediately ready, it may 29 // schedule the task (i.e. ResumeAt()) as a microtask such that it runs at 30 // the next microtask checkpoint, but it must not perform the task 31 // synchronously. 32 // Note: So, for now, we put the animation into the tracker, and trigger 33 // them immediately until the frames are ready. Using TriggerOnNextTick() 34 // for scroll-driven animations may have issues because we don't tick if 35 // no one does scroll. 36 if (!animation->TryTriggerNow()) { 37 // Note: We keep this animation pending even if its timeline is always 38 // inactive. It's pretty hard to tell its future status, for example, it's 39 // possible that the scroll container is in display:none subtree but the 40 // animating element isn't the subtree, then we need to keep tracking the 41 // situation until the scroll container gets framed. so in general we make 42 // this animation be pending (i.e. not ready) if its scroll-timeline is 43 // inactive, and this also matches the current spec definition. 44 continue; 45 } 46 mPendingSet.Remove(animation); 47 } 48 } 49 50 } // namespace mozilla