blob: 5d4cd26956bedcbe809cc49366e8ab09ac8f40be [file] [log] [blame]
jvanverthe1a3bc62016-08-12 10:40:38 -07001
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 */
8#include "SampleCode.h"
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -05009#include "SkAnimTimer.h"
jvanverthe1a3bc62016-08-12 10:40:38 -070010#include "SkBlurMask.h"
11#include "SkBlurMaskFilter.h"
Jim Van Verth2aa535e2017-02-06 14:36:01 -050012#include "SkColorFilter.h"
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -050013#include "SkCamera.h"
jvanverthe1a3bc62016-08-12 10:40:38 -070014#include "SkCanvas.h"
15#include "SkPath.h"
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -050016#include "SkPathOps.h"
jvanverthe1a3bc62016-08-12 10:40:38 -070017#include "SkPoint3.h"
Jim Van Verth43475ad2017-01-13 14:37:37 -050018#include "SkShadowUtils.h"
jvanverthe1a3bc62016-08-12 10:40:38 -070019#include "SkUtils.h"
20#include "SkView.h"
21#include "sk_tool_utils.h"
22
jvanverth6c177a12016-08-17 07:59:41 -070023////////////////////////////////////////////////////////////////////////////
24
jvanverthe1a3bc62016-08-12 10:40:38 -070025class ShadowsView : public SampleView {
26 SkPath fRectPath;
27 SkPath fRRPath;
28 SkPath fCirclePath;
Jim Van Verthbce74962017-01-25 09:39:46 -050029 SkPath fFunkyRRPath;
30 SkPath fCubicPath;
Jim Van Verth872da6b2018-04-10 11:24:11 -040031 SkPath fStarPath;
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -050032 SkPath fSquareRRectPath;
33 SkPath fWideRectPath;
34 SkPath fWideOvalPath;
Jim Van Verth872da6b2018-04-10 11:24:11 -040035 SkPath fNotchPath;
36 SkPath fTabPath;
37
jvanverthe1a3bc62016-08-12 10:40:38 -070038 SkPoint3 fLightPos;
Jim Van Verth2aa535e2017-02-06 14:36:01 -050039 SkScalar fZDelta;
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -050040 SkScalar fAnimTranslate;
Jim Van Verthda965502017-04-11 15:29:14 -040041 SkScalar fAnimAngle;
Jim Van Verth744cbb32017-12-19 13:02:38 -050042 SkScalar fAnimAlpha;
jvanverthe1a3bc62016-08-12 10:40:38 -070043
44 bool fShowAmbient;
45 bool fShowSpot;
jvanverthd7315f912016-08-17 10:06:18 -070046 bool fUseAlt;
jvanverthe1a3bc62016-08-12 10:40:38 -070047 bool fShowObject;
Robert Phillips95304e32016-10-07 14:44:07 -040048 bool fIgnoreShadowAlpha;
Jim Van Verth744cbb32017-12-19 13:02:38 -050049 bool fDoAlphaAnimation;
jvanverthe1a3bc62016-08-12 10:40:38 -070050
51public:
Jim Van Verth2aa535e2017-02-06 14:36:01 -050052 ShadowsView()
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -050053 : fZDelta(0)
54 , fAnimTranslate(0)
Jim Van Verthda965502017-04-11 15:29:14 -040055 , fAnimAngle(0)
Jim Van Verth744cbb32017-12-19 13:02:38 -050056 , fAnimAlpha(1)
Jim Van Verth2aa535e2017-02-06 14:36:01 -050057 , fShowAmbient(true)
jvanverthe1a3bc62016-08-12 10:40:38 -070058 , fShowSpot(true)
Jim Van Verthb6069df2017-04-28 11:00:35 -040059 , fUseAlt(false)
Robert Phillips95304e32016-10-07 14:44:07 -040060 , fShowObject(true)
Jim Van Verth744cbb32017-12-19 13:02:38 -050061 , fIgnoreShadowAlpha(false)
62 , fDoAlphaAnimation(false) {}
jvanverthe1a3bc62016-08-12 10:40:38 -070063
64protected:
65 void onOnceBeforeDraw() override {
66 fCirclePath.addCircle(0, 0, 50);
67 fRectPath.addRect(SkRect::MakeXYWH(-100, -50, 200, 100));
68 fRRPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-100, -50, 200, 100), 4, 4));
Jim Van Verthbce74962017-01-25 09:39:46 -050069 fFunkyRRPath.addRoundRect(SkRect::MakeXYWH(-50, -50, SK_Scalar1 * 100, SK_Scalar1 * 100),
70 40 * SK_Scalar1, 20 * SK_Scalar1,
71 SkPath::kCW_Direction);
72 fCubicPath.cubicTo(100 * SK_Scalar1, 50 * SK_Scalar1,
73 20 * SK_Scalar1, 100 * SK_Scalar1,
74 0 * SK_Scalar1, 0 * SK_Scalar1);
Jim Van Verth872da6b2018-04-10 11:24:11 -040075 fStarPath.moveTo(0.0f, -50.0f);
76 fStarPath.lineTo(14.43f, -25.0f);
77 fStarPath.lineTo(43.30f, -25.0f);
78 fStarPath.lineTo(28.86f, 0.0f);
79 fStarPath.lineTo(43.30f, 25.0f);
80 fStarPath.lineTo(14.43f, 25.0f);
81 fStarPath.lineTo(0.0f, 50.0f);
82 fStarPath.lineTo(-14.43f, 25.0f);
83 fStarPath.lineTo(-43.30f, 25.0f);
84 fStarPath.lineTo(-28.86f, 0.0f);
85 fStarPath.lineTo(-43.30f, -25.0f);
86 fStarPath.lineTo(-14.43f, -25.0f);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -050087 fSquareRRectPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-50, -50, 100, 100),
88 10, 10));
89 fWideRectPath.addRect(SkRect::MakeXYWH(0, 0, 630, 70));
90 fWideOvalPath.addOval(SkRect::MakeXYWH(0, 0, 630, 70));
Jim Van Verthbce74962017-01-25 09:39:46 -050091
Jim Van Verth872da6b2018-04-10 11:24:11 -040092 fNotchPath.moveTo(0, 80);
93 fNotchPath.arcTo(SkRect::MakeLTRB(-20, 80, 20, 120), -90, -90, false);
94 fNotchPath.lineTo(-75, 100);
95 fNotchPath.lineTo(-75, -100);
96 fNotchPath.lineTo(75, -100);
97 fNotchPath.lineTo(75, 100);
98 fNotchPath.arcTo(SkRect::MakeLTRB(-20, 80, 20, 120), 0, -90, false);
99
100 fTabPath.moveTo(-75, -100);
101 fTabPath.lineTo(75, -100);
102 fTabPath.lineTo(75, 100);
103 fTabPath.arcTo(SkRect::MakeLTRB(-20, 80, 20, 120), 0, 90, false);
104 fTabPath.arcTo(SkRect::MakeLTRB(-20, 80, 20, 120), 90, 90, false);
105 fTabPath.lineTo(-75, 100);
106
Jim Van Verthb6069df2017-04-28 11:00:35 -0400107 fLightPos = SkPoint3::Make(350, 0, 600);
jvanverthe1a3bc62016-08-12 10:40:38 -0700108 }
109
110 // overrides from SkEventSink
111 bool onQuery(SkEvent* evt) override {
112 if (SampleCode::TitleQ(*evt)) {
113 SampleCode::TitleR(evt, "AndroidShadows");
114 return true;
115 }
116
117 SkUnichar uni;
118 if (SampleCode::CharQ(*evt, &uni)) {
Jim Van Verth6f449692017-02-14 15:16:46 -0500119 bool handled = false;
jvanverthe1a3bc62016-08-12 10:40:38 -0700120 switch (uni) {
Jim Van Verth2aa535e2017-02-06 14:36:01 -0500121 case 'W':
jvanverthe1a3bc62016-08-12 10:40:38 -0700122 fShowAmbient = !fShowAmbient;
Jim Van Verth6f449692017-02-14 15:16:46 -0500123 handled = true;
jvanverthe1a3bc62016-08-12 10:40:38 -0700124 break;
125 case 'S':
126 fShowSpot = !fShowSpot;
Jim Van Verth6f449692017-02-14 15:16:46 -0500127 handled = true;
jvanverthe1a3bc62016-08-12 10:40:38 -0700128 break;
jvanverthd7315f912016-08-17 10:06:18 -0700129 case 'T':
130 fUseAlt = !fUseAlt;
Jim Van Verth6f449692017-02-14 15:16:46 -0500131 handled = true;
jvanverthd7315f912016-08-17 10:06:18 -0700132 break;
jvanverthe1a3bc62016-08-12 10:40:38 -0700133 case 'O':
134 fShowObject = !fShowObject;
Jim Van Verth6f449692017-02-14 15:16:46 -0500135 handled = true;
jvanverthe1a3bc62016-08-12 10:40:38 -0700136 break;
Jim Van Verth744cbb32017-12-19 13:02:38 -0500137 case 'N':
138 fDoAlphaAnimation = !fDoAlphaAnimation;
139 if (!fDoAlphaAnimation) {
140 fAnimAlpha = 1;
141 }
142 handled = true;
143 break;
jvanverthe1a3bc62016-08-12 10:40:38 -0700144 case '>':
Jim Van Verth2aa535e2017-02-06 14:36:01 -0500145 fZDelta += 0.5f;
Jim Van Verth6f449692017-02-14 15:16:46 -0500146 handled = true;
jvanverthe1a3bc62016-08-12 10:40:38 -0700147 break;
148 case '<':
Jim Van Verth2aa535e2017-02-06 14:36:01 -0500149 fZDelta -= 0.5f;
Jim Van Verth6f449692017-02-14 15:16:46 -0500150 handled = true;
jvanverthe1a3bc62016-08-12 10:40:38 -0700151 break;
Robert Phillips95304e32016-10-07 14:44:07 -0400152 case '?':
153 fIgnoreShadowAlpha = !fIgnoreShadowAlpha;
Jim Van Verth6f449692017-02-14 15:16:46 -0500154 handled = true;
Robert Phillips95304e32016-10-07 14:44:07 -0400155 break;
jvanverthe1a3bc62016-08-12 10:40:38 -0700156 default:
157 break;
158 }
Jim Van Verth6f449692017-02-14 15:16:46 -0500159 if (handled) {
Jim Van Verth6f449692017-02-14 15:16:46 -0500160 return true;
161 }
jvanverthe1a3bc62016-08-12 10:40:38 -0700162 }
163 return this->INHERITED::onQuery(evt);
164 }
165
166 void drawBG(SkCanvas* canvas) {
167 canvas->drawColor(0xFFDDDDDD);
168 }
169
Jim Van Verthda965502017-04-11 15:29:14 -0400170 void drawShadowedPath(SkCanvas* canvas, const SkPath& path,
Jim Van Verthe308a122017-05-08 14:19:30 -0400171 const SkPoint3& zPlaneParams,
jvanverthd7315f912016-08-17 10:06:18 -0700172 const SkPaint& paint, SkScalar ambientAlpha,
173 const SkPoint3& lightPos, SkScalar lightWidth, SkScalar spotAlpha) {
Jim Van Verthe7705782017-05-04 14:00:59 -0400174 if (fIgnoreShadowAlpha) {
Jim Van Verth872da6b2018-04-10 11:24:11 -0400175 ambientAlpha = 1;
176 spotAlpha = 1;
Jim Van Verthe7705782017-05-04 14:00:59 -0400177 }
Jim Van Verth060d9822017-05-04 09:58:17 -0400178 if (!fShowAmbient) {
179 ambientAlpha = 0;
180 }
181 if (!fShowSpot) {
182 spotAlpha = 0;
183 }
184 uint32_t flags = 0;
Jim Van Verth3c1b7db2016-10-31 16:06:51 -0400185 if (fUseAlt) {
Jim Van Verth060d9822017-05-04 09:58:17 -0400186 flags |= SkShadowFlags::kGeometricOnly_ShadowFlag;
Jim Van Verth3c1b7db2016-10-31 16:06:51 -0400187 }
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400188
Jim Van Vertha5566842018-02-22 10:58:34 -0500189 SkColor ambientColor = SkColorSetARGB(ambientAlpha * 255, 0, 0, 0);
190 SkColor spotColor = SkColorSetARGB(spotAlpha * 255, 0, 0, 0);
191 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams, lightPos, lightWidth,
192 ambientColor, spotColor, flags);
Jim Van Verth3c1b7db2016-10-31 16:06:51 -0400193
jvanverthe1a3bc62016-08-12 10:40:38 -0700194 if (fShowObject) {
195 canvas->drawPath(path, paint);
Robert Phillips95304e32016-10-07 14:44:07 -0400196 } else {
197 SkPaint strokePaint;
198
199 strokePaint.setColor(paint.getColor());
200 strokePaint.setStyle(SkPaint::kStroke_Style);
201
202 canvas->drawPath(path, strokePaint);
jvanverthe1a3bc62016-08-12 10:40:38 -0700203 }
204 }
205
206 void onDrawContent(SkCanvas* canvas) override {
207 this->drawBG(canvas);
Jim Van Verthb6069df2017-04-28 11:00:35 -0400208 const SkScalar kLightWidth = 800;
209 const SkScalar kAmbientAlpha = 0.1f;
jvanverthd7315f912016-08-17 10:06:18 -0700210 const SkScalar kSpotAlpha = 0.25f;
jvanverthe1a3bc62016-08-12 10:40:38 -0700211
212 SkPaint paint;
213 paint.setAntiAlias(true);
214
jvanverthd7315f912016-08-17 10:06:18 -0700215 SkPoint3 lightPos = fLightPos;
Jim Van Verthe308a122017-05-08 14:19:30 -0400216 SkPoint3 zPlaneParams = SkPoint3::Make(0, 0, 0);
jvanverthd7315f912016-08-17 10:06:18 -0700217
jvanverthe1a3bc62016-08-12 10:40:38 -0700218 paint.setColor(SK_ColorWHITE);
219 canvas->translate(200, 90);
Jim Van Verthe308a122017-05-08 14:19:30 -0400220 zPlaneParams.fZ = SkTMax(1.0f, 2 + fZDelta);
Jim Van Verth744cbb32017-12-19 13:02:38 -0500221 this->drawShadowedPath(canvas, fRRPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
222 lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
jvanverthe1a3bc62016-08-12 10:40:38 -0700223
224 paint.setColor(SK_ColorRED);
225 canvas->translate(250, 0);
Jim Van Verthe308a122017-05-08 14:19:30 -0400226 zPlaneParams.fZ = SkTMax(1.0f, 8 + fZDelta);
Jim Van Verth744cbb32017-12-19 13:02:38 -0500227 this->drawShadowedPath(canvas, fRectPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
228 lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
jvanverthe1a3bc62016-08-12 10:40:38 -0700229
230 paint.setColor(SK_ColorBLUE);
231 canvas->translate(-250, 110);
Jim Van Verthe308a122017-05-08 14:19:30 -0400232 zPlaneParams.fZ = SkTMax(1.0f, 12 + fZDelta);
Jim Van Verth744cbb32017-12-19 13:02:38 -0500233 this->drawShadowedPath(canvas, fCirclePath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
234 lightPos, kLightWidth, fAnimAlpha*0.5f);
jvanverth6c177a12016-08-17 07:59:41 -0700235
236 paint.setColor(SK_ColorGREEN);
237 canvas->translate(250, 0);
Jim Van Verthe308a122017-05-08 14:19:30 -0400238 zPlaneParams.fZ = SkTMax(1.0f, 64 + fZDelta);
Jim Van Verth744cbb32017-12-19 13:02:38 -0500239 this->drawShadowedPath(canvas, fRRPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
240 lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
Jim Van Verthbce74962017-01-25 09:39:46 -0500241
242 paint.setColor(SK_ColorYELLOW);
243 canvas->translate(-250, 110);
Jim Van Verthe308a122017-05-08 14:19:30 -0400244 zPlaneParams.fZ = SkTMax(1.0f, 8 + fZDelta);
Jim Van Verth744cbb32017-12-19 13:02:38 -0500245 this->drawShadowedPath(canvas, fFunkyRRPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
246 lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
Jim Van Verthbce74962017-01-25 09:39:46 -0500247
248 paint.setColor(SK_ColorCYAN);
249 canvas->translate(250, 0);
Jim Van Verthe308a122017-05-08 14:19:30 -0400250 zPlaneParams.fZ = SkTMax(1.0f, 16 + fZDelta);
Jim Van Verth744cbb32017-12-19 13:02:38 -0500251 this->drawShadowedPath(canvas, fCubicPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
252 lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500253
Jim Van Verth872da6b2018-04-10 11:24:11 -0400254 paint.setColor(SK_ColorWHITE);
255 canvas->translate(250, -180);
256 zPlaneParams.fZ = SkTMax(1.0f, 8 + fZDelta);
257 this->drawShadowedPath(canvas, fStarPath, zPlaneParams, paint,
258 kAmbientAlpha, lightPos, kLightWidth, kSpotAlpha);
259
260 paint.setColor(SK_ColorWHITE);
261 canvas->translate(150, 0);
262 zPlaneParams.fZ = SkTMax(1.0f, 2 + fZDelta);
263 this->drawShadowedPath(canvas, fNotchPath, zPlaneParams, paint,
264 kAmbientAlpha, lightPos, kLightWidth, kSpotAlpha);
265
266 paint.setColor(SK_ColorWHITE);
267 canvas->translate(200, 0);
268 zPlaneParams.fZ = SkTMax(1.0f, 16 + fZDelta);
269 this->drawShadowedPath(canvas, fTabPath, zPlaneParams, paint,
270 kAmbientAlpha, lightPos, kLightWidth, kSpotAlpha);
271
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500272 // circular reveal
273 SkPath tmpPath;
274 SkPath tmpClipPath;
275 tmpClipPath.addCircle(fAnimTranslate, 0, 60);
276 Op(fSquareRRectPath, tmpClipPath, kIntersect_SkPathOp, &tmpPath);
277
278 paint.setColor(SK_ColorMAGENTA);
Jim Van Verth872da6b2018-04-10 11:24:11 -0400279 canvas->translate(-725, 240);
Jim Van Verthe308a122017-05-08 14:19:30 -0400280 zPlaneParams.fZ = SkTMax(1.0f, 32 + fZDelta);
281 this->drawShadowedPath(canvas, tmpPath, zPlaneParams, paint, .1f,
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500282 lightPos, kLightWidth, .5f);
283
284 // perspective paths
285 SkPoint pivot = SkPoint::Make(fWideRectPath.getBounds().width()/2,
286 fWideRectPath.getBounds().height()/2);
Jim Van Verthda965502017-04-11 15:29:14 -0400287 SkPoint translate = SkPoint::Make(100, 450);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500288 paint.setColor(SK_ColorWHITE);
289 Sk3DView view;
290 view.save();
Jim Van Verthda965502017-04-11 15:29:14 -0400291 view.rotateX(fAnimAngle);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500292 SkMatrix persp;
293 view.getMatrix(&persp);
294 persp.preTranslate(-pivot.fX, -pivot.fY);
295 persp.postTranslate(pivot.fX + translate.fX, pivot.fY + translate.fY);
296 canvas->setMatrix(persp);
Jim Van Verthda965502017-04-11 15:29:14 -0400297 SkScalar radians = SkDegreesToRadians(fAnimAngle);
Jim Van Verthe308a122017-05-08 14:19:30 -0400298 zPlaneParams = SkPoint3::Make(0,
299 SkScalarSin(-radians),
300 SkTMax(1.0f, 16 + fZDelta) - SkScalarSin(-radians)*pivot.fY);
301 this->drawShadowedPath(canvas, fWideRectPath, zPlaneParams, paint, .1f,
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500302 lightPos, kLightWidth, .5f);
303
304 pivot = SkPoint::Make(fWideOvalPath.getBounds().width() / 2,
305 fWideOvalPath.getBounds().height() / 2);
Jim Van Verthda965502017-04-11 15:29:14 -0400306 translate = SkPoint::Make(100, 600);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500307 view.restore();
Jim Van Verthda965502017-04-11 15:29:14 -0400308 view.rotateY(fAnimAngle);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500309 view.getMatrix(&persp);
310 persp.preTranslate(-pivot.fX, -pivot.fY);
311 persp.postTranslate(pivot.fX + translate.fX, pivot.fY + translate.fY);
312 canvas->setMatrix(persp);
Jim Van Verthe308a122017-05-08 14:19:30 -0400313 zPlaneParams = SkPoint3::Make(-SkScalarSin(radians),
314 0,
315 SkTMax(1.0f, 32 + fZDelta) + SkScalarSin(radians)*pivot.fX);
316 this->drawShadowedPath(canvas, fWideOvalPath, zPlaneParams, paint, .1f,
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500317 lightPos, kLightWidth, .5f);
318 }
319
320 bool onAnimate(const SkAnimTimer& timer) override {
Brian Salomonab664fa2017-03-24 16:07:20 +0000321 fAnimTranslate = timer.pingPong(30, 0, 200, -200);
Jim Van Verthda965502017-04-11 15:29:14 -0400322 fAnimAngle = timer.pingPong(15, 0, 0, 20);
Jim Van Verth744cbb32017-12-19 13:02:38 -0500323 if (fDoAlphaAnimation) {
324 fAnimAlpha = timer.pingPong(5, 0, 1, 0);
325 }
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500326 return true;
jvanverthe1a3bc62016-08-12 10:40:38 -0700327 }
328
jvanverthe1a3bc62016-08-12 10:40:38 -0700329private:
Jim Van Verth6f449692017-02-14 15:16:46 -0500330 typedef SampleView INHERITED;
jvanverthe1a3bc62016-08-12 10:40:38 -0700331};
332
333//////////////////////////////////////////////////////////////////////////////
334
335static SkView* MyFactory() { return new ShadowsView; }
336static SkViewRegister reg(MyFactory);