Recently, I've been working on a framework that mimics Flutter using JavaScript. While fully replicating the original is beyond my current abilities, I'm giving it my best effort to emulate it closely. As part of this process, I plan to document the layout rules of Flutter widgets in a series of articles, aiming to publish one each week.
ClipPath
The ClipPath widget takes a clipper argument to cut the screen into various shapes. The clipper’s getClip method receives the size of the widget as its parameter. An example is shown where a square is clipped into a triangle.
ClipPath applies cutting based on the clipBehavior parameter, which includes none, hardEdge, antiAlias, and antiAliasWithSaveLayer. With none, the clipper has no effect. From hardEdge onwards, the cutting appears to be more precise, though the differences are subtle.
Comments on Flutter
ClipPath is a RenderObjectWidget, primarily focusing on clipping. The hitTest and paint methods prominently feature the clip, derived from the clipper’s getClip
ClipPath의 clip 타입은 Path이다. Path 코드를 보면 아래와 같다.
함수 구현부분은 플랫폼별로 빌드할 때 생성되는 듯 보인다.
아래에 addRect, addOval, addRRect는 moveTo, lineTo, artToPoint, close의 조합으로 구현 가능해 보인다. 그러나 flutter는 이부분도 native 빌드할때 생성하는걸로 남겨두었다.
Similar to ClipPath, ClipRect changes its generic type from Path to Rect but functions in the same manner.
The Rect class offers various factory constructors like fromLTRB, fromLTWH, fromCircle, and fromCenter to create a rectangle. The contains method, unlike in Path, is not part of a native build.
ClipRect, also a RenderObjectWidget, distinguishes itself from ClipPath by having a separate widget implementation, even though the hitTest and paint methods utilize the rectangle directly.
ClipOval
ClipOval operates similarly to ClipRect, with its clipper type remaining unchanged. It's another RenderObjectWidget where hitTest is uniquely implemented, and paint leverages a Path obtained through a specific method, suggesting optimization reasons behind Flutter's choice to implement these as separate widgets.
Conclusion
The purpose of this code analysis was to decide whether to implement ClipOval, ClipRect, and ClipRRect in Flitter as separate RenderObjectWidgets like Flutter, or to reuse ClipPath. The speculation is that Flutter's separate implementations for these widgets might be for optimization related to hit testing. The reasoning is that calculating containment within a Path might be more computationally intensive compared to the direct implementations in RenderClipRect or RenderClipOval. Ultimately, since SVG is used and hit testing doesn't need to be implemented manually, and there's no significant performance concern between using <rect/> and <path/>, it was decided to implement ClipRect, ClipOval, and ClipRRect using ClipPath.