You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为自定义SlantedRectangle形状的左上及右上角落添加圆角?

实现带圆角的斜切矩形

你可以通过手动绘制圆角圆弧的方式,给左上和右上顶点添加圆角。以下是修改后的代码:

struct SlantedRectangle: Shape {
    var cornerRadius: CGFloat = 10 // 可自定义圆角半径
    
    // 支持动画
    var animatableData: CGFloat {
        get { cornerRadius }
        set { cornerRadius = newValue }
    }

    func path(in rect: CGRect) -> Path {
        Path { path in
            let rightTopVertex = CGPoint(x: rect.width, y: 30)
            // 计算斜线的长度(从左上(0,0)到右上顶点的距离)
            let upperEdgeLength = sqrt(rect.width * rect.width + 30 * 30)
            
            // 1. 移动到右边垂直边的圆角起点
            let rightVerticalStart = CGPoint(x: rect.width, y: rightTopVertex.y + cornerRadius)
            path.move(to: rightVerticalStart)
            
            // 2. 绘制右边垂直边到右下角
            path.addLine(to: CGPoint(x: rect.width, y: rect.height))
            
            // 3. 绘制下边水平边到左下角
            path.addLine(to: CGPoint(x: 0, y: rect.height))
            
            // 4. 绘制左边垂直边到左上圆角起点
            let leftVerticalEnd = CGPoint(x: 0, y: cornerRadius)
            path.addLine(to: leftVerticalEnd)
            
            // 5. 绘制左上圆角圆弧
            let leftArcCenter = CGPoint(x: cornerRadius, y: cornerRadius)
            path.addArc(center: leftArcCenter,
                        radius: cornerRadius,
                        startAngle: .degrees(180),
                        endAngle: .degrees(270),
                        clockwise: true)
            
            // 6. 绘制左上到右上的斜线,截去圆角部分
            let upperEdgeOffsetX = rect.width / upperEdgeLength * cornerRadius
            let upperEdgeOffsetY = 30 / upperEdgeLength * cornerRadius
            let upperRightArcStart = CGPoint(x: rightTopVertex.x - upperEdgeOffsetX, y: rightTopVertex.y - upperEdgeOffsetY)
            path.addLine(to: upperRightArcStart)
            
            // 7. 绘制右上圆角圆弧
            // 计算右上圆角的圆心:垂直于斜线方向偏移cornerRadius
            let normalDx = -30 / upperEdgeLength * cornerRadius
            let normalDy = rect.width / upperEdgeLength * cornerRadius
            let rightArcCenter = CGPoint(x: rightTopVertex.x + normalDx, y: rightTopVertex.y + normalDy)
            // 计算圆弧的起始和结束角度
            let startAngle = atan2(upperRightArcStart.y - rightArcCenter.y, upperRightArcStart.x - rightArcCenter.x)
            let endAngle = atan2(rightVerticalStart.y - rightArcCenter.y, rightVerticalStart.x - rightArcCenter.x)
            path.addArc(center: rightArcCenter,
                        radius: cornerRadius,
                        startAngle: startAngle,
                        endAngle: endAngle,
                        clockwise: true)
        }
    }
}

关键步骤说明:

  • 添加了cornerRadius属性,方便你调整圆角大小,同时实现了animatableData支持动画效果。
  • 左上圆角:因为左边是垂直边,上边是斜线,直接以(cornerRadius, cornerRadius)为圆心绘制圆弧,连接左边垂直边的终点和斜线的起点。
  • 右上圆角:先计算斜线和右边垂直边的截点,再通过垂直于斜线的方向确定圆弧圆心,最后绘制圆弧连接两个截点,保证圆角与两条边平滑衔接。
  • 所有路径段依次连接,自动闭合形成完整形状。

内容的提问来源于stack exchange,提问作者Trevor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 22:40:34