|  | /* | 
|  | * Copyright 2013 Google Inc. | 
|  | * | 
|  | * Use of this source code is governed by a BSD-style license that can be | 
|  | * found in the LICENSE file. | 
|  | */ | 
|  |  | 
|  | #include "gm/gm.h" | 
|  | #include "include/core/SkCanvas.h" | 
|  | #include "include/core/SkPaint.h" | 
|  | #include "include/core/SkPath.h" | 
|  | #include "include/core/SkPoint.h" | 
|  | #include "include/core/SkScalar.h" | 
|  | #include "include/core/SkSize.h" | 
|  | #include "include/core/SkString.h" | 
|  | #include "include/core/SkTypes.h" | 
|  | #include "tools/ToolUtils.h" | 
|  | #include "tools/timer/TimeUtils.h" | 
|  |  | 
|  | // Reproduces https://code.google.com/p/chromium/issues/detail?id=279014 | 
|  |  | 
|  | constexpr int kWidth = 440; | 
|  | constexpr int kHeight = 440; | 
|  | constexpr SkScalar kAngle = 0.305f; | 
|  | constexpr int kMaxNumSteps = 140; | 
|  |  | 
|  | // Renders a string art shape. | 
|  | // The particular shape rendered can be controlled by adjusting kAngle, from 0 to 1 | 
|  |  | 
|  | class StringArtGM : public skiagm::GM { | 
|  | public: | 
|  | StringArtGM() : fNumSteps(kMaxNumSteps) {} | 
|  |  | 
|  | protected: | 
|  |  | 
|  | SkString onShortName() override { | 
|  | return SkString("stringart"); | 
|  | } | 
|  |  | 
|  | SkISize onISize() override { | 
|  | return SkISize::Make(kWidth, kHeight); | 
|  | } | 
|  |  | 
|  | void onDraw(SkCanvas* canvas) override { | 
|  | SkScalar angle = kAngle*SK_ScalarPI + SkScalarHalf(SK_ScalarPI); | 
|  | SkScalar size = SkIntToScalar(std::min(kWidth, kHeight)); | 
|  | SkPoint center = SkPoint::Make(SkScalarHalf(kWidth), SkScalarHalf(kHeight)); | 
|  | SkScalar length = 5; | 
|  | SkScalar step = angle; | 
|  |  | 
|  | SkPath path; | 
|  | path.moveTo(center); | 
|  |  | 
|  | for (int i = 0; i < fNumSteps && length < (SkScalarHalf(size) - 10.f); ++i) { | 
|  | SkPoint rp = SkPoint::Make(length*SkScalarCos(step) + center.fX, | 
|  | length*SkScalarSin(step) + center.fY); | 
|  | path.lineTo(rp); | 
|  | length += angle / SkScalarHalf(SK_ScalarPI); | 
|  | step += angle; | 
|  | } | 
|  |  | 
|  | SkPaint paint; | 
|  | paint.setAntiAlias(true); | 
|  | paint.setStyle(SkPaint::kStroke_Style); | 
|  | paint.setColor(ToolUtils::color_to_565(0xFF007700)); | 
|  |  | 
|  | canvas->drawPath(path, paint); | 
|  | } | 
|  |  | 
|  | bool onAnimate(double nanos) override { | 
|  | constexpr SkScalar kDesiredDurationSecs = 3.0f; | 
|  |  | 
|  | // Make the animation ping-pong back and forth but start in the fully drawn state | 
|  | SkScalar fraction = 1.0f - TimeUtils::Scaled(1e-9 * nanos, 2.0f/kDesiredDurationSecs, 2.0f); | 
|  | if (fraction <= 0.0f) { | 
|  | fraction = -fraction; | 
|  | } | 
|  |  | 
|  | SkASSERT(fraction >= 0.0f && fraction <= 1.0f); | 
|  |  | 
|  | fNumSteps = (int) (fraction * kMaxNumSteps); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | private: | 
|  | int fNumSteps; | 
|  |  | 
|  | using INHERITED = GM; | 
|  | }; | 
|  |  | 
|  | DEF_GM( return new StringArtGM; ) | 
|  |  | 
|  | ///////////////////////////////////////////////////////////////////////////////////////////////// | 
|  |  | 
|  | #if 0 | 
|  | #include "modules/skottie/include/Skottie.h" | 
|  |  | 
|  | class SkottieGM : public skiagm::GM { | 
|  | enum { | 
|  | kWidth = 800, | 
|  | kHeight = 600, | 
|  | }; | 
|  |  | 
|  | enum { | 
|  | N = 100, | 
|  | }; | 
|  | skottie::Animation* fAnims[N]; | 
|  | SkRect              fRects[N]; | 
|  | SkScalar            fDur; | 
|  |  | 
|  | public: | 
|  | SkottieGM() { | 
|  | sk_bzero(fAnims, sizeof(fAnims)); | 
|  | } | 
|  | ~SkottieGM() override { | 
|  | for (auto anim : fAnims) { | 
|  | SkSafeUnref(anim); | 
|  | } | 
|  | } | 
|  |  | 
|  | protected: | 
|  |  | 
|  | SkString onShortName() override { return SkString("skottie"); } | 
|  |  | 
|  | SkISize onISize() override { return SkISize::Make(kWidth, kHeight); } | 
|  |  | 
|  | void init() { | 
|  | SkRandom rand; | 
|  | auto data = SkData::MakeFromFileName("/Users/reed/Downloads/maps_pinlet.json"); | 
|  | //     for (;;) skottie::Animation::Make((const char*)data->data(), data->size()); | 
|  | for (int i = 0; i < N; ++i) { | 
|  | fAnims[i] = skottie::Animation::Make((const char*)data->data(), data->size()).release(); | 
|  | SkScalar x = rand.nextF() * kWidth; | 
|  | SkScalar y = rand.nextF() * kHeight; | 
|  | fRects[i].setXYWH(x, y, 400, 400); | 
|  | } | 
|  | fDur = fAnims[0]->duration(); | 
|  | } | 
|  |  | 
|  | void onDraw(SkCanvas* canvas) override { | 
|  | if (!fAnims[0]) { | 
|  | this->init(); | 
|  | } | 
|  | canvas->drawColor(0xFFBBBBBB); | 
|  | for (int i = 0; i < N; ++i) { | 
|  | fAnims[0]->render(canvas, &fRects[i]); | 
|  | } | 
|  | } | 
|  |  | 
|  | bool onAnimate(double nanos) override { | 
|  | SkScalar time = (float)(fmod(1e-9 * nanos, fDur) / fDur); | 
|  | for (auto anim : fAnims) { | 
|  | anim->seek(time); | 
|  | } | 
|  | return true; | 
|  | } | 
|  |  | 
|  | private: | 
|  | using INHERITED = GM; | 
|  | }; | 
|  | DEF_GM( return new SkottieGM; ) | 
|  | #endif | 
|  |  |