| /* |
| * 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 "SkottieSlide.h" |
| |
| #include "SkAnimTimer.h" |
| #include "SkCanvas.h" |
| #include "Skottie.h" |
| #include "SkOSFile.h" |
| #include "SkOSPath.h" |
| #include "SkStream.h" |
| |
| const int CELL_WIDTH = 240; |
| const int CELL_HEIGHT = 160; |
| const int COL_COUNT = 4; |
| const int SPACER_X = 12; |
| const int SPACER_Y = 24; |
| const int MARGIN = 8; |
| |
| SkottieSlide2::Rec::Rec(std::unique_ptr<skottie::Animation> anim) : fAnimation(std::move(anim)) |
| {} |
| |
| SkottieSlide2::Rec::Rec(Rec&& o) |
| : fAnimation(std::move(o.fAnimation)) |
| , fTimeBase(o.fTimeBase) |
| , fName(o.fName) |
| , fShowAnimationInval(o.fShowAnimationInval) |
| {} |
| |
| SkottieSlide2::SkottieSlide2(const SkString& path) |
| : fPath(path) |
| { |
| fName.set("skottie-dir"); |
| } |
| |
| void SkottieSlide2::load(SkScalar, SkScalar) { |
| SkString name; |
| SkOSFile::Iter iter(fPath.c_str(), "json"); |
| while (iter.next(&name)) { |
| SkString path = SkOSPath::Join(fPath.c_str(), name.c_str()); |
| if (auto anim = skottie::Animation::MakeFromFile(path.c_str())) { |
| fAnims.push_back(Rec(std::move(anim))).fName = name; |
| } |
| } |
| } |
| |
| void SkottieSlide2::unload() { |
| fAnims.reset(); |
| } |
| |
| SkISize SkottieSlide2::getDimensions() const { |
| const int rows = (fAnims.count() + COL_COUNT - 1) / COL_COUNT; |
| return { |
| MARGIN + (COL_COUNT - 1) * SPACER_X + COL_COUNT * CELL_WIDTH + MARGIN, |
| MARGIN + (rows - 1) * SPACER_Y + rows * CELL_HEIGHT + MARGIN, |
| }; |
| } |
| |
| void SkottieSlide2::draw(SkCanvas* canvas) { |
| SkPaint paint; |
| paint.setTextSize(12); |
| paint.setAntiAlias(true); |
| paint.setTextAlign(SkPaint::kCenter_Align); |
| |
| const SkRect dst = SkRect::MakeIWH(CELL_WIDTH, CELL_HEIGHT); |
| int x = 0, y = 0; |
| |
| canvas->translate(MARGIN, MARGIN); |
| for (const auto& rec : fAnims) { |
| SkAutoCanvasRestore acr(canvas, true); |
| canvas->translate(x * (CELL_WIDTH + SPACER_X), y * (CELL_HEIGHT + SPACER_Y)); |
| canvas->drawText(rec.fName.c_str(), rec.fName.size(), |
| dst.centerX(), dst.bottom() + paint.getTextSize(), paint); |
| rec.fAnimation->render(canvas, &dst); |
| if (++x == COL_COUNT) { |
| x = 0; |
| y += 1; |
| } |
| } |
| } |
| |
| bool SkottieSlide2::animate(const SkAnimTimer& timer) { |
| for (auto& rec : fAnims) { |
| if (rec.fTimeBase == 0) { |
| // Reset the animation time. |
| rec.fTimeBase = timer.msec(); |
| } |
| rec.fAnimation->animationTick(timer.msec() - rec.fTimeBase); |
| } |
| return true; |
| } |
| |
| bool SkottieSlide2::onMouse(SkScalar x, SkScalar y, sk_app::Window::InputState state, |
| uint32_t modifiers) { |
| if (fTrackingCell < 0 && state == sk_app::Window::kDown_InputState) { |
| fTrackingCell = this->findCell(x, y); |
| } |
| if (fTrackingCell >= 0 && state == sk_app::Window::kUp_InputState) { |
| int index = this->findCell(x, y); |
| if (fTrackingCell == index) { |
| fAnims[index].fShowAnimationInval = !fAnims[index].fShowAnimationInval; |
| fAnims[index].fAnimation->setShowInval(fAnims[index].fShowAnimationInval); |
| } |
| fTrackingCell = -1; |
| } |
| return fTrackingCell >= 0; |
| } |
| |
| int SkottieSlide2::findCell(float x, float y) const { |
| x -= MARGIN; |
| y -= MARGIN; |
| int index = -1; |
| if (x >= 0 && y >= 0) { |
| int ix = (int)x; |
| int iy = (int)y; |
| int col = ix / (CELL_WIDTH + SPACER_X); |
| int row = iy / (CELL_HEIGHT + SPACER_Y); |
| index = row * COL_COUNT + col; |
| if (index >= fAnims.count()) { |
| index = -1; |
| } |
| } |
| return index; |
| } |