Flutter Engine
The Flutter Engine
AndroidShadowsSlide.cpp
Go to the documentation of this file.
1
2/*
3 * Copyright 2016 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
10#include "include/core/SkPath.h"
16#include "src/base/SkUTF.h"
17#include "src/core/SkBlurMask.h"
18#include "tools/ToolUtils.h"
20#include "tools/viewer/Slide.h"
21
22////////////////////////////////////////////////////////////////////////////
23
24class ShadowsSlide : public Slide {
25 SkPath fRectPath;
26 SkPath fRRPath;
27 SkPath fCirclePath;
28 SkPath fFunkyRRPath;
29 SkPath fCubicPath;
30 SkPath fStarPath;
31 SkPath fSquareRRectPath;
32 SkPath fWideRectPath;
33 SkPath fWideOvalPath;
34 SkPath fNotchPath;
35 SkPath fTabPath;
36
37 SkPoint3 fLightPos;
38 SkScalar fZDelta = 0;
39 SkScalar fAnimTranslate = 0;
40 SkScalar fAnimAngle = 0;
41 SkScalar fAnimAlpha = 1;
42
43 bool fShowAmbient = true;
44 bool fShowSpot = true;
45 bool fUseAlt = false;
46 bool fUseBlur = true;
47 bool fShowObject = true;
48 bool fIgnoreShadowAlpha = false;
49 bool fDoAlphaAnimation = false;
50
51public:
52 ShadowsSlide() { fName = "AndroidShadows"; }
53
54 void load(SkScalar w, SkScalar h) override {
55 fCirclePath.addCircle(0, 0, 50);
56 fRectPath.addRect(SkRect::MakeXYWH(-100, -50, 200, 100));
57 fRRPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-100, -50, 200, 100), 4, 4));
58 fFunkyRRPath.addRoundRect(SkRect::MakeXYWH(-50, -50, SK_Scalar1 * 100, SK_Scalar1 * 100),
59 40 * SK_Scalar1, 20 * SK_Scalar1,
61 fCubicPath.cubicTo(100 * SK_Scalar1, 50 * SK_Scalar1,
62 20 * SK_Scalar1, 100 * SK_Scalar1,
63 0 * SK_Scalar1, 0 * SK_Scalar1);
64 fStarPath.moveTo(0.0f, -50.0f);
65 fStarPath.lineTo(14.43f, -25.0f);
66 fStarPath.lineTo(43.30f, -25.0f);
67 fStarPath.lineTo(28.86f, 0.0f);
68 fStarPath.lineTo(43.30f, 25.0f);
69 fStarPath.lineTo(14.43f, 25.0f);
70 fStarPath.lineTo(0.0f, 50.0f);
71 fStarPath.lineTo(-14.43f, 25.0f);
72 fStarPath.lineTo(-43.30f, 25.0f);
73 fStarPath.lineTo(-28.86f, 0.0f);
74 fStarPath.lineTo(-43.30f, -25.0f);
75 fStarPath.lineTo(-14.43f, -25.0f);
76 fSquareRRectPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-50, -50, 100, 100),
77 10, 10));
78 fWideRectPath.addRect(SkRect::MakeXYWH(0, 0, 630, 70));
79 fWideOvalPath.addOval(SkRect::MakeXYWH(0, 0, 630, 70));
80
81 fNotchPath.moveTo(0, 80);
82 fNotchPath.arcTo(SkRect::MakeLTRB(-20, 80, 20, 120), -90, -90, false);
83 fNotchPath.lineTo(-75, 100);
84 fNotchPath.lineTo(-75, -100);
85 fNotchPath.lineTo(75, -100);
86 fNotchPath.lineTo(75, 100);
87 fNotchPath.arcTo(SkRect::MakeLTRB(-20, 80, 20, 120), 0, -90, false);
88
89 fTabPath.moveTo(-75, -100);
90 fTabPath.lineTo(75, -100);
91 fTabPath.lineTo(75, 100);
92 fTabPath.arcTo(SkRect::MakeLTRB(-20, 80, 20, 120), 0, 90, false);
93 fTabPath.arcTo(SkRect::MakeLTRB(-20, 80, 20, 120), 90, 90, false);
94 fTabPath.lineTo(-75, 100);
95
96 fLightPos = SkPoint3::Make(350, 0, 600);
97 }
98
99 bool onChar(SkUnichar uni) override {
100 bool handled = false;
101 switch (uni) {
102 case 'W':
103 fShowAmbient = !fShowAmbient;
104 handled = true;
105 break;
106 case 'S':
107 fShowSpot = !fShowSpot;
108 handled = true;
109 break;
110 case 'T':
111 fUseAlt = !fUseAlt;
112 handled = true;
113 break;
114 case 'B':
115 fUseBlur = !fUseBlur;
116 handled = true;
117 break;
118 case 'O':
119 fShowObject = !fShowObject;
120 handled = true;
121 break;
122 case 'N':
123 fDoAlphaAnimation = !fDoAlphaAnimation;
124 if (!fDoAlphaAnimation) {
125 fAnimAlpha = 1;
126 }
127 handled = true;
128 break;
129 case '>':
130 fZDelta += 0.5f;
131 handled = true;
132 break;
133 case '<':
134 fZDelta -= 0.5f;
135 handled = true;
136 break;
137 case '?':
138 fIgnoreShadowAlpha = !fIgnoreShadowAlpha;
139 handled = true;
140 break;
141 default:
142 break;
143 }
144 if (handled) {
145 return true;
146 }
147 return false;
148 }
149
150
151 bool animate(double nanos) override {
152 fAnimTranslate = TimeUtils::PingPong(1e-9 * nanos, 30, 0, 125, -125);
153 fAnimAngle = TimeUtils::PingPong(1e-9 * nanos, 15, 0, 0, 20);
154 if (fDoAlphaAnimation) {
155 fAnimAlpha = TimeUtils::PingPong(1e-9 * nanos, 5, 0, 1, 0);
156 }
157 return true;
158 }
159
160 void draw(SkCanvas* canvas) override {
161 canvas->drawColor(0xFFDDDDDD);
162
163 const SkScalar kLightWidth = 800;
164 const SkScalar kAmbientAlpha = 0.039f;
165 const SkScalar kSpotAlpha = 0.19f;
166
168 paint.setAntiAlias(true);
169
170 SkPoint3 lightPos = fLightPos;
171 SkPoint3 zPlaneParams = SkPoint3::Make(0, 0, 0);
172
173 paint.setColor(SK_ColorWHITE);
174 canvas->translate(200, 90);
175 zPlaneParams.fZ = std::max(1.0f, 2 + fZDelta);
176 this->drawShadowedPath(canvas, fRRPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
177 lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
178
179 paint.setColor(SK_ColorRED);
180 canvas->translate(250, 0);
181 zPlaneParams.fZ = std::max(1.0f, 8 + fZDelta);
182 this->drawShadowedPath(canvas, fRectPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
183 lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
184
185 paint.setColor(SK_ColorBLUE);
186 canvas->translate(-250, 110);
187 zPlaneParams.fZ = std::max(1.0f, 12 + fZDelta);
188 this->drawShadowedPath(canvas, fCirclePath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
189 lightPos, kLightWidth, fAnimAlpha*0.5f);
190
191 paint.setColor(SK_ColorGREEN);
192 canvas->translate(250, 0);
193 zPlaneParams.fZ = std::max(1.0f, 64 + fZDelta);
194 this->drawShadowedPath(canvas, fRRPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
195 lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
196
197 paint.setColor(SK_ColorYELLOW);
198 canvas->translate(-250, 110);
199 zPlaneParams.fZ = std::max(1.0f, 8 + fZDelta);
200 this->drawShadowedPath(canvas, fFunkyRRPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
201 lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
202
203 paint.setColor(SK_ColorCYAN);
204 canvas->translate(250, 0);
205 zPlaneParams.fZ = std::max(1.0f, 16 + fZDelta);
206 this->drawShadowedPath(canvas, fCubicPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
207 lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
208
209 paint.setColor(SK_ColorWHITE);
210 canvas->translate(250, -180);
211 zPlaneParams.fZ = std::max(1.0f, 8 + fZDelta);
212 this->drawShadowedPath(canvas, fStarPath, zPlaneParams, paint,
213 kAmbientAlpha, lightPos, kLightWidth, kSpotAlpha);
214
215 paint.setColor(SK_ColorWHITE);
216 canvas->translate(150, 0);
217 zPlaneParams.fZ = std::max(1.0f, 2 + fZDelta);
218 this->drawShadowedPath(canvas, fNotchPath, zPlaneParams, paint,
219 kAmbientAlpha, lightPos, kLightWidth, kSpotAlpha);
220
221 paint.setColor(SK_ColorWHITE);
222 canvas->translate(200, 0);
223 zPlaneParams.fZ = std::max(1.0f, 16 + fZDelta);
224 this->drawShadowedPath(canvas, fTabPath, zPlaneParams, paint,
225 kAmbientAlpha, lightPos, kLightWidth, kSpotAlpha);
226
227 // circular reveal
228 SkPath tmpPath;
229 SkPath tmpClipPath;
230 tmpClipPath.addCircle(fAnimTranslate, 0, 60);
231 Op(fSquareRRectPath, tmpClipPath, kIntersect_SkPathOp, &tmpPath);
232
233 paint.setColor(SK_ColorMAGENTA);
234 canvas->translate(-725, 240);
235 zPlaneParams.fZ = std::max(1.0f, 32 + fZDelta);
236 this->drawShadowedPath(canvas, tmpPath, zPlaneParams, paint, .1f,
237 lightPos, kLightWidth, .5f);
238
239 // path ops bug
240 SkPath tmpClipPathBug;
241 tmpClipPathBug.addCircle(88.0344925f, 0, 60);
242 Op(fSquareRRectPath, tmpClipPathBug, kIntersect_SkPathOp, &tmpPath);
243
244 canvas->translate(250, 0);
245 zPlaneParams.fZ = std::max(1.0f, 32 + fZDelta);
246 this->drawShadowedPath(canvas, tmpPath, zPlaneParams, paint, .1f,
247 lightPos, kLightWidth, .5f);
248
249 // perspective paths
250 SkPoint pivot = SkPoint::Make(fWideRectPath.getBounds().width()/2,
251 fWideRectPath.getBounds().height()/2);
252 SkPoint translate = SkPoint::Make(100, 450);
253 paint.setColor(SK_ColorWHITE);
254 Sk3DView view;
255 view.save();
256 view.rotateX(fAnimAngle);
257 SkMatrix persp;
258 view.getMatrix(&persp);
259 persp.preTranslate(-pivot.fX, -pivot.fY);
260 persp.postTranslate(pivot.fX + translate.fX, pivot.fY + translate.fY);
261 canvas->setMatrix(persp);
262 SkScalar radians = SkDegreesToRadians(fAnimAngle);
263 zPlaneParams = SkPoint3::Make(0,
264 SkScalarSin(radians),
265 std::max(1.0f, 16 + fZDelta) - SkScalarSin(radians)*pivot.fY);
266 this->drawShadowedPath(canvas, fWideRectPath, zPlaneParams, paint, .1f,
267 lightPos, kLightWidth, .5f);
268
269 pivot = SkPoint::Make(fWideOvalPath.getBounds().width() / 2,
270 fWideOvalPath.getBounds().height() / 2);
271 translate = SkPoint::Make(100, 600);
272 view.restore();
273 view.save();
274 view.rotateY(fAnimAngle);
275 view.getMatrix(&persp);
276 persp.preTranslate(-pivot.fX, -pivot.fY);
277 persp.postTranslate(pivot.fX + translate.fX, pivot.fY + translate.fY);
278 canvas->setMatrix(persp);
279 zPlaneParams = SkPoint3::Make(-SkScalarSin(radians),
280 0,
281 std::max(1.0f, 32 + fZDelta) + SkScalarSin(radians)*pivot.fX);
282 this->drawShadowedPath(canvas, fWideOvalPath, zPlaneParams, paint, .1f,
283 lightPos, kLightWidth, .5f);
284
285 pivot = SkPoint::Make(fStarPath.getBounds().width() / 2,
286 fStarPath.getBounds().height() / 2);
287 translate = SkPoint::Make(700, 250);
288 view.restore();
289 view.rotateY(fAnimAngle);
290 view.getMatrix(&persp);
291 persp.preTranslate(-pivot.fX, -pivot.fY);
292 persp.postTranslate(pivot.fX + translate.fX, pivot.fY + translate.fY);
293 canvas->setMatrix(persp);
294 zPlaneParams = SkPoint3::Make(-SkScalarSin(radians),
295 0,
296 std::max(1.0f, 8 + fZDelta) + SkScalarSin(radians)*pivot.fX);
297 this->drawShadowedPath(canvas, fStarPath, zPlaneParams, paint, .1f,
298 lightPos, kLightWidth, .5f);
299 }
300
301private:
302 void drawShadowedPath(SkCanvas* canvas, const SkPath& path,
303 const SkPoint3& zPlaneParams,
304 const SkPaint& paint, SkScalar ambientAlpha,
305 const SkPoint3& lightPos, SkScalar lightWidth, SkScalar spotAlpha) {
306 if (fIgnoreShadowAlpha) {
307 ambientAlpha = 1;
308 spotAlpha = 1;
309 }
310 if (!fShowAmbient) {
311 ambientAlpha = 0;
312 }
313 if (!fShowSpot) {
314 spotAlpha = 0;
315 }
316 uint32_t flags = 0;
317 if (fUseAlt) {
319 }
320 if (fUseBlur) {
322 }
323
324 SkColor ambientColor = SkColorSetARGB(ambientAlpha * 255, 0, 0, 0);
325 SkColor spotColor = SkColorSetARGB(spotAlpha * 255, 0, 0, 0);
326 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams, lightPos, lightWidth,
327 ambientColor, spotColor, flags);
328
329 if (fShowObject) {
330 canvas->drawPath(path, paint);
331 } else {
332 SkPaint strokePaint;
333
334 strokePaint.setColor(paint.getColor());
335 strokePaint.setStyle(SkPaint::kStroke_Style);
336
337 canvas->drawPath(path, strokePaint);
338 }
339 }
340};
341
342//////////////////////////////////////////////////////////////////////////////
343
344DEF_SLIDE( return new ShadowsSlide(); )
constexpr SkColor SK_ColorYELLOW
Definition: SkColor.h:139
constexpr SkColor SK_ColorMAGENTA
Definition: SkColor.h:147
uint32_t SkColor
Definition: SkColor.h:37
constexpr SkColor SK_ColorCYAN
Definition: SkColor.h:143
constexpr SkColor SK_ColorBLUE
Definition: SkColor.h:135
constexpr SkColor SK_ColorRED
Definition: SkColor.h:126
static constexpr SkColor SkColorSetARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
Definition: SkColor.h:49
constexpr SkColor SK_ColorGREEN
Definition: SkColor.h:131
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
@ kIntersect_SkPathOp
intersect the two paths
Definition: SkPathOps.h:24
#define SkDegreesToRadians(degrees)
Definition: SkScalar.h:77
#define SkScalarSin(radians)
Definition: SkScalar.h:45
#define SK_Scalar1
Definition: SkScalar.h:18
@ kConcaveBlurOnly_ShadowFlag
Definition: SkShadowUtils.h:33
@ kGeometricOnly_ShadowFlag
Definition: SkShadowUtils.h:29
int32_t SkUnichar
Definition: SkTypes.h:175
#define DEF_SLIDE(code)
Definition: Slide.h:25
void load(SkScalar w, SkScalar h) override
bool onChar(SkUnichar uni) override
bool animate(double nanos) override
void draw(SkCanvas *canvas) override
void getMatrix(SkMatrix *) const
Definition: SkCamera.cpp:224
void restore()
Definition: SkCamera.cpp:172
void rotateX(SkScalar deg)
Definition: SkCamera.cpp:206
void save()
Definition: SkCamera.cpp:165
void rotateY(SkScalar deg)
Definition: SkCamera.cpp:210
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
void drawColor(SkColor color, SkBlendMode mode=SkBlendMode::kSrcOver)
Definition: SkCanvas.h:1182
void drawPath(const SkPath &path, const SkPaint &paint)
Definition: SkCanvas.cpp:1747
void setMatrix(const SkM44 &matrix)
Definition: SkCanvas.cpp:1349
SkMatrix & postTranslate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.cpp:281
SkMatrix & preTranslate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.cpp:263
void setStyle(Style style)
Definition: SkPaint.cpp:105
void setColor(SkColor color)
Definition: SkPaint.cpp:119
@ kStroke_Style
set to stroke geometry
Definition: SkPaint.h:194
Definition: SkPath.h:59
SkPath & addCircle(SkScalar x, SkScalar y, SkScalar radius, SkPathDirection dir=SkPathDirection::kCW)
Definition: SkPath.cpp:1213
SkPath & arcTo(const SkRect &oval, SkScalar startAngle, SkScalar sweepAngle, bool forceMoveTo)
Definition: SkPath.cpp:1220
SkPath & moveTo(SkScalar x, SkScalar y)
Definition: SkPath.cpp:688
SkPath & lineTo(SkScalar x, SkScalar y)
Definition: SkPath.cpp:728
SkPath & addRRect(const SkRRect &rrect, SkPathDirection dir=SkPathDirection::kCW)
Definition: SkPath.cpp:1000
SkPath & addRoundRect(const SkRect &rect, SkScalar rx, SkScalar ry, SkPathDirection dir=SkPathDirection::kCW)
Definition: SkPath.cpp:1093
const SkRect & getBounds() const
Definition: SkPath.cpp:430
SkPath & addOval(const SkRect &oval, SkPathDirection dir=SkPathDirection::kCW)
Definition: SkPath.cpp:1106
SkPath & cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar x3, SkScalar y3)
Definition: SkPath.cpp:799
SkPath & addRect(const SkRect &rect, SkPathDirection dir, unsigned start)
Definition: SkPath.cpp:864
static SkRRect MakeRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
Definition: SkRRect.h:180
static void DrawShadow(SkCanvas *canvas, const SkPath &path, const SkPoint3 &zPlaneParams, const SkPoint3 &lightPos, SkScalar lightRadius, SkColor ambientColor, SkColor spotColor, uint32_t flags=SkShadowFlags::kNone_ShadowFlag)
Definition: Slide.h:29
SkString fName
Definition: Slide.h:54
const Paint & paint
Definition: color_source.cc:38
float SkScalar
Definition: extension.cpp:12
FlutterSemanticsFlag flags
static float max(float r, float g, float b)
Definition: hsl.cpp:49
static float PingPong(double time, float period, float phase, float ends, float mid)
Definition: TimeUtils.h:37
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
SkScalar w
SkScalar h
static SkPoint3 Make(SkScalar x, SkScalar y, SkScalar z)
Definition: SkPoint3.h:18
SkScalar fZ
Definition: SkPoint3.h:16
float fX
x-axis value
Definition: SkPoint_impl.h:164
static constexpr SkPoint Make(float x, float y)
Definition: SkPoint_impl.h:173
float fY
y-axis value
Definition: SkPoint_impl.h:165
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659
constexpr float height() const
Definition: SkRect.h:769
constexpr float width() const
Definition: SkRect.h:762
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
Definition: SkRect.h:646