MouseHover

Signed-off-by: sunfei <sunfei.sun@huawei.com>
Change-Id:  I066d9bef965a0121a7b252706186f0d8213d8271
This commit is contained in:
xielongfeng 2021-11-02 14:16:04 +08:00 committed by sunfei
parent c218998354
commit 04d71fef54
11 changed files with 141 additions and 10 deletions

View File

@ -609,4 +609,12 @@ var ItemState
ItemState[ItemState["Disabled"] = 1] = "Disabled";
ItemState[ItemState["Waiting"] = 2] = "Waiting";
ItemState[ItemState["Skip"] = 3] = "Skip";
})(ItemState || (ItemState = {}));
})(ItemState || (ItemState = {}));
var HoverEffect;
(function (HoverEffect) {
HoverEffect[HoverEffect["Auto"] = 4] = "Auto";
HoverEffect[HoverEffect["Scale"] = 2] = "Scale";
HoverEffect[HoverEffect["Board"] = 3] = "Board";
HoverEffect[HoverEffect["None"] = 0] = "None";
})(HoverEffect || (HoverEffect = {}));

View File

@ -3128,6 +3128,7 @@ void JSViewAbstract::JSBind()
JSClass<JSViewAbstract>::StaticMethod("hueRotate", &JSViewAbstract::JsHueRotate);
JSClass<JSViewAbstract>::StaticMethod("clip", &JSViewAbstract::JsClip);
JSClass<JSViewAbstract>::StaticMethod("mask", &JSViewAbstract::JsMask);
JSClass<JSViewAbstract>::StaticMethod("hoverEffect", &JSViewAbstract::JsHoverEffect);
#if defined(WINDOWS_PLATFORM) || defined(MAC_PLATFORM)
JSClass<JSViewAbstract>::StaticMethod("debugLine", &JSViewAbstract::JsDebugLine);
#endif
@ -3719,4 +3720,14 @@ RefPtr<ThemeConstants> JSViewAbstract::GetThemeConstants()
return themeManager->GetThemeConstants();
}
void JSViewAbstract::JsHoverEffect(const JSCallbackInfo& info)
{
if (!info[0]->IsNumber()) {
LOGE("info[0] is not a number");
return;
}
auto boxComponent = ViewStackProcessor::GetInstance()->GetBoxComponent();
boxComponent->SetMouseAnimationType(static_cast<HoverAnimationType>(info[0]->ToNumber<int32_t>()));
}
} // namespace OHOS::Ace::Framework

View File

@ -101,6 +101,7 @@ public:
static void JsGridSpan(const JSCallbackInfo& Info);
static void JsGridOffset(const JSCallbackInfo& info);
static void JsUseSizeType(const JSCallbackInfo& Info);
static void JsHoverEffect(const JSCallbackInfo& info);
// for number and string with no unit, use default dimension unit.
static bool ParseJsDimension(const JSRef<JSVal>& jsValue, Dimension& result, DimensionUnit defaultUnit);

View File

@ -24,11 +24,6 @@
namespace OHOS::Ace {
enum class HoverAnimationType : int32_t {
NONE,
OPACITY,
SCALE,
};
using OnDragFunc = std::function<void(const RefPtr<DragEvent>& info)>;

View File

@ -35,6 +35,7 @@
#include "core/components/common/properties/color.h"
#include "core/components/flex/render_flex.h"
#include "core/components/image/image_component.h"
#include "core/components/transform/flutter_render_transform.h"
#include "core/pipeline/base/flutter_render_context.h"
#include "core/pipeline/base/scoped_canvas_state.h"
#include "core/pipeline/layers/flutter_scene_builder.h"
@ -243,6 +244,19 @@ void FlutterRenderBox::PerformLayout()
CalculateRepeatParam();
}
void FlutterRenderBox::UpdateLayer()
{
float translateX = GetLayoutSize().Width() / 2.0 * (1.0 - scale_);
float translateY = GetLayoutSize().Height() / 2.0 * (1.0 - scale_);
Matrix4 translateMatrix = Matrix4::CreateTranslate(translateX, translateY, 0.0);
Matrix4 scaleMatrix = Matrix4::CreateScale(scale_, scale_, 1.0);
Matrix4 transformMatrix = translateMatrix * scaleMatrix;
transformMatrix = FlutterRenderTransform::GetTransformByOffset(transformMatrix, GetGlobalOffset());
if (transformLayer_) {
transformLayer_->Update(transformMatrix);
}
}
void FlutterRenderBox::Paint(RenderContext& context, const Offset& offset)
{
const auto renderContext = static_cast<FlutterRenderContext*>(&context);
@ -601,8 +615,14 @@ RenderLayer FlutterRenderBox::GetRenderLayer()
}
renderLayer_->SetStaticOffset(alignOffset_.GetX(), alignOffset_.GetY());
}
return AceType::RawPtr(renderLayer_);
if (isZoom) {
if (!transformLayer_) {
transformLayer_ = AceType::MakeRefPtr<Flutter::TransformLayer>(Matrix4::CreateIdentity(), 0.0, 0.0);
}
return AceType::RawPtr(transformLayer_);
} else {
return AceType::RawPtr(renderLayer_);
}
}
flutter::RRect FlutterRenderBox::GetBoxRRect(

View File

@ -28,6 +28,7 @@
#include "core/pipeline/layers/clip_layer.h"
#include "core/pipeline/layers/container_layer.h"
#include "core/pipeline/layers/offset_layer.h"
#include "core/pipeline/layers/transform_layer.h"
namespace OHOS::Ace {
@ -47,6 +48,7 @@ public:
return true;
}
void DrawOnPixelMap() override;
void UpdateLayer();
protected:
virtual bool MaybeRelease() override;
@ -166,6 +168,7 @@ private:
RefPtr<FlutterRenderTaskHolder> renderTaskHolder_;
UploadSuccessCallback uploadSuccessCallback_;
RefPtr<Flutter::TransformLayer> transformLayer_;
};
} // namespace OHOS::Ace

