1 /* 2 * Copyright 2013 Google Inc. 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 "gm/gm.h" 9 #include "include/core/SkCanvas.h" 10 #include "include/core/SkPaint.h" 11 #include "include/core/SkPath.h" 12 #include "include/core/SkPoint.h" 13 #include "include/core/SkScalar.h" 14 #include "include/core/SkSize.h" 15 #include "include/core/SkString.h" 16 #include "include/core/SkTypes.h" 17 #include "tools/ToolUtils.h" 18 #include "tools/timer/TimeUtils.h" 19 20 // Reproduces https://code.google.com/p/chromium/issues/detail?id=279014 21 22 constexpr int kWidth = 440; 23 constexpr int kHeight = 440; 24 constexpr SkScalar kAngle = 0.305f; 25 constexpr int kMaxNumSteps = 140; 26 27 // Renders a string art shape. 28 // The particular shape rendered can be controlled by adjusting kAngle, from 0 to 1 29 30 class StringArtGM : public skiagm::GM { 31 public: StringArtGM()32 StringArtGM() : fNumSteps(kMaxNumSteps) {} 33 34 protected: 35 onShortName()36 SkString onShortName() override { 37 return SkString("stringart"); 38 } 39 onISize()40 SkISize onISize() override { 41 return SkISize::Make(kWidth, kHeight); 42 } 43 onDraw(SkCanvas * canvas)44 void onDraw(SkCanvas* canvas) override { 45 SkScalar angle = kAngle*SK_ScalarPI + SkScalarHalf(SK_ScalarPI); 46 SkScalar size = SkIntToScalar(std::min(kWidth, kHeight)); 47 SkPoint center = SkPoint::Make(SkScalarHalf(kWidth), SkScalarHalf(kHeight)); 48 SkScalar length = 5; 49 SkScalar step = angle; 50 51 SkPath path; 52 path.moveTo(center); 53 54 for (int i = 0; i < fNumSteps && length < (SkScalarHalf(size) - 10.f); ++i) { 55 SkPoint rp = SkPoint::Make(length*SkScalarCos(step) + center.fX, 56 length*SkScalarSin(step) + center.fY); 57 path.lineTo(rp); 58 length += angle / SkScalarHalf(SK_ScalarPI); 59 step += angle; 60 } 61 62 SkPaint paint; 63 paint.setAntiAlias(true); 64 paint.setStyle(SkPaint::kStroke_Style); 65 paint.setColor(ToolUtils::color_to_565(0xFF007700)); 66 67 canvas->drawPath(path, paint); 68 } 69 onAnimate(double nanos)70 bool onAnimate(double nanos) override { 71 constexpr SkScalar kDesiredDurationSecs = 3.0f; 72 73 // Make the animation ping-pong back and forth but start in the fully drawn state 74 SkScalar fraction = 1.0f - TimeUtils::Scaled(1e-9 * nanos, 2.0f/kDesiredDurationSecs, 2.0f); 75 if (fraction <= 0.0f) { 76 fraction = -fraction; 77 } 78 79 SkASSERT(fraction >= 0.0f && fraction <= 1.0f); 80 81 fNumSteps = (int) (fraction * kMaxNumSteps); 82 return true; 83 } 84 85 private: 86 int fNumSteps; 87 88 using INHERITED = GM; 89 }; 90 91 DEF_GM( return new StringArtGM; ) 92 93 ///////////////////////////////////////////////////////////////////////////////////////////////// 94 95 #if 0 96 #include "modules/skottie/include/Skottie.h" 97 98 class SkottieGM : public skiagm::GM { 99 enum { 100 kWidth = 800, 101 kHeight = 600, 102 }; 103 104 enum { 105 N = 100, 106 }; 107 skottie::Animation* fAnims[N]; 108 SkRect fRects[N]; 109 SkScalar fDur; 110 111 public: 112 SkottieGM() { 113 sk_bzero(fAnims, sizeof(fAnims)); 114 } 115 ~SkottieGM() override { 116 for (auto anim : fAnims) { 117 SkSafeUnref(anim); 118 } 119 } 120 121 protected: 122 123 SkString onShortName() override { return SkString("skottie"); } 124 125 SkISize onISize() override { return SkISize::Make(kWidth, kHeight); } 126 127 void init() { 128 SkRandom rand; 129 auto data = SkData::MakeFromFileName("/Users/reed/Downloads/maps_pinlet.json"); 130 // for (;;) skottie::Animation::Make((const char*)data->data(), data->size()); 131 for (int i = 0; i < N; ++i) { 132 fAnims[i] = skottie::Animation::Make((const char*)data->data(), data->size()).release(); 133 SkScalar x = rand.nextF() * kWidth; 134 SkScalar y = rand.nextF() * kHeight; 135 fRects[i].setXYWH(x, y, 400, 400); 136 } 137 fDur = fAnims[0]->duration(); 138 } 139 140 void onDraw(SkCanvas* canvas) override { 141 if (!fAnims[0]) { 142 this->init(); 143 } 144 canvas->drawColor(0xFFBBBBBB); 145 for (int i = 0; i < N; ++i) { 146 fAnims[0]->render(canvas, &fRects[i]); 147 } 148 } 149 150 bool onAnimate(double nanos) override { 151 SkScalar time = (float)(fmod(1e-9 * nanos, fDur) / fDur); 152 for (auto anim : fAnims) { 153 anim->seek(time); 154 } 155 return true; 156 } 157 158 private: 159 using INHERITED = GM; 160 }; 161 DEF_GM( return new SkottieGM; ) 162 #endif 163 164