hitTestNode function
Returns true if point hits node in scene coordinates.
Implementation
bool hitTestNode(Offset point, SceneNode node) {
if (!node.isVisible || !node.isSelectable) return false;
switch (node.type) {
case NodeType.image:
case NodeType.text:
case NodeType.rect:
final inverse = node.transform.invert();
if (inverse == null) {
return hitTestRect(point, node.boundsWorld);
}
final localPoint = inverse.applyToPoint(point);
final paddingScene = node.hitPadding + kHitSlop;
final paddingX =
paddingScene *
math.sqrt(inverse.a * inverse.a + inverse.c * inverse.c);
final paddingY =
paddingScene *
math.sqrt(inverse.b * inverse.b + inverse.d * inverse.d);
final bounds = node.localBounds;
return Rect.fromLTRB(
bounds.left - paddingX,
bounds.top - paddingY,
bounds.right + paddingX,
bounds.bottom + paddingY,
).contains(localPoint);
case NodeType.path:
final pathNode = node as PathNode;
if (pathNode.fillColor != null) {
final padding = pathNode.hitPadding + kHitSlop;
if (!pathNode.boundsWorld.inflate(padding).contains(point)) {
return false;
}
final localPath = pathNode.buildLocalPath();
if (localPath == null) return false;
final inverse = pathNode.transform.invert();
if (inverse == null) return false;
final localPoint = inverse.applyToPoint(point);
return localPath.contains(localPoint);
}
if (pathNode.strokeColor != null) {
final effectiveStrokeWidth =
pathNode.strokeWidth * _maxAxisScaleAbs(pathNode.transform);
final padding =
effectiveStrokeWidth / 2 + pathNode.hitPadding + kHitSlop;
return pathNode.boundsWorld.inflate(padding).contains(point);
}
return false;
case NodeType.line:
final line = node as LineNode;
final inverse = line.transform.invert();
if (inverse == null) return false;
final localPoint = inverse.applyToPoint(point);
return hitTestLine(localPoint, line.start, line.end, line.thickness);
case NodeType.stroke:
final stroke = node as StrokeNode;
final inverse = stroke.transform.invert();
if (inverse == null) return false;
final localPoint = inverse.applyToPoint(point);
return hitTestStroke(
localPoint,
stroke.points,
stroke.thickness,
hitPadding: stroke.hitPadding,
);
}
}