blob: 485b1f5ae812ab1de195088ebee27a7115901282 [file] [log] [blame]
/*
* Copyright 2019 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "modules/skottie/src/effects/Effects.h"
#include "modules/skottie/src/SkottieJson.h"
#include "modules/skottie/src/Transform.h"
#include "modules/sksg/include/SkSGOpacityEffect.h"
#include "modules/sksg/include/SkSGTransform.h"
namespace skottie {
namespace internal {
namespace {
class TransformEffectAdapter final : public DiscardableAdapterBase<TransformEffectAdapter,
sksg::OpacityEffect> {
public:
TransformEffectAdapter(const AnimationBuilder& abuilder,
const skjson::ObjectValue* jopacity,
const skjson::ObjectValue* jscale_uniform,
const skjson::ObjectValue* jscale_width,
const skjson::ObjectValue* jscale_height,
sk_sp<TransformAdapter2D> tadapter,
sk_sp<sksg::RenderNode> child)
: INHERITED(sksg::OpacityEffect::Make(std::move(child)))
, fTransformAdapter(std::move(tadapter)) {
this->bind(abuilder, jopacity , fOpacity );
this->bind(abuilder, jscale_uniform, fUniformScale);
this->bind(abuilder, jscale_width , fScaleWidth );
this->bind(abuilder, jscale_height , fScaleHeight );
this->attachDiscardableAdapter(fTransformAdapter);
}
private:
void onSync() override {
this->node()->setOpacity(fOpacity * 0.01f);
// In uniform mode, the scale is based solely in ScaleHeight.
const auto scale = SkVector::Make(SkScalarRoundToInt(fUniformScale) ? fScaleHeight
: fScaleWidth,
fScaleHeight);
// NB: this triggers an transform adapter -> SG sync.
fTransformAdapter->setScale(scale);
}
const sk_sp<TransformAdapter2D> fTransformAdapter;
ScalarValue fOpacity = 100,
fUniformScale = 0, // bool
fScaleWidth = 100,
fScaleHeight = 100;
using INHERITED = DiscardableAdapterBase<TransformEffectAdapter, sksg::OpacityEffect>;
};
} // namespace
sk_sp<sksg::RenderNode> EffectBuilder::attachTransformEffect(const skjson::ArrayValue& jprops,
sk_sp<sksg::RenderNode> layer) const {
enum : size_t {
kAnchorPoint_Index = 0,
kPosition_Index = 1,
kUniformScale_Index = 2,
kScaleHeight_Index = 3,
kScaleWidth_Index = 4,
kSkew_Index = 5,
kSkewAxis_Index = 6,
kRotation_Index = 7,
kOpacity_Index = 8,
// kUseCompShutterAngle_Index = 9,
// kShutterAngle_Index = 10,
// kSampling_Index = 11,
};
auto transform_adapter = TransformAdapter2D::Make(*fBuilder,
GetPropValue(jprops, kAnchorPoint_Index),
GetPropValue(jprops, kPosition_Index),
nullptr, // scale is handled externally
GetPropValue(jprops, kRotation_Index),
GetPropValue(jprops, kSkew_Index),
GetPropValue(jprops, kSkewAxis_Index));
if (!transform_adapter) {
return nullptr;
}
auto transform_effect_node = sksg::TransformEffect::Make(std::move(layer),
transform_adapter->node());
return fBuilder->attachDiscardableAdapter<TransformEffectAdapter>
(*fBuilder,
GetPropValue(jprops, kOpacity_Index),
GetPropValue(jprops, kUniformScale_Index),
GetPropValue(jprops, kScaleWidth_Index),
GetPropValue(jprops, kScaleHeight_Index),
std::move(transform_adapter),
std::move(transform_effect_node)
);
}
} // namespace internal
} // namespace skottie