Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inverting touch point relatively to view transformation #45571

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -260,21 +260,34 @@ ShadowNode::Shared LayoutableShadowNode::findNodeAtPoint(
!layoutableShadowNode->canChildrenBeTouchTarget()) {
return nullptr;
}

auto layoutMetrics = layoutableShadowNode->getLayoutMetrics();
auto frame = layoutMetrics.frame;
auto overflow = layoutMetrics.overflowInset;

auto currentTransform = layoutableShadowNode->getTransform();
bool isInverted = currentTransform.inv();
Point transformedPoint = point;

if (isInverted) {
transformedPoint = currentTransform.applyWithRect(transformedPoint, frame);
}

auto frame = layoutableShadowNode->getLayoutMetrics().frame;
auto transformedFrame = frame * layoutableShadowNode->getTransform();
auto isPointInside = transformedFrame.containsPoint(point);

if (!isPointInside) {
return nullptr;
} else if (!layoutableShadowNode->canChildrenBeTouchTarget()) {
return node;
auto isPointInside = frame.containsPoint(transformedPoint);

if (isPointInside && !layoutableShadowNode->canChildrenBeTouchTarget()) {
return node;
}

auto newPoint = point - transformedFrame.origin -
auto newPoint = transformedPoint - frame.origin -
layoutableShadowNode->getContentOriginOffset(false);

auto sortedChildren = node->getChildren();

if (!isPointInside && (sortedChildren.size() == 0 || overflow.isZero())) {
return nullptr;
}

std::stable_sort(
sortedChildren.begin(),
sortedChildren.end(),
Expand All @@ -284,12 +297,18 @@ ShadowNode::Shared LayoutableShadowNode::findNodeAtPoint(

for (auto it = sortedChildren.rbegin(); it != sortedChildren.rend(); it++) {
const auto& childShadowNode = *it;
auto hitView = findNodeAtPoint(childShadowNode, newPoint);
if (hitView) {
return hitView;
}
auto hitSubview = findNodeAtPoint(childShadowNode, newPoint);

if (hitSubview) {
return hitSubview;
}
}

if (layoutableShadowNode->canBeTouchTarget() && isPointInside) {
return node;
}
return layoutableShadowNode->canBeTouchTarget() ? node : nullptr;

return nullptr;
}

#if RN_DEBUG_STRING_CONVERTIBLE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ struct RectangleEdges {
return left == top && left == right && left == bottom;
}

bool isZero() const noexcept {
return left == 0 && top == 0 && right == 0 && bottom == 0;
}

static const RectangleEdges<T> ZERO;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,15 @@ Rect Transform::applyWithCenter(const Rect& rect, const Point& center) const {
transformedA, transformedB, transformedC, transformedD);
}

Point Transform::applyWithRect(const Point& point, const Rect& rect) const {
return this->applyWithCenter(point, rect.getCenter());
}

Point Transform::applyWithCenter(const Point& point, const Point& center) const {
auto vector = *this * Vector{point.x - center.x, point.y - center.y, 0, 1};
return {vector.x + center.x, vector.y + center.y};
}

