blob: 8f076f4c66db0666674316b4ea695c5eb07e6001 [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 Verth2c1cd6d2017-03-10 14:34:51 -050031 SkPath fSquareRRectPath;
32 SkPath fWideRectPath;
33 SkPath fWideOvalPath;
jvanverthe1a3bc62016-08-12 10:40:38 -070034 SkPoint3 fLightPos;
Jim Van Verth2aa535e2017-02-06 14:36:01 -050035 SkScalar fZDelta;
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -050036 SkScalar fAnimTranslate;
Jim Van Verthda965502017-04-11 15:29:14 -040037 SkScalar fAnimAngle;
Jim Van Verth744cbb32017-12-19 13:02:38 -050038 SkScalar fAnimAlpha;
jvanverthe1a3bc62016-08-12 10:40:38 -070039
40 bool fShowAmbient;
41 bool fShowSpot;
jvanverthd7315f912016-08-17 10:06:18 -070042 bool fUseAlt;
jvanverthe1a3bc62016-08-12 10:40:38 -070043 bool fShowObject;
Robert Phillips95304e32016-10-07 14:44:07 -040044 bool fIgnoreShadowAlpha;
Jim Van Verth744cbb32017-12-19 13:02:38 -050045 bool fDoAlphaAnimation;
jvanverthe1a3bc62016-08-12 10:40:38 -070046
47public:
Jim Van Verth2aa535e2017-02-06 14:36:01 -050048 ShadowsView()
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -050049 : fZDelta(0)
50 , fAnimTranslate(0)
Jim Van Verthda965502017-04-11 15:29:14 -040051 , fAnimAngle(0)
Jim Van Verth744cbb32017-12-19 13:02:38 -050052 , fAnimAlpha(1)
Jim Van Verth2aa535e2017-02-06 14:36:01 -050053 , fShowAmbient(true)
jvanverthe1a3bc62016-08-12 10:40:38 -070054 , fShowSpot(true)
Jim Van Verthb6069df2017-04-28 11:00:35 -040055 , fUseAlt(false)
Robert Phillips95304e32016-10-07 14:44:07 -040056 , fShowObject(true)
Jim Van Verth744cbb32017-12-19 13:02:38 -050057 , fIgnoreShadowAlpha(false)
58 , fDoAlphaAnimation(false) {}
jvanverthe1a3bc62016-08-12 10:40:38 -070059
60protected:
61 void onOnceBeforeDraw() override {
62 fCirclePath.addCircle(0, 0, 50);
63 fRectPath.addRect(SkRect::MakeXYWH(-100, -50, 200, 100));
64 fRRPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-100, -50, 200, 100), 4, 4));
Jim Van Verthbce74962017-01-25 09:39:46 -050065 fFunkyRRPath.addRoundRect(SkRect::MakeXYWH(-50, -50, SK_Scalar1 * 100, SK_Scalar1 * 100),
66 40 * SK_Scalar1, 20 * SK_Scalar1,
67 SkPath::kCW_Direction);
68 fCubicPath.cubicTo(100 * SK_Scalar1, 50 * SK_Scalar1,
69 20 * SK_Scalar1, 100 * SK_Scalar1,
70 0 * SK_Scalar1, 0 * SK_Scalar1);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -050071 fSquareRRectPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-50, -50, 100, 100),
72 10, 10));
73 fWideRectPath.addRect(SkRect::MakeXYWH(0, 0, 630, 70));
74 fWideOvalPath.addOval(SkRect::MakeXYWH(0, 0, 630, 70));
Jim Van Verthbce74962017-01-25 09:39:46 -050075
Jim Van Verthb6069df2017-04-28 11:00:35 -040076 fLightPos = SkPoint3::Make(350, 0, 600);
jvanverthe1a3bc62016-08-12 10:40:38 -070077 }
78
79 // overrides from SkEventSink
80 bool onQuery(SkEvent* evt) override {
81 if (SampleCode::TitleQ(*evt)) {
82 SampleCode::TitleR(evt, "AndroidShadows");
83 return true;
84 }
85
86 SkUnichar uni;
87 if (SampleCode::CharQ(*evt, &uni)) {
Jim Van Verth6f449692017-02-14 15:16:46 -050088 bool handled = false;
jvanverthe1a3bc62016-08-12 10:40:38 -070089 switch (uni) {
Jim Van Verth2aa535e2017-02-06 14:36:01 -050090 case 'W':
jvanverthe1a3bc62016-08-12 10:40:38 -070091 fShowAmbient = !fShowAmbient;
Jim Van Verth6f449692017-02-14 15:16:46 -050092 handled = true;
jvanverthe1a3bc62016-08-12 10:40:38 -070093 break;
94 case 'S':
95 fShowSpot = !fShowSpot;
Jim Van Verth6f449692017-02-14 15:16:46 -050096 handled = true;
jvanverthe1a3bc62016-08-12 10:40:38 -070097 break;
jvanverthd7315f912016-08-17 10:06:18 -070098 case 'T':
99 fUseAlt = !fUseAlt;
Jim Van Verth6f449692017-02-14 15:16:46 -0500100 handled = true;
jvanverthd7315f912016-08-17 10:06:18 -0700101 break;
jvanverthe1a3bc62016-08-12 10:40:38 -0700102 case 'O':
103 fShowObject = !fShowObject;
Jim Van Verth6f449692017-02-14 15:16:46 -0500104 handled = true;
jvanverthe1a3bc62016-08-12 10:40:38 -0700105 break;
Jim Van Verth744cbb32017-12-19 13:02:38 -0500106 case 'N':
107 fDoAlphaAnimation = !fDoAlphaAnimation;
108 if (!fDoAlphaAnimation) {
109 fAnimAlpha = 1;
110 }
111 handled = true;
112 break;
jvanverthe1a3bc62016-08-12 10:40:38 -0700113 case '>':
Jim Van Verth2aa535e2017-02-06 14:36:01 -0500114 fZDelta += 0.5f;
Jim Van Verth6f449692017-02-14 15:16:46 -0500115 handled = true;
jvanverthe1a3bc62016-08-12 10:40:38 -0700116 break;
117 case '<':
Jim Van Verth2aa535e2017-02-06 14:36:01 -0500118 fZDelta -= 0.5f;
Jim Van Verth6f449692017-02-14 15:16:46 -0500119 handled = true;
jvanverthe1a3bc62016-08-12 10:40:38 -0700120 break;
Robert Phillips95304e32016-10-07 14:44:07 -0400121 case '?':
122 fIgnoreShadowAlpha = !fIgnoreShadowAlpha;
Jim Van Verth6f449692017-02-14 15:16:46 -0500123 handled = true;
Robert Phillips95304e32016-10-07 14:44:07 -0400124 break;
jvanverthe1a3bc62016-08-12 10:40:38 -0700125 default:
126 break;
127 }
Jim Van Verth6f449692017-02-14 15:16:46 -0500128 if (handled) {
Jim Van Verth6f449692017-02-14 15:16:46 -0500129 return true;
130 }
jvanverthe1a3bc62016-08-12 10:40:38 -0700131 }
132 return this->INHERITED::onQuery(evt);
133 }
134
135 void drawBG(SkCanvas* canvas) {
136 canvas->drawColor(0xFFDDDDDD);
137 }
138
Jim Van Verthda965502017-04-11 15:29:14 -0400139 void drawShadowedPath(SkCanvas* canvas, const SkPath& path,
Jim Van Verthe308a122017-05-08 14:19:30 -0400140 const SkPoint3& zPlaneParams,
jvanverthd7315f912016-08-17 10:06:18 -0700141 const SkPaint& paint, SkScalar ambientAlpha,
142 const SkPoint3& lightPos, SkScalar lightWidth, SkScalar spotAlpha) {
Jim Van Verthe7705782017-05-04 14:00:59 -0400143 if (fIgnoreShadowAlpha) {
144 ambientAlpha = 255;
145 spotAlpha = 255;
146 }
Jim Van Verth060d9822017-05-04 09:58:17 -0400147 if (!fShowAmbient) {
148 ambientAlpha = 0;
149 }
150 if (!fShowSpot) {
151 spotAlpha = 0;
152 }
153 uint32_t flags = 0;
Jim Van Verth3c1b7db2016-10-31 16:06:51 -0400154 if (fUseAlt) {
Jim Van Verth060d9822017-05-04 09:58:17 -0400155 flags |= SkShadowFlags::kGeometricOnly_ShadowFlag;
Jim Van Verth3c1b7db2016-10-31 16:06:51 -0400156 }
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400157
Jim Van Vertha5566842018-02-22 10:58:34 -0500158 SkColor ambientColor = SkColorSetARGB(ambientAlpha * 255, 0, 0, 0);
159 SkColor spotColor = SkColorSetARGB(spotAlpha * 255, 0, 0, 0);
160 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams, lightPos, lightWidth,
161 ambientColor, spotColor, flags);
Jim Van Verth3c1b7db2016-10-31 16:06:51 -0400162
jvanverthe1a3bc62016-08-12 10:40:38 -0700163 if (fShowObject) {
164 canvas->drawPath(path, paint);
Robert Phillips95304e32016-10-07 14:44:07 -0400165 } else {
166 SkPaint strokePaint;
167
168 strokePaint.setColor(paint.getColor());
169 strokePaint.setStyle(SkPaint::kStroke_Style);
170
171 canvas->drawPath(path, strokePaint);
jvanverthe1a3bc62016-08-12 10:40:38 -0700172 }
173 }
174
175 void onDrawContent(SkCanvas* canvas) override {
176 this->drawBG(canvas);
Jim Van Verthb6069df2017-04-28 11:00:35 -0400177 const SkScalar kLightWidth = 800;
178 const SkScalar kAmbientAlpha = 0.1f;
jvanverthd7315f912016-08-17 10:06:18 -0700179 const SkScalar kSpotAlpha = 0.25f;
jvanverthe1a3bc62016-08-12 10:40:38 -0700180
181 SkPaint paint;
182 paint.setAntiAlias(true);
183
jvanverthd7315f912016-08-17 10:06:18 -0700184 SkPoint3 lightPos = fLightPos;
Jim Van Verthe308a122017-05-08 14:19:30 -0400185 SkPoint3 zPlaneParams = SkPoint3::Make(0, 0, 0);
jvanverthd7315f912016-08-17 10:06:18 -0700186
jvanverthe1a3bc62016-08-12 10:40:38 -0700187 paint.setColor(SK_ColorWHITE);
188 canvas->translate(200, 90);
Jim Van Verthe308a122017-05-08 14:19:30 -0400189 zPlaneParams.fZ = SkTMax(1.0f, 2 + fZDelta);
Jim Van Verth744cbb32017-12-19 13:02:38 -0500190 this->drawShadowedPath(canvas, fRRPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
191 lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
jvanverthe1a3bc62016-08-12 10:40:38 -0700192
193 paint.setColor(SK_ColorRED);
194 canvas->translate(250, 0);
Jim Van Verthe308a122017-05-08 14:19:30 -0400195 zPlaneParams.fZ = SkTMax(1.0f, 8 + fZDelta);
Jim Van Verth744cbb32017-12-19 13:02:38 -0500196 this->drawShadowedPath(canvas, fRectPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
197 lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
jvanverthe1a3bc62016-08-12 10:40:38 -0700198
199 paint.setColor(SK_ColorBLUE);
200 canvas->translate(-250, 110);
Jim Van Verthe308a122017-05-08 14:19:30 -0400201 zPlaneParams.fZ = SkTMax(1.0f, 12 + fZDelta);
Jim Van Verth744cbb32017-12-19 13:02:38 -0500202 this->drawShadowedPath(canvas, fCirclePath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
203 lightPos, kLightWidth, fAnimAlpha*0.5f);
jvanverth6c177a12016-08-17 07:59:41 -0700204
205 paint.setColor(SK_ColorGREEN);
206 canvas->translate(250, 0);
Jim Van Verthe308a122017-05-08 14:19:30 -0400207 zPlaneParams.fZ = SkTMax(1.0f, 64 + fZDelta);
Jim Van Verth744cbb32017-12-19 13:02:38 -0500208 this->drawShadowedPath(canvas, fRRPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
209 lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
Jim Van Verthbce74962017-01-25 09:39:46 -0500210
211 paint.setColor(SK_ColorYELLOW);
212 canvas->translate(-250, 110);
Jim Van Verthe308a122017-05-08 14:19:30 -0400213 zPlaneParams.fZ = SkTMax(1.0f, 8 + fZDelta);
Jim Van Verth744cbb32017-12-19 13:02:38 -0500214 this->drawShadowedPath(canvas, fFunkyRRPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
215 lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
Jim Van Verthbce74962017-01-25 09:39:46 -0500216
217 paint.setColor(SK_ColorCYAN);
218 canvas->translate(250, 0);
Jim Van Verthe308a122017-05-08 14:19:30 -0400219 zPlaneParams.fZ = SkTMax(1.0f, 16 + fZDelta);
Jim Van Verth744cbb32017-12-19 13:02:38 -0500220 this->drawShadowedPath(canvas, fCubicPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
221 lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500222
223 // circular reveal
224 SkPath tmpPath;
225 SkPath tmpClipPath;
226 tmpClipPath.addCircle(fAnimTranslate, 0, 60);
227 Op(fSquareRRectPath, tmpClipPath, kIntersect_SkPathOp, &tmpPath);
228
229 paint.setColor(SK_ColorMAGENTA);
230 canvas->translate(-125, 60);
Jim Van Verthe308a122017-05-08 14:19:30 -0400231 zPlaneParams.fZ = SkTMax(1.0f, 32 + fZDelta);
232 this->drawShadowedPath(canvas, tmpPath, zPlaneParams, paint, .1f,
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500233 lightPos, kLightWidth, .5f);
234
235 // perspective paths
236 SkPoint pivot = SkPoint::Make(fWideRectPath.getBounds().width()/2,
237 fWideRectPath.getBounds().height()/2);
Jim Van Verthda965502017-04-11 15:29:14 -0400238 SkPoint translate = SkPoint::Make(100, 450);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500239 paint.setColor(SK_ColorWHITE);
240 Sk3DView view;
241 view.save();
Jim Van Verthda965502017-04-11 15:29:14 -0400242 view.rotateX(fAnimAngle);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500243 SkMatrix persp;
244 view.getMatrix(&persp);
245 persp.preTranslate(-pivot.fX, -pivot.fY);
246 persp.postTranslate(pivot.fX + translate.fX, pivot.fY + translate.fY);
247 canvas->setMatrix(persp);
Jim Van Verthda965502017-04-11 15:29:14 -0400248 SkScalar radians = SkDegreesToRadians(fAnimAngle);
Jim Van Verthe308a122017-05-08 14:19:30 -0400249 zPlaneParams = SkPoint3::Make(0,
250 SkScalarSin(-radians),
251 SkTMax(1.0f, 16 + fZDelta) - SkScalarSin(-radians)*pivot.fY);
252 this->drawShadowedPath(canvas, fWideRectPath, zPlaneParams, paint, .1f,
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500253 lightPos, kLightWidth, .5f);
254
255 pivot = SkPoint::Make(fWideOvalPath.getBounds().width() / 2,
256 fWideOvalPath.getBounds().height() / 2);
Jim Van Verthda965502017-04-11 15:29:14 -0400257 translate = SkPoint::Make(100, 600);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500258 view.restore();
Jim Van Verthda965502017-04-11 15:29:14 -0400259 view.rotateY(fAnimAngle);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500260 view.getMatrix(&persp);
261 persp.preTranslate(-pivot.fX, -pivot.fY);
262 persp.postTranslate(pivot.fX + translate.fX, pivot.fY + translate.fY);
263 canvas->setMatrix(persp);
Jim Van Verthe308a122017-05-08 14:19:30 -0400264 zPlaneParams = SkPoint3::Make(-SkScalarSin(radians),
265 0,
266 SkTMax(1.0f, 32 + fZDelta) + SkScalarSin(radians)*pivot.fX);
267 this->drawShadowedPath(canvas, fWideOvalPath, zPlaneParams, paint, .1f,
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500268 lightPos, kLightWidth, .5f);
269 }
270
271 bool onAnimate(const SkAnimTimer& timer) override {
Brian Salomonab664fa2017-03-24 16:07:20 +0000272 fAnimTranslate = timer.pingPong(30, 0, 200, -200);
Jim Van Verthda965502017-04-11 15:29:14 -0400273 fAnimAngle = timer.pingPong(15, 0, 0, 20);
Jim Van Verth744cbb32017-12-19 13:02:38 -0500274 if (fDoAlphaAnimation) {
275 fAnimAlpha = timer.pingPong(5, 0, 1, 0);
276 }
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500277 return true;
jvanverthe1a3bc62016-08-12 10:40:38 -0700278 }
279
jvanverthe1a3bc62016-08-12 10:40:38 -0700280private:
Jim Van Verth6f449692017-02-14 15:16:46 -0500281 typedef SampleView INHERITED;
jvanverthe1a3bc62016-08-12 10:40:38 -0700282};
283
284//////////////////////////////////////////////////////////////////////////////
285
286static SkView* MyFactory() { return new ShadowsView; }
287static SkViewRegister reg(MyFactory);