Kevin Lubick | 4683942 | 2019-01-03 14:27:27 -0500 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2019 Google LLC |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
| 6 | */ |
| 7 | |
| 8 | #include "SkCanvas.h" |
| 9 | #include "SkMakeUnique.h" |
| 10 | #include "SkTypes.h" |
| 11 | #include "Skottie.h" |
| 12 | |
| 13 | #include <string> |
| 14 | |
| 15 | #include <emscripten.h> |
| 16 | #include <emscripten/bind.h> |
| 17 | #include "WasmAliases.h" |
| 18 | |
| 19 | #if SK_INCLUDE_MANAGED_SKOTTIE |
| 20 | #include "SkottieProperty.h" |
| 21 | #include "SkottieUtils.h" |
| 22 | #endif // SK_INCLUDE_MANAGED_SKOTTIE |
| 23 | |
| 24 | using namespace emscripten; |
| 25 | |
| 26 | #if SK_INCLUDE_MANAGED_SKOTTIE |
| 27 | namespace { |
| 28 | |
| 29 | class ManagedAnimation final : public SkRefCnt { |
| 30 | public: |
| 31 | static sk_sp<ManagedAnimation> Make(const std::string& json) { |
| 32 | auto mgr = skstd::make_unique<skottie_utils::CustomPropertyManager>(); |
| 33 | auto animation = skottie::Animation::Builder() |
| 34 | .setMarkerObserver(mgr->getMarkerObserver()) |
| 35 | .setPropertyObserver(mgr->getPropertyObserver()) |
| 36 | .make(json.c_str(), json.size()); |
| 37 | |
| 38 | return animation |
| 39 | ? sk_sp<ManagedAnimation>(new ManagedAnimation(std::move(animation), std::move(mgr))) |
| 40 | : nullptr; |
| 41 | } |
| 42 | |
| 43 | // skottie::Animation API |
| 44 | void render(SkCanvas* canvas) const { fAnimation->render(canvas, nullptr); } |
| 45 | void render(SkCanvas* canvas, const SkRect& dst) const { fAnimation->render(canvas, &dst); } |
| 46 | void seek(SkScalar t) { fAnimation->seek(t); } |
| 47 | SkScalar duration() const { return fAnimation->duration(); } |
| 48 | const SkSize& size() const { return fAnimation->size(); } |
| 49 | std::string version() const { return std::string(fAnimation->version().c_str()); } |
| 50 | |
| 51 | // CustomPropertyManager API |
| 52 | JSArray getColorProps() const { |
| 53 | JSArray props = emscripten::val::array(); |
| 54 | |
| 55 | for (const auto& cp : fPropMgr->getColorProps()) { |
| 56 | JSObject prop = emscripten::val::object(); |
| 57 | prop.set("key", cp); |
| 58 | prop.set("value", fPropMgr->getColor(cp)); |
| 59 | props.call<void>("push", prop); |
| 60 | } |
| 61 | |
| 62 | return props; |
| 63 | } |
| 64 | |
| 65 | JSArray getOpacityProps() const { |
| 66 | JSArray props = emscripten::val::array(); |
| 67 | |
| 68 | for (const auto& op : fPropMgr->getOpacityProps()) { |
| 69 | JSObject prop = emscripten::val::object(); |
| 70 | prop.set("key", op); |
| 71 | prop.set("value", fPropMgr->getOpacity(op)); |
| 72 | props.call<void>("push", prop); |
| 73 | } |
| 74 | |
| 75 | return props; |
| 76 | } |
| 77 | |
| 78 | bool setColor(const std::string& key, JSColor c) { |
| 79 | return fPropMgr->setColor(key, static_cast<SkColor>(c)); |
| 80 | } |
| 81 | |
| 82 | bool setOpacity(const std::string& key, float o) { |
| 83 | return fPropMgr->setOpacity(key, o); |
| 84 | } |
| 85 | |
| 86 | JSArray getMarkers() const { |
| 87 | JSArray markers = emscripten::val::array(); |
| 88 | for (const auto& m : fPropMgr->markers()) { |
| 89 | JSObject marker = emscripten::val::object(); |
| 90 | marker.set("name", m.name); |
| 91 | marker.set("t0" , m.t0); |
| 92 | marker.set("t1" , m.t1); |
| 93 | markers.call<void>("push", marker); |
| 94 | } |
| 95 | return markers; |
| 96 | } |
| 97 | |
| 98 | private: |
| 99 | ManagedAnimation(sk_sp<skottie::Animation> animation, |
| 100 | std::unique_ptr<skottie_utils::CustomPropertyManager> propMgr) |
| 101 | : fAnimation(std::move(animation)) |
| 102 | , fPropMgr(std::move(propMgr)) {} |
| 103 | |
| 104 | sk_sp<skottie::Animation> fAnimation; |
| 105 | std::unique_ptr<skottie_utils::CustomPropertyManager> fPropMgr; |
| 106 | }; |
| 107 | |
| 108 | } // anonymous ns |
| 109 | #endif // SK_INCLUDE_MANAGED_SKOTTIE |
| 110 | |
| 111 | EMSCRIPTEN_BINDINGS(Skottie) { |
| 112 | // Animation things (may eventually go in own library) |
| 113 | class_<skottie::Animation>("Animation") |
| 114 | .smart_ptr<sk_sp<skottie::Animation>>("sk_sp<Animation>") |
| 115 | .function("version", optional_override([](skottie::Animation& self)->std::string { |
| 116 | return std::string(self.version().c_str()); |
| 117 | })) |
| 118 | .function("size", &skottie::Animation::size) |
| 119 | .function("duration", &skottie::Animation::duration) |
| 120 | .function("seek", &skottie::Animation::seek) |
| 121 | .function("render", optional_override([](skottie::Animation& self, SkCanvas* canvas)->void { |
| 122 | self.render(canvas, nullptr); |
| 123 | }), allow_raw_pointers()) |
| 124 | .function("render", optional_override([](skottie::Animation& self, SkCanvas* canvas, |
| 125 | const SkRect r)->void { |
| 126 | self.render(canvas, &r); |
| 127 | }), allow_raw_pointers()); |
| 128 | |
| 129 | function("MakeAnimation", optional_override([](std::string json)->sk_sp<skottie::Animation> { |
| 130 | return skottie::Animation::Make(json.c_str(), json.length()); |
| 131 | })); |
| 132 | constant("skottie", true); |
| 133 | |
| 134 | #if SK_INCLUDE_MANAGED_SKOTTIE |
| 135 | class_<ManagedAnimation>("ManagedAnimation") |
| 136 | .smart_ptr<sk_sp<ManagedAnimation>>("sk_sp<ManagedAnimation>") |
| 137 | .function("version" , &ManagedAnimation::version) |
| 138 | .function("size" , &ManagedAnimation::size) |
| 139 | .function("duration" , &ManagedAnimation::duration) |
| 140 | .function("seek" , &ManagedAnimation::seek) |
| 141 | .function("render" , select_overload<void(SkCanvas*) const>(&ManagedAnimation::render), allow_raw_pointers()) |
| 142 | .function("render" , select_overload<void(SkCanvas*, const SkRect&) const> |
| 143 | (&ManagedAnimation::render), allow_raw_pointers()) |
| 144 | .function("setColor" , &ManagedAnimation::setColor) |
| 145 | .function("setOpacity", &ManagedAnimation::setOpacity) |
| 146 | .function("getMarkers", &ManagedAnimation::getMarkers) |
| 147 | .function("getColorProps" , &ManagedAnimation::getColorProps) |
| 148 | .function("getOpacityProps", &ManagedAnimation::getOpacityProps); |
| 149 | |
| 150 | function("MakeManagedAnimation", &ManagedAnimation::Make); |
| 151 | constant("managed_skottie", true); |
| 152 | #endif // SK_INCLUDE_MANAGED_SKOTTIE |
| 153 | } |