From 623fadf8be3d3a2061f8b491575c5b82707121df Mon Sep 17 00:00:00 2001 From: Jim Van Verth Date: Tue, 23 May 2017 13:50:58 -0400 Subject: Add Material Design shadow reference sample Change-Id: I889a3f508407178c457f675c321880d869caf9ea Reviewed-on: https://skia-review.googlesource.com/17717 Commit-Queue: Jim Van Verth Reviewed-by: Robert Phillips --- samplecode/SampleShadowReference.cpp | 205 +++++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100755 samplecode/SampleShadowReference.cpp (limited to 'samplecode/SampleShadowReference.cpp') diff --git a/samplecode/SampleShadowReference.cpp b/samplecode/SampleShadowReference.cpp new file mode 100755 index 0000000000..99ff4b2c8b --- /dev/null +++ b/samplecode/SampleShadowReference.cpp @@ -0,0 +1,205 @@ + +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "SampleCode.h" +#include "Resources.h" +#include "SkCanvas.h" +#include "SkImage.h" +#include "SkPath.h" +#include "SkPoint3.h" +#include "SkShadowUtils.h" + +//////////////////////////////////////////////////////////////////////////// +// Sample to compare the Material Design shadow reference to our results + +class ShadowRefView : public SampleView { + SkPath fRRectPath; + sk_sp fReferenceImage; + + bool fShowAmbient; + bool fShowSpot; + bool fUseAlt; + bool fShowObject; + +public: + ShadowRefView() + : fShowAmbient(true) + , fShowSpot(true) + , fUseAlt(false) + , fShowObject(true) {} + +protected: + void onOnceBeforeDraw() override { + fRRectPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-130, -128.5, 130, 128.5), 4, 4)); + fReferenceImage = GetResourceAsImage("shadowreference.png"); + } + + // overrides from SkEventSink + bool onQuery(SkEvent* evt) override { + if (SampleCode::TitleQ(*evt)) { + SampleCode::TitleR(evt, "ShadowReference"); + return true; + } + + SkUnichar uni; + if (SampleCode::CharQ(*evt, &uni)) { + 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; + default: + break; + } + if (handled) { + this->inval(nullptr); + return true; + } + } + return this->INHERITED::onQuery(evt); + } + + void drawBG(SkCanvas* canvas) { + canvas->drawColor(0xFFFFFFFF); + canvas->drawImage(fReferenceImage, 10, 30); + } + + void drawShadowedPath(SkCanvas* canvas, const SkPath& path, + const SkPoint3& zPlaneParams, + const SkPaint& paint, SkScalar ambientAlpha, + const SkPoint3& lightPos, SkScalar lightWidth, SkScalar spotAlpha) { + if (!fShowAmbient) { + ambientAlpha = 0; + } + if (!fShowSpot) { + spotAlpha = 0; + } + uint32_t flags = 0; + if (fUseAlt) { + flags |= SkShadowFlags::kGeometricOnly_ShadowFlag; + } + SkShadowUtils::DrawShadow(canvas, path, zPlaneParams, + lightPos, lightWidth, + ambientAlpha, spotAlpha, SK_ColorBLACK, 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 { + this->drawBG(canvas); + const SkScalar kDP = 4; // the reference image is 4x bigger than it is displayed on + // on the web page, so we need to reflect that here and + // multiply the heights and light params accordingly + const SkScalar kLightWidth = kDP*400; + const SkScalar kAmbientAlpha = 0.03f; + const SkScalar kSpotAlpha = 0.35f; + + SkPaint paint; + paint.setAntiAlias(true); + paint.setColor(SK_ColorWHITE); + + SkPoint3 lightPos = { 175, -800, kDP * 600 }; + SkScalar xPos = 230; + SkScalar yPos = 254.25f; + SkRect clipRect = SkRect::MakeXYWH(45, 75, 122, 250); + SkPoint clipDelta = SkPoint::Make(320, 0); + SkPoint3 zPlaneParams = SkPoint3::Make(0, 0, kDP * 2); + + canvas->save(); + canvas->clipRect(clipRect); + canvas->translate(xPos, yPos); + this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha, + lightPos, kLightWidth, kSpotAlpha); + canvas->restore(); + + lightPos.fX += 320; + xPos += 320; + clipRect.offset(clipDelta); + zPlaneParams.fZ = kDP * 3; + canvas->save(); + canvas->clipRect(clipRect); + canvas->translate(xPos, yPos); + this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha, + lightPos, kLightWidth, kSpotAlpha); + canvas->restore(); + + lightPos.fX += 320; + xPos += 320; + clipRect.offset(clipDelta); + zPlaneParams.fZ = kDP * 4; + canvas->save(); + canvas->clipRect(clipRect); + canvas->translate(xPos, yPos); + this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha, + lightPos, kLightWidth, kSpotAlpha); + canvas->restore(); + + lightPos.fX += 320; + xPos += 320; + clipRect.offset(clipDelta); + zPlaneParams.fZ = kDP * 6; + canvas->save(); + canvas->clipRect(clipRect); + canvas->translate(xPos, yPos); + this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha, + lightPos, kLightWidth, kSpotAlpha); + canvas->restore(); + + lightPos.fX += 320; + xPos += 320; + clipRect.offset(clipDelta); + zPlaneParams.fZ = kDP * 8; + canvas->save(); + canvas->clipRect(clipRect); + canvas->translate(xPos, yPos); + this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha, + lightPos, kLightWidth, kSpotAlpha); + canvas->restore(); + + lightPos.fX += 320; + xPos += 320; + clipRect.offset(clipDelta); + zPlaneParams.fZ = kDP * 16; + canvas->save(); + canvas->clipRect(clipRect); + canvas->translate(xPos, yPos); + this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha, + lightPos, kLightWidth, kSpotAlpha); + canvas->restore(); + + } + +private: + typedef SampleView INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +static SkView* MyFactory() { return new ShadowRefView; } +static SkViewRegister reg(MyFactory); -- cgit v1.2.3