diff options
author | Florin Malita <fmalita@chromium.org> | 2017-12-30 12:27:00 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-12-30 22:55:39 +0000 |
commit | 094ccde2380bfbb615e25d0d80208148fcd47f17 (patch) | |
tree | d6233c61996a3f268938953608b0b3a2d4590e07 /tools | |
parent | 83b2b08afcf903a455cd0ea999d0c2936088fffd (diff) |
Initial Lottie loader impl (Skotty)
Coarse workflow:
* Construction
1) build a Json tree
2) collect asset IDs (for preComp/image layer resolution)
3) "attach" pass
- traverse the Json tree
- build an SkSG dom, one fragment at a time
- attach "animator" objects to the dom, for each animated prop
4) done, we can throw away the Json tree
* For each animation tick
1) iterate over active animators and poke their respective dom nodes/attributes
2) revalidate the SkSG dom
3) draw the SkSG dom
Note: post construction, things are super-simple - we just poke SkSG DOM attributes
with interpolated values, and everything else is handled by SkSG (invalidation,
revalidation, render).
Change-Id: I96a02be7eb4fb4cb3831f59bf2b3908ea190c0dd
Reviewed-on: https://skia-review.googlesource.com/89420
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Florin Malita <fmalita@chromium.org>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/flags/SkCommandLineFlags.h | 3 | ||||
-rw-r--r-- | tools/viewer/SkottySlide.cpp | 75 | ||||
-rw-r--r-- | tools/viewer/SkottySlide.h | 39 | ||||
-rw-r--r-- | tools/viewer/Viewer.cpp | 16 |
4 files changed, 133 insertions, 0 deletions
diff --git a/tools/flags/SkCommandLineFlags.h b/tools/flags/SkCommandLineFlags.h index 15f12d915b..4a22c3f4bf 100644 --- a/tools/flags/SkCommandLineFlags.h +++ b/tools/flags/SkCommandLineFlags.h @@ -155,6 +155,9 @@ public: fStrings[i].set(str); } + const SkString* begin() const { return fStrings.begin(); } + const SkString* end() const { return fStrings.end(); } + private: void reset() { fStrings.reset(); } diff --git a/tools/viewer/SkottySlide.cpp b/tools/viewer/SkottySlide.cpp new file mode 100644 index 0000000000..d65b7ecbc1 --- /dev/null +++ b/tools/viewer/SkottySlide.cpp @@ -0,0 +1,75 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkottySlide.h" + +#include "SkAnimTimer.h" +#include "Skotty.h" +#include "SkStream.h" + +SkottySlide::SkottySlide(const SkString& name, const SkString& path) + : fPath(path) { + fName = name; +} + +void SkottySlide::load(SkScalar, SkScalar) { + auto stream = SkStream::MakeFromFile(fPath.c_str()); + fAnimation = skotty::Animation::Make(stream.get()); + fTimeBase = 0; // force a time reset + + if (fAnimation) { + SkDebugf("loaded Bodymovin animation v: %s, size: [%f %f], fr: %f\n", + fAnimation->version().c_str(), + fAnimation->size().width(), + fAnimation->size().height(), + fAnimation->frameRate()); + } else { + SkDebugf("failed to load Bodymovin animation: %s\n", fPath.c_str()); + } +} + +void SkottySlide::unload() { + fAnimation.reset(); +} + +SkISize SkottySlide::getDimensions() const { + return fAnimation? fAnimation->size().toCeil() : SkISize::Make(0, 0); +} + +void SkottySlide::draw(SkCanvas* canvas) { + if (fAnimation) { + fAnimation->render(canvas); + } +} + +bool SkottySlide::animate(const SkAnimTimer& timer) { + if (fTimeBase == 0) { + // Reset the animation time. + fTimeBase = timer.msec(); + } + + if (fAnimation) { + auto t = timer.msec() - fTimeBase; + fAnimation->animationTick(t); + } + return true; +} + +bool SkottySlide::onChar(SkUnichar c) { + switch (c) { + case 'I': + if (fAnimation) { + fShowAnimationInval = !fShowAnimationInval; + fAnimation->setShowInval(fShowAnimationInval); + } + break; + default: + break; + } + + return INHERITED::onChar(c); +} diff --git a/tools/viewer/SkottySlide.h b/tools/viewer/SkottySlide.h new file mode 100644 index 0000000000..9b7ae7c890 --- /dev/null +++ b/tools/viewer/SkottySlide.h @@ -0,0 +1,39 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkottySlide_DEFINED +#define SkottySlide_DEFINED + +#include "Slide.h" + +namespace skotty { class Animation; } + +class SkottySlide : public Slide { +public: + SkottySlide(const SkString& name, const SkString& path); + ~SkottySlide() override = default; + + void load(SkScalar winWidth, SkScalar winHeight) override; + void unload() override; + + SkISize getDimensions() const override; + + void draw(SkCanvas*) override; + bool animate(const SkAnimTimer&) override; + + bool onChar(SkUnichar) override; + +private: + SkString fPath; + std::unique_ptr<skotty::Animation> fAnimation; + SkMSec fTimeBase = 0; + bool fShowAnimationInval = false; + + typedef Slide INHERITED; +}; + +#endif // SkottySlide_DEFINED diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp index 1f701e25b3..55a025c1ed 100644 --- a/tools/viewer/Viewer.cpp +++ b/tools/viewer/Viewer.cpp @@ -11,6 +11,7 @@ #include "ImageSlide.h" #include "Resources.h" #include "SampleSlide.h" +#include "SkottySlide.h" #include "SKPSlide.h" #include "GrContext.h" @@ -68,9 +69,11 @@ static DEFINE_bool(list, false, "List samples?"); #ifdef SK_BUILD_FOR_ANDROID static DEFINE_string(skps, "/data/local/tmp/skps", "Directory to read skps from."); static DEFINE_string(jpgs, "/data/local/tmp/resources", "Directory to read jpgs from."); +static DEFINE_string(jsons, "/data/local/tmp/jsons", "Directory to read (Bodymovin) jsons from."); #else static DEFINE_string(skps, "skps", "Directory to read skps from."); static DEFINE_string(jpgs, "jpgs", "Directory to read jpgs from."); +static DEFINE_string(jsons, "jsons", "Directory to read (Bodymovin) jsons from."); #endif static DEFINE_string2(backend, b, "sw", "Backend to use. Allowed values are " BACKENDS_STR "."); @@ -480,6 +483,19 @@ void Viewer::initSlides() { } } } + + // JSONs + for (const auto& json : FLAGS_jsons) { + SkOSFile::Iter it(json.c_str(), ".json"); + SkString jsonName; + while (it.next(&jsonName)) { + if (SkCommandLineFlags::ShouldSkip(FLAGS_match, jsonName.c_str())) { + continue; + } + fSlides.push_back(sk_make_sp<SkottySlide>(jsonName, SkOSPath::Join(json.c_str(), + jsonName.c_str()))); + } + } } |