EdgeInsets operator*(const EdgeInsets& edgeInsets, const Transform& transform) {
return EdgeInsets{
edgeInsets.left * transform.matrix[0],
Expand Down Expand Up @@ -487,4 +496,138 @@ Size operator*(const Size& size, const Transform& transform) {
return result;
}

bool Transform::inv() {
if (*this == Transform::Identity()) {
return true;
}

double inv[16], det;
int i;
auto m = this->matrix;

inv[0] = m[5] * m[10] * m[15] -
m[5] * m[11] * m[14] -
m[9] * m[6] * m[15] +
m[9] * m[7] * m[14] +
m[13] * m[6] * m[11] -
m[13] * m[7] * m[10];

inv[4] = -m[4] * m[10] * m[15] +
m[4] * m[11] * m[14] +
m[8] * m[6] * m[15] -
m[8] * m[7] * m[14] -
m[12] * m[6] * m[11] +
m[12] * m[7] * m[10];

inv[8] = m[4] * m[9] * m[15] -
m[4] * m[11] * m[13] -
m[8] * m[5] * m[15] +
m[8] * m[7] * m[13] +
m[12] * m[5] * m[11] -
m[12] * m[7] * m[9];

inv[12] = -m[4] * m[9] * m[14] +
m[4] * m[10] * m[13] +
m[8] * m[5] * m[14] -
m[8] * m[6] * m[13] -
m[12] * m[5] * m[10] +
m[12] * m[6] * m[9];

inv[1] = -m[1] * m[10] * m[15] +
m[1] * m[11] * m[14] +
m[9] * m[2] * m[15] -
m[9] * m[3] * m[14] -
m[13] * m[2] * m[11] +
m[13] * m[3] * m[10];

inv[5] = m[0] * m[10] * m[15] -
m[0] * m[11] * m[14] -
m[8] * m[2] * m[15] +
m[8] * m[3] * m[14] +
m[12] * m[2] * m[11] -
m[12] * m[3] * m[10];

inv[9] = -m[0] * m[9] * m[15] +
m[0] * m[11] * m[13] +
m[8] * m[1] * m[15] -
m[8] * m[3] * m[13] -
m[12] * m[1] * m[11] +
m[12] * m[3] * m[9];

inv[13] = m[0] * m[9] * m[14] -
m[0] * m[10] * m[13] -
m[8] * m[1] * m[14] +
m[8] * m[2] * m[13] +
m[12] * m[1] * m[10] -
m[12] * m[2] * m[9];

inv[2] = m[1] * m[6] * m[15] -
m[1] * m[7] * m[14] -
m[5] * m[2] * m[15] +
m[5] * m[3] * m[14] +
m[13] * m[2] * m[7] -
m[13] * m[3] * m[6];

inv[6] = -m[0] * m[6] * m[15] +
m[0] * m[7] * m[14] +
m[4] * m[2] * m[15] -
m[4] * m[3] * m[14] -
m[12] * m[2] * m[7] +
m[12] * m[3] * m[6];

inv[10] = m[0] * m[5] * m[15] -
m[0] * m[7] * m[13] -
m[4] * m[1] * m[15] +
m[4] * m[3] * m[13] +
m[12] * m[1] * m[7] -
m[12] * m[3] * m[5];

inv[14] = -m[0] * m[5] * m[14] +
m[0] * m[6] * m[13] +
m[4] * m[1] * m[14] -
m[4] * m[2] * m[13] -
m[12] * m[1] * m[6] +
m[12] * m[2] * m[5];

inv[3] = -m[1] * m[6] * m[11] +
m[1] * m[7] * m[10] +
m[5] * m[2] * m[11] -
m[5] * m[3] * m[10] -
m[9] * m[2] * m[7] +
m[9] * m[3] * m[6];

inv[7] = m[0] * m[6] * m[11] -
m[0] * m[7] * m[10] -
m[4] * m[2] * m[11] +
m[4] * m[3] * m[10] +
m[8] * m[2] * m[7] -
m[8] * m[3] * m[6];

inv[11] = -m[0] * m[5] * m[11] +
m[0] * m[7] * m[9] +
m[4] * m[1] * m[11] -
m[4] * m[3] * m[9] -
m[8] * m[1] * m[7] +
m[8] * m[3] * m[5];

inv[15] = m[0] * m[5] * m[10] -
m[0] * m[6] * m[9] -
m[4] * m[1] * m[10] +
m[4] * m[2] * m[9] +
m[8] * m[1] * m[6] -
m[8] * m[2] * m[5];

det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];

if (det == 0)
return false;

det = 1.0 / det;

for (i = 0; i < 16; i++)
this->matrix[i] = inv[i] * det;

return true;
}

} // namespace facebook::react
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ struct Transform {
*/
static Transform Skew(Float x, Float y);

bool inv();

/*
* Returns a transform that rotates by `angle` radians along the given axis.
*/
Expand Down Expand Up @@ -189,6 +191,10 @@ struct Transform {

Rect applyWithCenter(const Rect& rect, const Point& center) const;

Point applyWithRect(const Point& point, const Rect& rect) const;

Point applyWithCenter(const Point& point, const Point& center) const;

/**
* Convert to folly::dynamic.
*/
Expand Down
Loading