diff --git a/docs/examples/Color_Wheel.cpp b/docs/examples/Color_Wheel.cpp new file mode 100644 index 0000000000..f5f738bd22 --- /dev/null +++ b/docs/examples/Color_Wheel.cpp @@ -0,0 +1,46 @@ +// Copyright 2020 Google LLC. +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. +#include "tools/fiddle/examples.h" +REG_FIDDLE(Color_Wheel, 256, 256, false, 0) { +static void draw_center_letter(SkCanvas* canvas, const char* str , const SkFont& font, + SkScalar x, SkScalar y, SkColor4f color) { + SkRect bnds; + font.measureText(str, strlen(str), SkTextEncoding::kUTF8, &bnds); + canvas->drawString(str, x - bnds.centerX(), y - bnds.centerY(), font, SkPaint(color)); +} + +void draw(SkCanvas* canvas) { + constexpr float SCALE = 256; + constexpr float STROKE = 12; + SkAutoCanvasRestore autoCanvasRestore(canvas, true); + canvas->translate(0.5f * SCALE, 0.5f * SCALE); + canvas->clear(0); + canvas->drawCircle({0, 0}, (SCALE - STROKE) * 0.5f, SkPaint(SkColors::kWhite)); + { + SkPaint sweep; + const SkMatrix rotate = SkMatrix::MakeAll(0, -1, 0, 1, 0, 0, 0, 0, 1); + static const SkColor4f kColors[7] = { + SkColors::kRed, SkColors::kYellow, SkColors::kGreen, SkColors::kCyan, + SkColors::kBlue, SkColors::kMagenta, SkColors::kRed}; + sweep.setShader( + SkGradientShader::MakeSweep(0, 0, kColors, nullptr, nullptr, 7, 0, &rotate)); + sweep.setStyle(SkPaint::kStroke_Style); + sweep.setStrokeWidth(STROKE); + canvas->drawCircle({0, 0}, (SCALE - STROKE) * 0.5f, sweep); + } + const double sqrt_3_over_2 = 0.8660254037844387; + const SkScalar D = 0.3f * SCALE; + const SkScalar X = (float)(D * sqrt_3_over_2); + const SkScalar Y = D * 0.5f; + + sk_sp fontMgr = SkFontMgr::RefDefault(); + SkFont font(fontMgr->legacyMakeTypeface(nullptr, SkFontStyle::Bold()), 0.28125f * SCALE); + draw_center_letter(canvas, "K", font, 0, 0, SkColors::kBlack); + draw_center_letter(canvas, "R", font, 0, D, SkColors::kRed); + draw_center_letter(canvas, "G", font, -X, -Y, SkColors::kGreen); + draw_center_letter(canvas, "B", font, X, -Y, SkColors::kBlue); + draw_center_letter(canvas, "C", font, 0, -D, SkColors::kCyan); + draw_center_letter(canvas, "M", font, X, Y, SkColors::kMagenta); + draw_center_letter(canvas, "Y", font, -X, Y, SkColors::kYellow); +} +} // END FIDDLE diff --git a/docs/examples/Octopus_Generator_Animated.cpp b/docs/examples/Octopus_Generator_Animated.cpp new file mode 100644 index 0000000000..183d3490fb --- /dev/null +++ b/docs/examples/Octopus_Generator_Animated.cpp @@ -0,0 +1,37 @@ +// Copyright 2020 Google LLC. +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. +#include "tools/fiddle/examples.h" +REG_FIDDLE_ANIMATED(Octopus_Generator_Animated, 256, 256, false, 0, 4) { +void paintOctopus(int x, int y, int size_base, SkColor color, SkCanvas* canvas) { + SkPaint paint; + paint.setAntiAlias(true); + paint.setColor(color); + int radius = 3*size_base; + canvas->drawCircle(x, y, radius, paint); + for (int leg = 0; leg < 8; ++leg) { + canvas->drawCircle(x - radius + (2*radius/7.5*leg), + y + radius - pow(abs(4-leg), 2), size_base/2 + 2, paint); + } + paint.setColor(SkColorSetRGB(SkColorGetR(color) + 20, + SkColorGetG(color) + 20, + SkColorGetB(color) + 20)); + canvas->drawCircle(x-size_base, y+size_base, size_base/2, paint); + canvas->drawCircle(x+size_base, y+size_base, size_base/2, paint); +} + +void draw(SkCanvas* canvas) { + SkRandom rand; + + for (int i = 0; i < 400; ++i) { + float x = rand.nextRangeScalar(0, 256); + float y = rand.nextRangeScalar(0, 256); + float s = rand.nextRangeScalar(6, 12); + SkColor c = rand.nextU() | SkColorSetARGB(255, 0, 0, 0); + float radius = rand.nextRangeScalar(0, 40); + float angle = (rand.nextRangeScalar(0, 1) + frame) * 6.28319; + x += radius * cos(angle); + y += radius * sin(angle); + paintOctopus(x, y, s, c, canvas); + } +} +} // END FIDDLE diff --git a/docs/examples/SKIA_LOGO_ANIMATE.cpp b/docs/examples/SKIA_LOGO_ANIMATE.cpp new file mode 100644 index 0000000000..63e167e38e --- /dev/null +++ b/docs/examples/SKIA_LOGO_ANIMATE.cpp @@ -0,0 +1,118 @@ +// Copyright 2020 Google LLC. +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. +#include "tools/fiddle/examples.h" +REG_FIDDLE_ANIMATED(SKIA_LOGO_ANIMATE, 816, 464, false, 0, 2) { +void draw(SkCanvas* canvas) { + canvas->scale(4.0f, 4.0f); + const SkColor background = SK_ColorWHITE; // SK_ColorTRANSPARENT; + const SkColor lettering = 0xFF292929; + const SkColor lineColors[2] = {0x30565656, 0xFF565656}; + SkPath s, k, a, triangle; + SkPaint p; + p.setAntiAlias(true); + + canvas->clear(background); + canvas->scale(0.363f, 0.363f); + + + s.moveTo(34.63, 100.63); + s.cubicTo(44.38, 88.57, 59.87, 82.86, 74.88, 81.2); + s.cubicTo(97.4, 78.5, 120.27, 83.25, 140.87, 92.37); + s.lineTo(127.12, 127.14); + s.cubicTo(113.55, 121.16, 99.04, 115.9, 83.98, 116.56); + s.cubicTo(78.86, 116.75, 72.88, 118.54, 70.71, 123.69); + s.cubicTo(68.62, 128.43, 71.52, 133.68, 75.58, 136.27); + s.cubicTo(91.49, 146.66, 110.67, 151.38, 125.46, 163.6); + s.cubicTo(132.35, 169.11, 137.33, 176.9, 139.36, 185.49); + s.cubicTo(142.55, 199.14, 140.94, 214.31, 133.13, 226.17); + s.cubicTo(126.23, 236.96, 114.82, 244.16, 102.75, 247.89); + s.cubicTo(87.95, 252.51, 72.16, 252.21, 56.88, 250.78); + s.cubicTo(45.54, 249.72, 34.64, 246.05, 24.32, 241.36); + s.lineTo(24.25, 201.1); + s.cubicTo(38.23, 208.15, 53.37, 213.15, 68.98, 214.75); + s.cubicTo(75.42, 215.25, 82.17, 215.63, 88.31, 213.27); + s.cubicTo(92.84, 211.53, 96.4, 206.93, 95.86, 201.93); + s.cubicTo(95.64, 196.77, 91.1, 193.38, 87.03, 190.99); + s.cubicTo(71.96, 182.67, 54.94, 177.66, 41.5, 166.57); + s.cubicTo(33.19, 159.73, 27.51, 149.8, 26.1, 139.11); + s.cubicTo(24.09, 125.88, 25.91, 111.25, 34.63, 100.63); + canvas->drawPath(s, p); + + k.moveTo(160.82, 82.85); + k.lineTo(206.05, 82.85); + k.lineTo(206.05, 155.15); + k.lineTo(254.83, 82.84); + k.lineTo(304.01, 82.85); + k.lineTo(251.52, 157.27); + k.lineTo(303.09, 249.42); + k.lineTo(252.28, 249.4); + k.lineTo(219.18, 185.75); + k.lineTo(206.23, 193.45); + k.lineTo(206.05, 249.42); + k.lineTo(160.82, 249.42); + k.lineTo(160.82, 82.85); + canvas->drawPath(k, p); + + a.moveTo(426.45, 218.16); + a.lineTo(480.705, 218.16); + a.lineTo(489.31, 249.4); + a.lineTo(538.54, 249.42); + a.lineTo(483.56, 82.18); + a.lineTo(423.43, 82.17); + a.lineTo(369.13, 249.42); + a.lineTo(418.5, 249.47); + a.lineTo(453.75, 109.83); + a.lineTo(471.77, 181.28); + a.lineTo(430.5, 181.28); + canvas->drawPath(a, p); + + canvas->save(); + + float pos = frame > 0.5 ? 1 : frame * 2; + canvas->translate((1-pos) * -200.0, 0.0); + + const SkColor rgb[] = {0xFFE94037, 0xFF70BF4F, 0xFF465BA6}; + const uint8_t alpha = pos*255.999; + + p.setColor(rgb[1]); + p.setAlpha(alpha); + canvas->drawRect({326.0, 82.25, 343.9, 249.2}, p); + p.setColor(rgb[0]); + p.setAlpha(alpha); + canvas->drawRect({310.2, 82.25, 327.0, 249.2}, p); + p.setColor(rgb[2]); + p.setAlpha(alpha); + canvas->drawRect({342.9, 82.25, 358.87, 249.2}, p); + + p.setColor(lettering); + //p.setAlpha(cast_alpha(pos)); + canvas->drawCircle(335.355, 45.965, 29.25, p); + + triangle.reset(); + triangle.moveTo(362.64, 257.32); + triangle.lineTo(335.292, 293.392); + triangle.lineTo(307.8, 257.48); + triangle.lineTo(362.64, 257.32); + p.setColor(lettering); + canvas->drawPath(triangle, p); + + canvas->restore(); + + // line + const SkPoint pts[2] = {{160, 290}, {341, 290}}; + p.setShader(SkGradientShader::MakeLinear( + pts, lineColors, NULL, 2, SkTileMode::kClamp)); + if (true) { + SkRRect rrectClip; + rrectClip.setRectXY({138, 291, 138 + pos*(341-138), 300}, 25.0, 5.0); + canvas->clipRRect(rrectClip, SkClipOp::kIntersect); + SkRRect rrect; + rrect.setRectXY({138, 291, 341, 300}, 25.0, 5.0); + canvas->drawRRect(rrect, p); + } else { + SkPath path; + path.addRoundRect({138, 291, 341, 299.95}, 25.0, 5.0); + canvas->drawPath(path, p); + } +} +} // END FIDDLE diff --git a/docs/examples/SkPath_cubicTo_example_parametric_animated.cpp b/docs/examples/SkPath_cubicTo_example_parametric_animated.cpp new file mode 100644 index 0000000000..92eb2a3963 --- /dev/null +++ b/docs/examples/SkPath_cubicTo_example_parametric_animated.cpp @@ -0,0 +1,100 @@ +// Copyright 2020 Google LLC. +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. +#include "tools/fiddle/examples.h" +REG_FIDDLE_ANIMATED(SkPath_cubicTo_example_parametric_animated, 512, 512, false, 0, 3) { +/* + If the starting point is (x0, y0), then this curve is defined as the + paramentric curve as `t` goes from 0 to 1: + s := 1 - t + x := (s * s * s * x0) + + (3 * s * s * t * x1) + + (3 * s * t * t * x2) + + (t * t * t * x3) + y := (s * s * s * y0) + + (3 * s * s * t * y1) + + (3 * s * t * t * y2) + + (t * t * t * y3) + +*/ + +SkPoint cubic(SkPoint p0, SkPoint p1, SkPoint p2, SkPoint p3, float t) { + // a simple mathematical definition of cubic curve. + // There are faster ways to calculate this. + float s = 1 - t; + return {(s * s * s * p0.x()) + + (3 * s * s * t * p1.x()) + + (3 * s * t * t * p2.x()) + + (t * t * t * p3.x()), + (s * s * s * p0.y()) + + (3 * s * s * t * p1.y()) + + (3 * s * t * t * p2.y()) + + (t * t * t * p3.y())}; +} + +static SkPoint interpolate(SkPoint a, SkPoint b, float t) { + return {SkScalarInterp(a.x(), b.x(), t), + SkScalarInterp(a.y(), b.y(), t)}; +} + +void draw(SkCanvas* canvas) { + canvas->clear(SkColorSetARGB(255,255,255,255)); + + SkPoint a{136, 64}; + SkPoint b{448, 448}; + SkPoint c{64, 448}; + SkPoint d{376, 64}; + + SkPoint ab = interpolate(a, b, frame); + SkPoint bc = interpolate(b, c, frame); + SkPoint cd = interpolate(c, d, frame); + SkPoint abc = interpolate(ab, bc, frame); + SkPoint bcd = interpolate(bc, cd, frame); + + SkPaint paint; + paint.setAntiAlias(true); + paint.setStyle(SkPaint::kStroke_Style); + paint.setStrokeWidth(1); + + canvas->drawLine(ab, bc, paint); + canvas->drawLine(bc, cd, paint); + canvas->drawLine(abc, bcd, paint); + + paint.setStrokeWidth(3); + canvas->drawLine(a, b, paint); + canvas->drawLine(b, c, paint); + canvas->drawLine(c, d, paint); + + paint.setStrokeWidth(5); + paint.setColor(SkColorSetARGB(255, 0, 0, 255)); + SkPath cubicCurve; + cubicCurve.moveTo(a); + cubicCurve.cubicTo(b, c, d); + canvas->drawPath(cubicCurve, paint); + + SkFont font(nullptr, 32); + SkPaint textPaint; + textPaint.setColor(SkColorSetARGB(255, 0, 255, 0)); + textPaint.setAntiAlias(true); + sk_sp mgr(SkFontMgr::RefDefault()); + sk_sp face(mgr->matchFamilyStyle("DejaVu Sans Mono", SkFontStyle())); + canvas->drawString("a", a.x(), a.y(), font, textPaint); + canvas->drawString("b", b.x(), b.y(), font, textPaint); + canvas->drawString("c", c.x()-20, c.y(), font, textPaint); + canvas->drawString("d", d.x(), d.y(), font, textPaint); + SkString msg = SkStringPrintf("%.4f", frame); + textPaint.setColor(SkColorSetARGB(255, 204, 204, 204)); + canvas->drawString(msg.c_str(), 4, 36, font, textPaint); + + SkPaint pointPaint; + pointPaint.setAntiAlias(true); + pointPaint.setStrokeWidth(8); + pointPaint.setStrokeCap(SkPaint::kRound_Cap); + + pointPaint.setColor(SkColorSetARGB(255, 255, 0, 0)); + canvas->drawPoint(interpolate(abc, bcd, frame), pointPaint); + + pointPaint.setColor(SkColorSetARGB(255, 0, 255, 0)); + pointPaint.setStrokeWidth(7); + canvas->drawPoint(cubic(a, b, c, d, frame), pointPaint); +} +} // END FIDDLE diff --git a/docs/examples/SkPath_quadTo_example_parametric_animated.cpp b/docs/examples/SkPath_quadTo_example_parametric_animated.cpp new file mode 100644 index 0000000000..92b39d3a47 --- /dev/null +++ b/docs/examples/SkPath_quadTo_example_parametric_animated.cpp @@ -0,0 +1,79 @@ +// Copyright 2020 Google LLC. +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. +#include "tools/fiddle/examples.h" +REG_FIDDLE_ANIMATED(SkPath_quadTo_example_parametric_animated, 512, 512, false, 0, 4) { +// SkPath_quadTo_example_parametric_animated + +SkPoint quad(SkPoint p0, SkPoint p1, SkPoint p2, float t) { + float s = 1 - t; + return {(s * s * p0.x()) + (2 * s * t * p1.x()) + (t * t * p2.x()), + (s * s * p0.y()) + (2 * s * t * p1.y()) + (t * t * p2.y())}; +} + +/* + + If the starting point is (x0, y0), then this curve is defined as the + paramentric curve as `t` goes from 0 to 1: + + s := 1 - t + x := (s * s * x0) + (2 * s * t * x1) + (t * t * x2) + y := (s * s * y0) + (2 * s * t * y1) + (t * t * y2) + +*/ + +static SkPoint interpolate(SkPoint a, SkPoint b, float t) { + return {SkScalarInterp(a.x(), b.x(), t), + SkScalarInterp(a.y(), b.y(), t)}; +} + +static void draw_line(SkCanvas* canvas, SkPoint p0, SkPoint p1, const SkPaint& paint) { + canvas->drawLine(p0.x(), p0.y(), p1.x(), p1.y(), paint); +} + +static void draw_point(SkCanvas* canvas, SkPoint p, const SkPaint& paint) { + canvas->drawPoint(p.x(), p.y(), paint); +} + +void draw(SkCanvas* canvas) { + canvas->clear(SkColorSetARGB(255,255,255,255)); + + SkPaint paint; + paint.setAntiAlias(true); + paint.setStyle(SkPaint::kStroke_Style); + paint.setStrokeWidth(5); + + SkPoint a{10, 100}; + SkPoint b{200, 400}; + SkPoint c{390, 100}; + + SkPoint ab = interpolate(a, b, frame); + SkPoint bc = interpolate(b, c, frame); + + draw_line(canvas, a, b, paint); + draw_line(canvas, b, c, paint); + + paint.setStrokeWidth(1); + draw_line(canvas, ab, bc, paint); + paint.setStrokeWidth(5); + + paint.setColor(SkColorSetARGB(255,0,0,255)); + SkPath quadraticCurve; + quadraticCurve.moveTo(a); + quadraticCurve.quadTo(b, c); + canvas->drawPath(quadraticCurve, paint); + + SkPaint textPaint; + SkFont font(nullptr, 32); + textPaint.setAntiAlias(true); + canvas->drawString("a", a.x(), a.y(), font, textPaint); + canvas->drawString("b", b.x()+20, b.y()+20, font, textPaint); + canvas->drawString("c", c.x(), c.y(), font, textPaint); + + SkPaint pointPaint; + pointPaint.setAntiAlias(true); + pointPaint.setStrokeWidth(8); + pointPaint.setStrokeCap(SkPaint::kRound_Cap); + pointPaint.setColor(SkColorSetARGB(255, 0, 255, 0)); + draw_point(canvas, quad(a, b, c, frame), pointPaint); +} +} // END FIDDLE diff --git a/docs/examples/Turtle.cpp b/docs/examples/Turtle.cpp new file mode 100644 index 0000000000..5275b7cfdb --- /dev/null +++ b/docs/examples/Turtle.cpp @@ -0,0 +1,74 @@ +// Copyright 2020 Google LLC. +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. +#include "tools/fiddle/examples.h" +REG_FIDDLE_ANIMATED(Turtle, 256, 256, false, 0, 2) { +// Simple turtle based graphics. The turtle starts out at 128, 128, looking North, pen down. +// The input string is read left to right (but see 'r' below). Commands are a single character, +// sometimes followed by additional arguments: +// +// u : Raises the pen +// d : Lowers the pen +// + : Reads integer N, rotates turtle N degrees clockwise +// - : Reads integer N, rotates turtle N degrees counterclockwise +// f : Reads integer N, moves turtle forwards N units +// r : Reads integer N, then separator character C. C should be some non-digit, non-command +// character. Repeats all commands after C until the next instance of C, N times. Can be +// nested. +//const char* input = "r2[r3(f50+90f50+90f50+90f50(+45uf50d["; +//const char* input = "r360|f1+1|"; +const char* input = "uf100+91dr180|f3+2|+89uf60+90r2$f20-90dr60|f1+6|u-90f20$-90f50-90f30d+180f60uf1000"; + +struct Turtle { float x; float y; float h; bool p; } t; + +const SkPaint& p() { + static SkPaint paint; + paint.setColor(SK_ColorBLACK); + paint.setAntiAlias(true); + paint.setStyle(SkPaint::kStroke_Style); + paint.setStrokeWidth(0); + return paint; +} + +const char* eval(SkCanvas* canvas, const char* s, char e, float& dist, float& l, bool pt) { + while (*s != e) { + switch(*s++) { + case 'u': t.p = false; break; + case 'd': t.p = true; break; + case '+': t.h += atoi(s); break; + case '-': t.h -= atoi(s); break; + case 'f': { + float d = atoi(s); + d = std::min(d, l); + dist += d; l -= d; + float r = t.h * 0.01745329f; + auto s = sinf(r), c = cosf(r); + Turtle nt = { t.x + s * d, t.y - c * d, t.h, t.p }; + if (pt && t.p) canvas->drawLine(t.x, t.y, nt.x, nt.y, p()); + t = nt; + break; + } + case 'r': { + int c = atoi(s); + while (*s >= '0' && *s <= '9') { ++s; } + auto n = s+1; + for (int i = 0; i < c; ++i) { n = eval(canvas, s+1, *s, dist, l, pt); } + s = n; + } + } + } + return s+1; +} + +void draw(SkCanvas* canvas) { + canvas->clear(SK_ColorWHITE); + + t = { 128, 128, 0, true }; + float totalDist = 0; + float l = 1E9f; + eval(canvas, input, 0, totalDist, l, false); + + l = frame * totalDist; + t = { 128, 128, 0, true }; + eval(canvas, input, 0, totalDist, l, true); +} +} // END FIDDLE diff --git a/docs/examples/l_system_plant.cpp b/docs/examples/l_system_plant.cpp new file mode 100644 index 0000000000..89eba4de22 --- /dev/null +++ b/docs/examples/l_system_plant.cpp @@ -0,0 +1,75 @@ +// Copyright 2020 Google LLC. +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. +#include "tools/fiddle/examples.h" +REG_FIDDLE_ANIMATED(l_system_plant, 256, 256, false, 0, 3) { +// L-System +// https://en.wikipedia.org/wiki/L-system#Example_7:_Fractal_plant + +struct rules_t { + char c; + std::string s; +}; + +rules_t rules[6] = { + {'X', "F-[[X]+X]+F[+FX]-X"}, + {'F', "FF"}, + {'+', "+"}, + {'-', "-"}, + {'[', "["}, + {']', "]"}, +}; + +std::string E(std::string s) { + if (s.size() == 0) { + return ""; + } + for (int i=0; i<6; i++) { + if (rules[i].c == s[0]) { + return rules[i].s + E(s.substr(1)); + } + } + return ""; +} + +struct Pt { + SkScalar x; + SkScalar y; + SkScalar a; +}; + +void draw(SkCanvas* canvas) { + canvas->drawColor(SK_ColorLTGRAY); + + SkPaint p; + p.setColor(0xFFA6761D); + p.setAntiAlias(true); + p.setStyle(SkPaint::kStroke_Style); + p.setStrokeWidth(1); + + std::vector ptstack; + std::string plant = E(E(E(E(E("X"))))); + const double len = 2.5; + struct Pt pt = {128, 256, 3.14}; + SkPath path; + path.moveTo(pt.x, pt.y); + + for (std::string::iterator it=plant.begin(); it!=plant.end(); ++it) { + if (*it == 'F') { + pt.x += len*sin(pt.a); + pt.y += len*cos(pt.a); + path.lineTo(pt.x, pt.y); + } else if (*it == '+') { + pt.a += (0.15 + sin(frame*2.0*3.14159)*0.05); + } else if (*it == '-') { + pt.a += (-0.15 + sin(frame*2.0*3.14159)*0.05); + } else if (*it == '[') { + ptstack.push_back(pt); + } else if (*it == ']') { + pt = ptstack.back(); + ptstack.pop_back(); + path.moveTo(pt.x, pt.y); + } + } + canvas->drawPath(path, p); +} +} // END FIDDLE diff --git a/docs/examples/pong.cpp b/docs/examples/pong.cpp new file mode 100644 index 0000000000..ccc02d3101 --- /dev/null +++ b/docs/examples/pong.cpp @@ -0,0 +1,33 @@ +// Copyright 2020 Google LLC. +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. +#include "tools/fiddle/examples.h" +REG_FIDDLE_ANIMATED(pong, 256, 256, false, 0, 10) { +static SkScalar PingPong(double t, SkScalar period, SkScalar phase, + SkScalar ends, SkScalar mid) { + double value = ::fmod(t + phase, period); + double half = period / 2.0; + double diff = ::fabs(value - half); + return SkDoubleToScalar(ends + (1.0 - diff / half) * (mid - ends)); +} + +void draw(SkCanvas* canvas) { + canvas->clear(SK_ColorBLACK); + float ballX = PingPong(frame * duration, 2.5f, 0.0f, 0.0f, 1.0f); + float ballY = PingPong(frame * duration, 2.0f, 0.4f, 0.0f, 1.0f); + + SkPaint p; + p.setColor(SK_ColorWHITE); + p.setAntiAlias(true); + + float bX = ballX * 472 + 20; + float bY = ballY * 200 + 28; + + if (canvas->getGrContext()) { + canvas->drawRect(SkRect::MakeXYWH(236, bY - 15, 10, 30), p); + bX -= 256; + } else { + canvas->drawRect(SkRect::MakeXYWH(10, bY - 15, 10, 30), p); + } + canvas->drawCircle(bX, bY, 5, p); +} +} // END FIDDLE diff --git a/docs/examples/pong2.cpp b/docs/examples/pong2.cpp new file mode 100644 index 0000000000..0cf5630b16 --- /dev/null +++ b/docs/examples/pong2.cpp @@ -0,0 +1,31 @@ +// Copyright 2020 Google LLC. +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. +#include "tools/fiddle/examples.h" +REG_FIDDLE_ANIMATED(pong2, 512, 256, false, 0, 10) { +static SkScalar PingPong(double t, SkScalar period, SkScalar phase, + SkScalar ends, SkScalar mid) { + double value = ::fmod(t + phase, period); + double half = period / 2.0; + double diff = ::fabs(value - half); + return SkDoubleToScalar(ends + (1.0 - diff / half) * (mid - ends)); +} + +void draw(SkCanvas* canvas) { + float bX = PingPong(frame * duration, 2.5f, 0.0f, 0, 1) * 472 + 20; + float bY = PingPong(frame * duration, 2.0f, 0.4f, 0, 1) * 200 + 28; + + SkPaint p; + p.setColor(SK_ColorWHITE); + p.setAntiAlias(true); + + canvas->clear(SK_ColorBLACK); + canvas->drawRect(SkRect::MakeXYWH(492, bY - 15, 10, 30), p); + canvas->drawRect(SkRect::MakeXYWH(10, bY - 15, 10, 30), p); + canvas->drawCircle(bX, bY, 5, p); + + const float intervals[] = { 12, 6 }; + p.setStrokeWidth(5); + p.setPathEffect(SkDashPathEffect::Make(intervals, SK_ARRAY_COUNT(intervals), 0)); + canvas->drawLine({256,0}, {256, 256}, p); +} +} // END FIDDLE diff --git a/docs/examples/radial_gradient_shader_with_animated_color.cpp b/docs/examples/radial_gradient_shader_with_animated_color.cpp new file mode 100644 index 0000000000..75ae6f53f6 --- /dev/null +++ b/docs/examples/radial_gradient_shader_with_animated_color.cpp @@ -0,0 +1,15 @@ +// Copyright 2020 Google LLC. +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. +#include "tools/fiddle/examples.h" +REG_FIDDLE_ANIMATED(radial_gradient_shader_with_animated_color, 256, 256, false, 0, 2) { +void draw(SkCanvas* canvas) { + float p = 0.5 * (1 - cos(6.28318548f * frame)); + SkColor blue = SkColor(0xff * p) | 0xFF000000; + SkColor colors[2] = {blue, SK_ColorYELLOW}; + SkPaint paint; + paint.setShader(SkGradientShader::MakeRadial( + SkPoint::Make(128.0f, 128.0f), 180.0f, + colors, nullptr, 2, SkTileMode::kClamp, 0, nullptr)); + canvas->drawPaint(paint); +} +} // END FIDDLE diff --git a/docs/examples/shapes_with_motion.cpp b/docs/examples/shapes_with_motion.cpp new file mode 100644 index 0000000000..6227348add --- /dev/null +++ b/docs/examples/shapes_with_motion.cpp @@ -0,0 +1,33 @@ +// Copyright 2020 Google LLC. +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. +#include "tools/fiddle/examples.h" +REG_FIDDLE_ANIMATED(shapes_with_motion, 256, 256, false, 5, 4) { +void draw(SkCanvas* canvas) { + //float p = 1 - fabs(2 * frame - 1); + float p = 0.5 * (1 - cos(6.28318548f * frame)); + canvas->drawColor(SK_ColorWHITE); + + SkPaint paint; + paint.setStyle(SkPaint::kFill_Style); + paint.setAntiAlias(true); + paint.setStrokeWidth(4); + paint.setColor(0xffFE938C); + + SkRect rect = SkRect::MakeXYWH(10, 10, 100, 160); + canvas->drawRect(rect, paint); + + SkRRect oval; + oval.setOval(rect); + oval.offset(40, p * 80); + paint.setColor(0xffE6B89C); + canvas->drawRRect(oval, paint); + + paint.setColor(0xff9CAFB7); + canvas->drawCircle(180 * p, 50, 25, paint); + + rect.offset(80, 50); + paint.setColor(0xff4281A4); + paint.setStyle(SkPaint::kStroke_Style); + canvas->drawRoundRect(rect, 10, 10, paint); +} +} // END FIDDLE diff --git a/docs/examples/skew_x_animated.cpp b/docs/examples/skew_x_animated.cpp new file mode 100644 index 0000000000..92b3f675e2 --- /dev/null +++ b/docs/examples/skew_x_animated.cpp @@ -0,0 +1,19 @@ +// Copyright 2020 Google LLC. +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. +#include "tools/fiddle/examples.h" +REG_FIDDLE_ANIMATED(skew_x_animated, 256, 256, false, 6, 6) { +void draw(SkCanvas* canvas) { + canvas->clear(SK_ColorWHITE); + SkMatrix matrix; + matrix.setAll(2, 5 * cos(6.28318548 * frame), 0, + 0, 2, 128, + 0, 0, 1); + SkPaint paint; + paint.setShader( + image->makeShader( + SkTileMode::kRepeat, + SkTileMode::kRepeat, + &matrix)); + canvas->drawPaint(paint); +} +} // END FIDDLE diff --git a/docs/examples/software_bitmap_w_perspective.cpp b/docs/examples/software_bitmap_w_perspective.cpp new file mode 100644 index 0000000000..555d0af74b --- /dev/null +++ b/docs/examples/software_bitmap_w_perspective.cpp @@ -0,0 +1,19 @@ +// Copyright 2020 Google LLC. +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. +#include "tools/fiddle/examples.h" +REG_FIDDLE_ANIMATED(software_bitmap_w_perspective, 256, 256, false, 6, 5) { +void draw(SkCanvas* canvas) { + const float width = image->width(); + const float height = image->height(); + + const SkPoint src[] = {{ 0, 0}, {width, 0}, {width * (float)frame, height * (float)frame}, { 0, height}}; + const SkPoint dst[] = { {0, 0}, {width, 0}, {width, height}, {0, height} }; + + SkMatrix matrix; + matrix.setPolyToPoly(src, dst, 4); + + SkAutoCanvasRestore acr(canvas, true); + canvas->concat(matrix); + canvas->drawImage(image, 0, 0); +} +} // END FIDDLE diff --git a/experimental/tools/get_examples.py b/experimental/tools/get_examples.py new file mode 100755 index 0000000000..60a64a8bea --- /dev/null +++ b/experimental/tools/get_examples.py @@ -0,0 +1,90 @@ +#! /usr/bin/env python +# Copyright 2020 Google LLC. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +''' +get_examples.py: Populate docs/examples/ from the list of named fiddles. +''' + +import os +import re +import sys + +if sys.version_info[0] < 3: + from urllib2 import urlopen + from HTMLParser import HTMLParser + def unescape(v): return HTMLParser().unescape(v) +else: + from urllib.request import urlopen + from html.parser import HTMLParser + from html import unescape + +def cxx_bool(v): return 'true' if v else 'false' + +assert os.pardir == '..' and '/' in [os.sep, os.altsep] + +def process_fiddle(name): + if name == 'MAD_Magazine_Oct_1985': + return + filename = 'docs/examples/%s.cpp' % name + if os.path.exists(filename): + return + url = 'https://fiddle.skia.org/c/@' + name + content = urlopen(url).read() + regex = (']*>(.*)') + match = re.search(regex, content.decode('utf-8'), flags=re.S) + if not match: + sys.stderr.write('error: %s\n' % url) + + width = match.group(1) + height = match.group(2) + source_image = match.group(3) + code = unescape(match.group(5)) + extra = re.sub('\s+', ' ', match.group(4)) + textonly = 'textonly' in extra + + mduration = re.search(' duration="([0-9]+)" ', extra) + duration = int(mduration.group(1)) if mduration else 0 + + skip = False + for term in ['offscreen_texturable', 'offscreen_mipmap', 'srgb']: + if ' ' + term + ' ' in extra: + sys.stdout.write('SKIPPING [%s]: %s\n' % (term, name)) + skip = True + if skip: + sys.stdout.flush() + return + + sys.stdout.write('Writing to: %s\n' % filename) + sys.stdout.flush() + with open(filename, 'w') as o: + o.write('// Copyright 2020 Google LLC.\n' + '// Use of this source code is governed by a BSD-style' + ' license that can be found in the LICENSE file.\n' + '#include "tools/fiddle/examples.h"\n') + if duration: + o.write('REG_FIDDLE_ANIMATED(') + o.write(', '.join([name, width, height, cxx_bool(textonly), + source_image, str(duration)])) + else: + o.write('REG_FIDDLE(') + o.write(', '.join([name, width, height, cxx_bool(textonly), + source_image])) + o.write(') {\n') + o.write(code) + o.write('\n} // END FIDDLE\n') + +def main(): + os.chdir(os.path.dirname(__file__) + '/../..') + for line in urlopen('https://fiddle.skia.org/named/'): + line_match = re.search(r'/c/@([A-Za-z0-9_-]*)', line.decode('utf-8')) + if not line_match: + continue + name = line_match.group(1) + process_fiddle(name) + +if __name__ == '__main__': + main() diff --git a/tools/fiddle/all_examples.cpp b/tools/fiddle/all_examples.cpp index 1af6dd7b5f..6a52cd96ec 100644 --- a/tools/fiddle/all_examples.cpp +++ b/tools/fiddle/all_examples.cpp @@ -250,6 +250,7 @@ #include "../../docs/examples/Color_Type_RGB_101010.cpp" #include "../../docs/examples/Color_Type_RGB_565.cpp" #include "../../docs/examples/Color_Type_RGB_888.cpp" +#include "../../docs/examples/Color_Wheel.cpp" #include "../../docs/examples/Colors.cpp" #include "../../docs/examples/Conic_Weight_a.cpp" #include "../../docs/examples/Conic_Weight_b.cpp" @@ -520,6 +521,7 @@ #include "../../docs/examples/Modulate.cpp" #include "../../docs/examples/Multiply.cpp" #include "../../docs/examples/Octopus_Generator.cpp" +#include "../../docs/examples/Octopus_Generator_Animated.cpp" #include "../../docs/examples/Overlay.cpp" #include "../../docs/examples/PDF.cpp" #include "../../docs/examples/PaintDump.cpp" @@ -1012,6 +1014,7 @@ #include "../../docs/examples/Region_translate_2.cpp" #include "../../docs/examples/Region_writeToMemory.cpp" #include "../../docs/examples/SKIA_LOGO.cpp" +#include "../../docs/examples/SKIA_LOGO_ANIMATE.cpp" #include "../../docs/examples/SKIA_LOGO_svg.cpp" #include "../../docs/examples/Saturation.cpp" #include "../../docs/examples/Screen.cpp" @@ -1028,8 +1031,10 @@ #include "../../docs/examples/SkPath_arcto_conic_parametric2.cpp" #include "../../docs/examples/SkPath_cubicTo_example.cpp" #include "../../docs/examples/SkPath_cubicTo_example_parametric.cpp" +#include "../../docs/examples/SkPath_cubicTo_example_parametric_animated.cpp" #include "../../docs/examples/SkPath_quadTo_example.cpp" #include "../../docs/examples/SkPath_quadTo_example_parametric.cpp" +#include "../../docs/examples/SkPath_quadTo_example_parametric_animated.cpp" #include "../../docs/examples/SmoothBezierSplineInterpolation.cpp" #include "../../docs/examples/Soft_Light.cpp" #include "../../docs/examples/Src.cpp" @@ -1085,6 +1090,7 @@ #include "../../docs/examples/Text_Scale_X.cpp" #include "../../docs/examples/Text_Size.cpp" #include "../../docs/examples/Text_Skew_X.cpp" +#include "../../docs/examples/Turtle.cpp" #include "../../docs/examples/Typeface_Methods.cpp" #include "../../docs/examples/UnicornPoop.cpp" #include "../../docs/examples/UnpremulBugs.cpp" @@ -1146,6 +1152,7 @@ #include "../../docs/examples/inlinepixmapconstructor.cpp" #include "../../docs/examples/issue640176.cpp" #include "../../docs/examples/kLow_SkFilterQuality.cpp" +#include "../../docs/examples/l_system_plant.cpp" #include "../../docs/examples/maddash.cpp" #include "../../docs/examples/makeRasterImage_fail.cpp" #include "../../docs/examples/mapradius.cpp" @@ -1157,13 +1164,17 @@ #include "../../docs/examples/pathops.cpp" #include "../../docs/examples/persp_text_2.cpp" #include "../../docs/examples/picture_shader.cpp" +#include "../../docs/examples/pong.cpp" +#include "../../docs/examples/pong2.cpp" #include "../../docs/examples/purplestamp.cpp" +#include "../../docs/examples/radial_gradient_shader_with_animated_color.cpp" #include "../../docs/examples/radial_gradient_test.cpp" #include "../../docs/examples/redwhiteonblue.cpp" #include "../../docs/examples/rotations.cpp" #include "../../docs/examples/setimagefilter.cpp" #include "../../docs/examples/shader.cpp" #include "../../docs/examples/shader_alphaimage.cpp" +#include "../../docs/examples/shapes_with_motion.cpp" #include "../../docs/examples/skbug6031.cpp" #include "../../docs/examples/skbug_237_drawImageRect.cpp" #include "../../docs/examples/skbug_237_drawImage_with_blur.cpp" @@ -1172,6 +1183,7 @@ #include "../../docs/examples/skcanvas_paint.cpp" #include "../../docs/examples/skcanvas_square.cpp" #include "../../docs/examples/skcanvas_star.cpp" +#include "../../docs/examples/skew_x_animated.cpp" #include "../../docs/examples/skpaint_2pt.cpp" #include "../../docs/examples/skpaint_bitmap_shader.cpp" #include "../../docs/examples/skpaint_blur_mask_filter.cpp" @@ -1196,6 +1208,7 @@ #include "../../docs/examples/skpaint_sweep.cpp" #include "../../docs/examples/skpaint_turb.cpp" #include "../../docs/examples/skpaint_xfer.cpp" +#include "../../docs/examples/software_bitmap_w_perspective.cpp" #include "../../docs/examples/star.cpp" #include "../../docs/examples/star2.cpp" #include "../../docs/examples/stroke_closed_degenerate_path.cpp" diff --git a/tools/fiddle/examples.h b/tools/fiddle/examples.h index 8ecc328b02..304f01926d 100644 --- a/tools/fiddle/examples.h +++ b/tools/fiddle/examples.h @@ -16,10 +16,10 @@ struct Example { int fImageIndex; int fWidth; int fHeight; + double fAnimationDuration; bool fText; bool fSRGB; bool fF16; - bool fAnimation; bool fOffscreen; }; } @@ -32,10 +32,14 @@ extern sk_sp image; extern double duration; // The total duration of the animation in seconds. extern double frame; // A value in [0, 1] of where we are in the animation. -#define REG_FIDDLE(NAME, W, H, TEXT, I) \ +#define REG_FIDDLE_ANIMATED(NAME, W, H, TEXT, I, DURATION) \ namespace example_##NAME { void draw(SkCanvas*); } \ sk_tools::Registry reg_##NAME( \ - fiddle::Example{&example_##NAME::draw, #NAME, I, W, H, TEXT, false, false, false, false}); \ + fiddle::Example{&example_##NAME::draw, #NAME, I, W, H, DURATION, TEXT, \ + false, false, false}); \ namespace example_##NAME +#define REG_FIDDLE(NAME, W, H, TEXT, I) \ + REG_FIDDLE_ANIMATED(NAME, W, H, TEXT, I, 0) + #endif // examples_DEFINED