Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
LinearWipeEffect.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2019 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
13#include "include/core/SkSize.h"
21
22#include <algorithm>
23#include <cmath>
24#include <cstddef>
25#include <utility>
26
27namespace skjson {
28class ArrayValue;
29}
30
31namespace skottie {
32namespace internal {
33
34namespace {
35
36class LinearWipeAdapter final : public MaskShaderEffectBase {
37public:
40 const SkSize& layer_size,
41 const AnimationBuilder* abuilder) {
42 return sk_sp<LinearWipeAdapter>(new LinearWipeAdapter(jprops,
43 std::move(layer),
44 layer_size,
45 abuilder));
46 }
47
48private:
49 LinearWipeAdapter(const skjson::ArrayValue& jprops,
51 const SkSize& layer_size,
52 const AnimationBuilder* abuilder)
53 : INHERITED(std::move(layer), layer_size) {
54 enum : size_t {
55 kCompletion_Index = 0,
56 kAngle_Index = 1,
57 kFeather_Index = 2,
58 };
59
60 EffectBinder(jprops, *abuilder, this)
61 .bind(kCompletion_Index, fCompletion)
62 .bind( kAngle_Index, fAngle )
63 .bind( kFeather_Index, fFeather );
64 }
65
66 MaskInfo onMakeMask() const override {
67 if (fCompletion >= 100) {
68 // The layer is fully disabled.
69 // TODO: fix layer controller visibility clash and pass a null shader instead.
70 return { SkShaders::Color(SK_ColorTRANSPARENT), false };
71 }
72
73 if (fCompletion <= 0) {
74 // The layer is fully visible (no mask).
75 return { nullptr, true };
76 }
77
78 const auto t = SkTPin(fCompletion * 0.01f, 0.0f, 1.0f),
79 feather = std::max(fFeather, 0.0f),
80 angle = SkDegreesToRadians(90 - fAngle),
81 cos_ = std::cos(angle),
82 sin_ = std::sin(angle);
83
84 // Select the correct diagonal vector depending on quadrant.
85 const SkVector angle_v = {cos_, sin_},
86 diag_v = {std::copysign(this->layerSize().width() , cos_),
87 std::copysign(this->layerSize().height(), sin_)};
88
89 // The transition length is the projection of the diagonal onto the angle vector.
90 const auto len = SkVector::DotProduct(diag_v, angle_v);
91
92 // Pad the gradient segment to accommodate optional feather ramps at both extremities.
93 const auto grad_len = len + feather * 2;
94 const SkVector grad_v = angle_v * grad_len,
95 adjusted_grad_v = { grad_v.fX, -grad_v.fY }, // Y flipped for drawing space.
96 center_v = {0.5f * this->layerSize().width(),
97 0.5f * this->layerSize().height()};
98
99 // Gradient start/end points:
100 const SkPoint pts[] = {
101 center_v - adjusted_grad_v * 0.5f,
102 center_v + adjusted_grad_v * 0.5f,
103 };
104
105 static constexpr SkColor colors[] = { 0x00000000,
106 0xffffffff };
107
108 // To emulate the feather effect, we distance the color stops to generate
109 // a linear transition/ramp. For t == 0 the ramp should be completely outside/before
110 // the transition domain, and for t == 1 it should be completely outside/after.
111 //
112 // [0 ................... |len|]
113 //
114 // [0 <feather_ramp> [ ] <feather_ramp> |grad_len|]
115 const auto adjusted_t = t * (len + feather) / grad_len;
116 const SkScalar pos[] = { adjusted_t,
117 adjusted_t + feather / grad_len };
118
119 return { SkGradientShader::MakeLinear(pts, colors, pos, 2, SkTileMode::kClamp), true };
120 }
121
122 ScalarValue fCompletion = 0,
123 fAngle = 0,
124 fFeather = 0;
125
126 using INHERITED = MaskShaderEffectBase;
127};
128
129} // namespace
130
131sk_sp<sksg::RenderNode> EffectBuilder::attachLinearWipeEffect(const skjson::ArrayValue& jprops,
132 sk_sp<sksg::RenderNode> layer) const {
133 return fBuilder->attachDiscardableAdapter<LinearWipeAdapter>(jprops,
134 std::move(layer),
135 fLayerSize,
136 fBuilder);
137}
138
139} // namespace internal
140} // namespace skottie
141
SkPoint pos
uint32_t SkColor
Definition SkColor.h:37
constexpr SkColor SK_ColorTRANSPARENT
Definition SkColor.h:99
static std::unique_ptr< SkEncoder > Make(SkWStream *dst, const SkPixmap *src, const SkYUVAPixmaps *srcYUVA, const SkColorSpace *srcYUVAColorSpace, const SkJpegEncoder::Options &options)
#define INHERITED(method,...)
#define SkDegreesToRadians(degrees)
Definition SkScalar.h:77
static constexpr const T & SkTPin(const T &x, const T &lo, const T &hi)
Definition SkTPin.h:19
static sk_sp< SkShader > MakeLinear(const SkPoint pts[2], const SkColor colors[], const SkScalar pos[], int count, SkTileMode mode, uint32_t flags=0, const SkMatrix *localMatrix=nullptr)
void attachDiscardableAdapter(sk_sp< T > adapter) const
float SkScalar
Definition extension.cpp:12
PODArray< SkColor > colors
Definition SkRecords.h:276
SkScalar ScalarValue
Definition ref_ptr.h:256
int32_t height
int32_t width
float fX
x-axis value
static float DotProduct(const SkVector &a, const SkVector &b)
float fY
y-axis value