View File

@ -65,6 +65,8 @@ void RenderBox::Update(const RefPtr<Component>& component)
UpdateBackDecoration(box->GetBackDecoration());
UpdateFrontDecoration(box->GetFrontDecoration());
animationType_ = box->GetMouseAnimationType();
hoverAnimationType_ = animationType_;
isZoom = animationType_ == HoverAnimationType::SCALE;
MarkNeedLayout();
auto tapGesture = box->GetOnClick();
@ -643,6 +645,26 @@ void RenderBox::OnMouseHoverExitAnimation()
controllerExit_->SetFillMode(FillMode::FORWARDS);
}
void RenderBox::CreateFloatAnimation(
RefPtr<KeyframeAnimation<float>>& floatAnimation, float beginValue, float endValue)
{
if (!floatAnimation) {
return;
}
auto keyframeBegin = AceType::MakeRefPtr<Keyframe<float>>(0.0, beginValue);
auto keyframeEnd = AceType::MakeRefPtr<Keyframe<float>>(1.0, endValue);
floatAnimation->AddKeyframe(keyframeBegin);
floatAnimation->AddKeyframe(keyframeEnd);
WeakPtr<Decoration> weakDecoration = WeakPtr<Decoration>(backDecoration_);
floatAnimation->AddListener([weakBox = AceType::WeakClaim(this), weakDecoration](float value) {
auto box = weakBox.Upgrade();
if (box) {
box->scale_ = value;
box->MarkNeedRender();
}
});
}
void RenderBox::CreateColorAnimation(
RefPtr<KeyframeAnimation<Color>>& colorAnimation, const Color& beginValue, const Color& endValue)
{
@ -668,6 +690,28 @@ void RenderBox::CreateColorAnimation(
});
}
void RenderBox::MouseHoverEnterTest()
{
ResetController(controllerExit_);
if (!controllerEnter_) {
controllerEnter_ = AceType::MakeRefPtr<Animator>(context_);
}
if (animationType_ == HoverAnimationType::SCALE) {
scaleAnimationEnter_ = AceType::MakeRefPtr<KeyframeAnimation<float>>();
CreateFloatAnimation(scaleAnimationEnter_,1.0, 1.05);
controllerEnter_->AddInterpolator(scaleAnimationEnter_);
} else if (animationType_ == HoverAnimationType::BOARD) {
colorAnimationEnter_ = AceType::MakeRefPtr<KeyframeAnimation<Color>>();
CreateColorAnimation(colorAnimationEnter_, hoverColor_, Color::FromRGBO(0, 0, 0, 0.05));
controllerEnter_->AddInterpolator(colorAnimationEnter_);
} else {
return;
}
controllerEnter_->SetDuration(HOVER_ANIMATION_DURATION);
controllerEnter_->Play();
controllerEnter_->SetFillMode(FillMode::FORWARDS);
}
void RenderBox::ResetController(RefPtr<Animator>& controller)
{
if (controller) {
@ -678,6 +722,29 @@ void RenderBox::ResetController(RefPtr<Animator>& controller)
}
}
void RenderBox::MouseHoverExitTest()
{
ResetController(controllerEnter_);
if (!controllerExit_) {
controllerExit_ = AceType::MakeRefPtr<Animator>(context_);
}
if (animationType_ == HoverAnimationType::SCALE) {
scaleAnimationExit_ = AceType::MakeRefPtr<KeyframeAnimation<float>>();
auto begin = scale_;
CreateFloatAnimation(scaleAnimationExit_, begin, 1.0);
controllerExit_->AddInterpolator(scaleAnimationExit_);
} else if (animationType_ == HoverAnimationType::BOARD) {
colorAnimationExit_ = AceType::MakeRefPtr<KeyframeAnimation<Color>>();
CreateColorAnimation(colorAnimationExit_, hoverColor_, Color::FromRGBO(0, 0, 0, 0.0));
controllerExit_->AddInterpolator(colorAnimationExit_);
} else {
return;
}
controllerExit_->SetDuration(HOVER_ANIMATION_DURATION);
controllerExit_->Play();
controllerExit_->SetFillMode(FillMode::FORWARDS);
}
void RenderBox::StopMouseHoverAnimation()
{
if (controllerExit_) {

View File

@ -153,12 +153,15 @@ public:
AnimatableDimension GetBackdropRadius() const;
void SetWindowBlurProgress(double progress);
double GetWindowBlurProgress() const;
void CreateFloatAnimation(RefPtr<KeyframeAnimation<float>>& floatAnimation, float beginValue, float endValue);
Size GetBorderSize() const override;
ColorPropertyAnimatable::SetterMap GetColorPropertySetterMap() override;
ColorPropertyAnimatable::GetterMap GetColorPropertyGetterMap() override;
Offset GetGlobalOffsetExternal() const override;
Offset GetGlobalOffset() const override;
void MouseHoverEnterTest() override;
void MouseHoverExitTest() override;
void OnTouchTestHit(
const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result) override;
@ -215,8 +218,12 @@ protected:
RefPtr<Animator> controllerExit_;
RefPtr<KeyframeAnimation<Color>> colorAnimationEnter_;
RefPtr<KeyframeAnimation<Color>> colorAnimationExit_;
RefPtr<KeyframeAnimation<float>> scaleAnimationEnter_;
RefPtr<KeyframeAnimation<float>> scaleAnimationExit_;
HoverAnimationType animationType_ = HoverAnimationType::NONE;
Color hoverColor_ = Color::TRANSPARENT;
float scale_ = 1.0f;
bool isZoom = false;
private:
void ResetController(RefPtr<Animator>& controller);

View File

@ -50,6 +50,14 @@ enum class UpdateRenderType : uint32_t {
EVENT = 1 << 2
};
enum class HoverAnimationType : int32_t {
NONE,
OPACITY,
SCALE,
BOARD,
AUTO,
};
// Component is a read-only structure, represent the basic information how to display it.
class ACE_EXPORT Component : public virtual AceType {
DECLARE_ACE_TYPE(Component, AceType);

View File

@ -698,7 +698,11 @@ bool RenderNode::MouseHoverTest(const Point& parentLocalPoint)
}
// mouse state of the node is from NONE to HOVER, the callback of hover enter is triggered.
if (mouseState_ == MouseState::NONE) {
OnMouseHoverEnterTest();
if (hoverAnimationType_ == HoverAnimationType::AUTO) {
OnMouseHoverEnterTest();
} else {
MouseHoverEnterTest();
}
mouseState_ = MouseState::HOVER;
HandleMouseHoverEvent(MouseState::HOVER);
}
@ -709,7 +713,11 @@ bool RenderNode::MouseHoverTest(const Point& parentLocalPoint)
}
// mouse state of the node is from HOVER to NONE, the callback of hover exit is triggered.
if (mouseState_ == MouseState::HOVER) {
OnMouseHoverExitTest();
if (hoverAnimationType_ == HoverAnimationType::AUTO) {
OnMouseHoverExitTest();
} else {
MouseHoverExitTest();
}
mouseState_ = MouseState::NONE;
HandleMouseHoverEvent(MouseState::NONE);
}

View File

@ -908,6 +908,8 @@ protected:
virtual void OnMouseTestHit(const Offset& coordinateOffset, MouseTestResult& result) {}
virtual void OnMouseHoverEnterTest() {}
virtual void OnMouseHoverExitTest() {}
virtual void MouseHoverEnterTest() {}
virtual void MouseHoverExitTest() {}
void PrepareLayout();
@ -980,6 +982,7 @@ protected:
bool needWindowBlur_ = false;
bool needUpdateAccessibility_ = true;
bool disabled_ = false;
HoverAnimationType hoverAnimationType_ = HoverAnimationType::AUTO;
int32_t minPlatformVersion_ = 0;
MouseState mouseState_ = MouseState::NONE;