123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- /*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #include "include/core/SkCanvas.h"
- #include "include/core/SkColorFilter.h"
- #include "include/core/SkPath.h"
- #include "include/core/SkPoint3.h"
- #include "include/effects/SkBlurMaskFilter.h"
- #include "include/pathops/SkPathOps.h"
- #include "include/utils/SkCamera.h"
- #include "include/utils/SkShadowUtils.h"
- #include "samplecode/Sample.h"
- #include "src/core/SkBlurMask.h"
- #include "src/utils/SkUTF.h"
- #include "tools/ToolUtils.h"
- #include "tools/timer/TimeUtils.h"
- ////////////////////////////////////////////////////////////////////////////
- class ShadowsView : public Sample {
- SkPath fRectPath;
- SkPath fRRPath;
- SkPath fCirclePath;
- SkPath fFunkyRRPath;
- SkPath fCubicPath;
- SkPath fStarPath;
- SkPath fSquareRRectPath;
- SkPath fWideRectPath;
- SkPath fWideOvalPath;
- SkPath fNotchPath;
- SkPath fTabPath;
- SkPoint3 fLightPos;
- SkScalar fZDelta = 0;
- SkScalar fAnimTranslate = 0;
- SkScalar fAnimAngle = 0;
- SkScalar fAnimAlpha = 1;
- bool fShowAmbient = true;
- bool fShowSpot = true;
- bool fUseAlt = false;
- bool fShowObject = true;
- bool fIgnoreShadowAlpha = false;
- bool fDoAlphaAnimation = false;
- void onOnceBeforeDraw() override {
- fCirclePath.addCircle(0, 0, 50);
- fRectPath.addRect(SkRect::MakeXYWH(-100, -50, 200, 100));
- fRRPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-100, -50, 200, 100), 4, 4));
- fFunkyRRPath.addRoundRect(SkRect::MakeXYWH(-50, -50, SK_Scalar1 * 100, SK_Scalar1 * 100),
- 40 * SK_Scalar1, 20 * SK_Scalar1,
- SkPath::kCW_Direction);
- fCubicPath.cubicTo(100 * SK_Scalar1, 50 * SK_Scalar1,
- 20 * SK_Scalar1, 100 * SK_Scalar1,
- 0 * SK_Scalar1, 0 * SK_Scalar1);
- fStarPath.moveTo(0.0f, -50.0f);
- fStarPath.lineTo(14.43f, -25.0f);
- fStarPath.lineTo(43.30f, -25.0f);
- fStarPath.lineTo(28.86f, 0.0f);
- fStarPath.lineTo(43.30f, 25.0f);
- fStarPath.lineTo(14.43f, 25.0f);
- fStarPath.lineTo(0.0f, 50.0f);
- fStarPath.lineTo(-14.43f, 25.0f);
- fStarPath.lineTo(-43.30f, 25.0f);
- fStarPath.lineTo(-28.86f, 0.0f);
- fStarPath.lineTo(-43.30f, -25.0f);
- fStarPath.lineTo(-14.43f, -25.0f);
- fSquareRRectPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-50, -50, 100, 100),
- 10, 10));
- fWideRectPath.addRect(SkRect::MakeXYWH(0, 0, 630, 70));
- fWideOvalPath.addOval(SkRect::MakeXYWH(0, 0, 630, 70));
- fNotchPath.moveTo(0, 80);
- fNotchPath.arcTo(SkRect::MakeLTRB(-20, 80, 20, 120), -90, -90, false);
- fNotchPath.lineTo(-75, 100);
- fNotchPath.lineTo(-75, -100);
- fNotchPath.lineTo(75, -100);
- fNotchPath.lineTo(75, 100);
- fNotchPath.arcTo(SkRect::MakeLTRB(-20, 80, 20, 120), 0, -90, false);
- fTabPath.moveTo(-75, -100);
- fTabPath.lineTo(75, -100);
- fTabPath.lineTo(75, 100);
- fTabPath.arcTo(SkRect::MakeLTRB(-20, 80, 20, 120), 0, 90, false);
- fTabPath.arcTo(SkRect::MakeLTRB(-20, 80, 20, 120), 90, 90, false);
- fTabPath.lineTo(-75, 100);
- fLightPos = SkPoint3::Make(350, 0, 600);
- }
- SkString name() override { return SkString("AndroidShadows"); }
- bool onChar(SkUnichar uni) override {
- bool handled = false;
- switch (uni) {
- case 'W':
- fShowAmbient = !fShowAmbient;
- handled = true;
- break;
- case 'S':
- fShowSpot = !fShowSpot;
- handled = true;
- break;
- case 'T':
- fUseAlt = !fUseAlt;
- handled = true;
- break;
- case 'O':
- fShowObject = !fShowObject;
- handled = true;
- break;
- case 'N':
- fDoAlphaAnimation = !fDoAlphaAnimation;
- if (!fDoAlphaAnimation) {
- fAnimAlpha = 1;
- }
- handled = true;
- break;
- case '>':
- fZDelta += 0.5f;
- handled = true;
- break;
- case '<':
- fZDelta -= 0.5f;
- handled = true;
- break;
- case '?':
- fIgnoreShadowAlpha = !fIgnoreShadowAlpha;
- handled = true;
- break;
- default:
- break;
- }
- if (handled) {
- return true;
- }
- return false;
- }
- void drawShadowedPath(SkCanvas* canvas, const SkPath& path,
- const SkPoint3& zPlaneParams,
- const SkPaint& paint, SkScalar ambientAlpha,
- const SkPoint3& lightPos, SkScalar lightWidth, SkScalar spotAlpha) {
- if (fIgnoreShadowAlpha) {
- ambientAlpha = 1;
- spotAlpha = 1;
- }
- if (!fShowAmbient) {
- ambientAlpha = 0;
- }
- if (!fShowSpot) {
- spotAlpha = 0;
- }
- uint32_t flags = 0;
- if (fUseAlt) {
- flags |= SkShadowFlags::kGeometricOnly_ShadowFlag;
- }
- SkColor ambientColor = SkColorSetARGB(ambientAlpha * 255, 0, 0, 0);
- SkColor spotColor = SkColorSetARGB(spotAlpha * 255, 0, 0, 0);
- SkShadowUtils::DrawShadow(canvas, path, zPlaneParams, lightPos, lightWidth,
- ambientColor, spotColor, flags);
- if (fShowObject) {
- canvas->drawPath(path, paint);
- } else {
- SkPaint strokePaint;
- strokePaint.setColor(paint.getColor());
- strokePaint.setStyle(SkPaint::kStroke_Style);
- canvas->drawPath(path, strokePaint);
- }
- }
- void onDrawContent(SkCanvas* canvas) override {
- canvas->drawColor(0xFFDDDDDD);
- const SkScalar kLightWidth = 800;
- const SkScalar kAmbientAlpha = 0.039f;
- const SkScalar kSpotAlpha = 0.19f;
- SkPaint paint;
- paint.setAntiAlias(true);
- SkPoint3 lightPos = fLightPos;
- SkPoint3 zPlaneParams = SkPoint3::Make(0, 0, 0);
- paint.setColor(SK_ColorWHITE);
- canvas->translate(200, 90);
- zPlaneParams.fZ = SkTMax(1.0f, 2 + fZDelta);
- this->drawShadowedPath(canvas, fRRPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
- lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
- paint.setColor(SK_ColorRED);
- canvas->translate(250, 0);
- zPlaneParams.fZ = SkTMax(1.0f, 8 + fZDelta);
- this->drawShadowedPath(canvas, fRectPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
- lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
- paint.setColor(SK_ColorBLUE);
- canvas->translate(-250, 110);
- zPlaneParams.fZ = SkTMax(1.0f, 12 + fZDelta);
- this->drawShadowedPath(canvas, fCirclePath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
- lightPos, kLightWidth, fAnimAlpha*0.5f);
- paint.setColor(SK_ColorGREEN);
- canvas->translate(250, 0);
- zPlaneParams.fZ = SkTMax(1.0f, 64 + fZDelta);
- this->drawShadowedPath(canvas, fRRPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
- lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
- paint.setColor(SK_ColorYELLOW);
- canvas->translate(-250, 110);
- zPlaneParams.fZ = SkTMax(1.0f, 8 + fZDelta);
- this->drawShadowedPath(canvas, fFunkyRRPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
- lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
- paint.setColor(SK_ColorCYAN);
- canvas->translate(250, 0);
- zPlaneParams.fZ = SkTMax(1.0f, 16 + fZDelta);
- this->drawShadowedPath(canvas, fCubicPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
- lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
- paint.setColor(SK_ColorWHITE);
- canvas->translate(250, -180);
- zPlaneParams.fZ = SkTMax(1.0f, 8 + fZDelta);
- this->drawShadowedPath(canvas, fStarPath, zPlaneParams, paint,
- kAmbientAlpha, lightPos, kLightWidth, kSpotAlpha);
- paint.setColor(SK_ColorWHITE);
- canvas->translate(150, 0);
- zPlaneParams.fZ = SkTMax(1.0f, 2 + fZDelta);
- this->drawShadowedPath(canvas, fNotchPath, zPlaneParams, paint,
- kAmbientAlpha, lightPos, kLightWidth, kSpotAlpha);
- paint.setColor(SK_ColorWHITE);
- canvas->translate(200, 0);
- zPlaneParams.fZ = SkTMax(1.0f, 16 + fZDelta);
- this->drawShadowedPath(canvas, fTabPath, zPlaneParams, paint,
- kAmbientAlpha, lightPos, kLightWidth, kSpotAlpha);
- // circular reveal
- SkPath tmpPath;
- SkPath tmpClipPath;
- tmpClipPath.addCircle(fAnimTranslate, 0, 60);
- Op(fSquareRRectPath, tmpClipPath, kIntersect_SkPathOp, &tmpPath);
- paint.setColor(SK_ColorMAGENTA);
- canvas->translate(-725, 240);
- zPlaneParams.fZ = SkTMax(1.0f, 32 + fZDelta);
- this->drawShadowedPath(canvas, tmpPath, zPlaneParams, paint, .1f,
- lightPos, kLightWidth, .5f);
- // path ops bug
- SkPath tmpClipPathBug;
- tmpClipPathBug.addCircle(88.0344925f, 0, 60);
- Op(fSquareRRectPath, tmpClipPathBug, kIntersect_SkPathOp, &tmpPath);
- canvas->translate(250, 0);
- zPlaneParams.fZ = SkTMax(1.0f, 32 + fZDelta);
- this->drawShadowedPath(canvas, tmpPath, zPlaneParams, paint, .1f,
- lightPos, kLightWidth, .5f);
- // perspective paths
- SkPoint pivot = SkPoint::Make(fWideRectPath.getBounds().width()/2,
- fWideRectPath.getBounds().height()/2);
- SkPoint translate = SkPoint::Make(100, 450);
- paint.setColor(SK_ColorWHITE);
- Sk3DView view;
- view.save();
- view.rotateX(fAnimAngle);
- SkMatrix persp;
- view.getMatrix(&persp);
- persp.preTranslate(-pivot.fX, -pivot.fY);
- persp.postTranslate(pivot.fX + translate.fX, pivot.fY + translate.fY);
- canvas->setMatrix(persp);
- SkScalar radians = SkDegreesToRadians(fAnimAngle);
- zPlaneParams = SkPoint3::Make(0,
- SkScalarSin(radians),
- SkTMax(1.0f, 16 + fZDelta) - SkScalarSin(radians)*pivot.fY);
- this->drawShadowedPath(canvas, fWideRectPath, zPlaneParams, paint, .1f,
- lightPos, kLightWidth, .5f);
- pivot = SkPoint::Make(fWideOvalPath.getBounds().width() / 2,
- fWideOvalPath.getBounds().height() / 2);
- translate = SkPoint::Make(100, 600);
- view.restore();
- view.save();
- view.rotateY(fAnimAngle);
- view.getMatrix(&persp);
- persp.preTranslate(-pivot.fX, -pivot.fY);
- persp.postTranslate(pivot.fX + translate.fX, pivot.fY + translate.fY);
- canvas->setMatrix(persp);
- zPlaneParams = SkPoint3::Make(-SkScalarSin(radians),
- 0,
- SkTMax(1.0f, 32 + fZDelta) + SkScalarSin(radians)*pivot.fX);
- this->drawShadowedPath(canvas, fWideOvalPath, zPlaneParams, paint, .1f,
- lightPos, kLightWidth, .5f);
- pivot = SkPoint::Make(fStarPath.getBounds().width() / 2,
- fStarPath.getBounds().height() / 2);
- translate = SkPoint::Make(700, 250);
- view.restore();
- view.rotateY(fAnimAngle);
- view.getMatrix(&persp);
- persp.preTranslate(-pivot.fX, -pivot.fY);
- persp.postTranslate(pivot.fX + translate.fX, pivot.fY + translate.fY);
- canvas->setMatrix(persp);
- zPlaneParams = SkPoint3::Make(-SkScalarSin(radians),
- 0,
- SkTMax(1.0f, 8 + fZDelta) + SkScalarSin(radians)*pivot.fX);
- this->drawShadowedPath(canvas, fStarPath, zPlaneParams, paint, .1f,
- lightPos, kLightWidth, .5f);
- }
- bool onAnimate(double nanos) override {
- fAnimTranslate = TimeUtils::PingPong(1e-9 * nanos, 30, 0, 125, -125);
- fAnimAngle = TimeUtils::PingPong(1e-9 * nanos, 15, 0, 0, 20);
- if (fDoAlphaAnimation) {
- fAnimAlpha = TimeUtils::PingPong(1e-9 * nanos, 5, 0, 1, 0);
- }
- return true;
- }
- private:
- typedef Sample INHERITED;
- };
- //////////////////////////////////////////////////////////////////////////////
- DEF_SAMPLE( return new ShadowsView(); )
|