feat: support outerBorder / innerBorder for polygon graphic - #2103
Conversation
39d02f3 to
e31507c
Compare
xuefei1313
left a comment
There was a problem hiding this comment.
发现 3 个需要修正的边界条件,均已附在对应行:缩放下 AABB 与实际边框坐标不一致、凹角圆角偏移方向错误,以及重复顶点在圆角分支中仍会产生 NaN。
| strokeBoundsBuffer = defaultOuterBorder.strokeBoundsBuffer | ||
| } = outerBorder; | ||
|
|
||
| offsetPolygonPoints(points, distance as number, closePath).forEach(point => { |
There was a problem hiding this comment.
[P1] 这里的 AABB 没有和实际绘制使用同一坐标空间。keepStrokeScale 默认为 false 时,渲染端会用 getScaledStroke 将 distance 转为局部坐标;例如 scaleX = scaleY = 0.5、distance = 10 时,绘制的局部偏移是 20(屏幕上仍是 10),但这里仅偏移 10,随后再被矩阵缩小为屏幕上的 5。增量重绘会因此漏清/裁掉外边框。请在这里使用等价的局部缩放距离(或在变换后的坐标中合并边界),并覆盖缩小变换的回归测试。
| if (noCorner) { | ||
| drawPolygon(context.camera ? context : context.nativeContext, nextPoints, x, y); | ||
| } else { | ||
| drawRoundedPolygon( |
There was a problem hiding this comment.
[P1] offsetPolygonPoints 虽然让重复顶点的结果保持有限值,但圆角分支仍会把重复点传给 drawRoundedPolygon。现有 duplicate-edge 测试的输入只要再设置 cornerRadius: 2,该函数就在该顶点得到 length2 = 0,随后 getProportionPoint 发生 0 / 0 并将 NaN 写入 lineTo/arcTo。Polygon 目前接受重复顶点,请在圆角绘制前收敛退化边,或让 drawRoundedPolygon 跳过零长度边,并补充实际 border-render 回归测试。
e31507c to
c543c0f
Compare
xuefei1313
left a comment
There was a problem hiding this comment.
上轮提出的凹角圆角、重复顶点和图元自身缩放场景均已处理;但非缩放边框在父级缩放下的 AABB 仍会漏算,需修正后再合入。
Add equidistant polygon border outlines and register the polygon render contribution. Handle transformed bounds, open paths, convex and concave rounded corners, and degenerate or duplicate edges without emitting non-finite coordinates. Add focused geometry, bounds, and render regression coverage.
c543c0f to
7fb3d28
Compare
xuefei1313
left a comment
There was a problem hiding this comment.
发现两处需要在合并前修复的问题:动态修改 outerBorder 后的边界失效,以及 keepStrokeScale 未传递给边框线宽。详情见行内评论。
xuefei1313
left a comment
There was a problem hiding this comment.
已复核修复:state patch 触发 Polygon 外边框 bounds 失效,且边框绘制与 bounds 均遵循 keepStrokeScale。已补充回归用例,并通过全包测试。
Closes #2102
What
outerBorder/innerBorderare implemented per graphic type in the render contributions. rect / arc / circle / symbol have them;polygon-contribution-render.tsonly re-exports texture and background, so configuringouterBorderon a polygon silently renders nothing.This adds the polygon implementation.
How
common/polygon.ts—offsetPolygonPoints(points, distance)Offsets every edge along its normal and intersects adjacent offset lines to get an equidistant outline. The polygon's signed area decides the normal direction, so a positive
distancealways expands outwards regardless of vertex winding;innerBorderpasses a negative distance. Degenerate (zero-length) and collinear edges fall back to the original vertex, so noNaNcoordinate can reach the path.polygon-contribution-render.ts—DefaultPolygonRenderContributionMirrors the rect contribution:
afterFillStroke, honourskeepStrokeScale/getScaledStroke, supportsstrokeCb. Corner radius is shifted by the same distance (max(0, cornerRadius ± d)) so the border stays equidistant from the outline instead of drifting at the corners. Registered inDefaultCanvasPolygonRender.builtinContributions.It also reproduces rect's
opacityinject/restore aroundsetStrokeStyle— the theme defaults forouterBordercarrystrokeOpacitybut noopacity, and without the injectionsetStrokeStylebails out silently and the border is stroked with leftover canvas state. See the issue for details.graphic/polygon.tsupdatePolygonAABBBoundsImprecisenow callsupdateBoundsOfCommonOuterBorder, same as rect — otherwise the border sits outside the AABB and the dirty rect clips it on incremental repaints.Verification
Verified against the equivalent change backported into
1.1.5and running in our product (funnel charts in VChart, both the funnel body and the conversion bands are polygons):outerBorderrenders as a closed ring equidistant from the trapezoid, following the rounded corners;innerBorderrenders on the inside;strokeis untouched (which was the whole point — writingstrokedirectly would overwrite it);No behaviour change for polygons that don't configure a border: the contribution returns immediately when neither
outerBordernorinnerBorderis set.