Skip to content

Instantly share code, notes, and snippets.

@WonderJeffy
Created March 28, 2025 06:26
Show Gist options
  • Save WonderJeffy/2403fc80d2c6b8ab15c10d3754792209 to your computer and use it in GitHub Desktop.
Save WonderJeffy/2403fc80d2c6b8ab15c10d3754792209 to your computer and use it in GitHub Desktop.
SwiftUI 绘制圆角三角
struct RoundedEquilateralTriangle: Shape {
var sideLength: CGFloat
var leftRadius: CGFloat
var topRadius: CGFloat
var rightRadius: CGFloat
func path(in rect: CGRect) -> Path {
var path = Path()
let height = sideLength * sqrt(3) / 2 // 等边三角形的高
// 计算三角形的中心点
let center = CGPoint(x: rect.width / 2, y: rect.height / 2)
// 计算三个顶点坐标(相对于中心点)
let topPoint = CGPoint(x: center.x, y: center.y - 2 * height / 3)
let bottomLeftPoint = CGPoint(x: center.x - sideLength / 2, y: center.y + height / 3)
let bottomRightPoint = CGPoint(x: center.x + sideLength / 2, y: center.y + height / 3)
// 计算每个圆角的起始和结束点
let topCornerStart = pointAlongLine(from: bottomLeftPoint, to: topPoint, distance: leftRadius)
let topCornerEnd = pointAlongLine(from: bottomRightPoint, to: topPoint, distance: topRadius)
let leftCornerStart = pointAlongLine(from: topPoint, to: bottomLeftPoint, distance: leftRadius)
let leftCornerEnd = pointAlongLine(from: bottomRightPoint, to: bottomLeftPoint, distance: rightRadius)
let rightCornerStart = pointAlongLine(from: bottomLeftPoint, to: bottomRightPoint, distance: rightRadius)
let rightCornerEnd = pointAlongLine(from: topPoint, to: bottomRightPoint, distance: topRadius)
// 绘制路径
path.move(to: topCornerStart)
path.addLine(to: leftCornerStart)
path.addArc(tangent1End: bottomLeftPoint, tangent2End: leftCornerEnd, radius: leftRadius)
path.addLine(to: rightCornerStart)
path.addArc(tangent1End: bottomRightPoint, tangent2End: rightCornerEnd, radius: rightRadius)
path.addLine(to: topCornerEnd)
path.addArc(tangent1End: topPoint, tangent2End: topCornerStart, radius: topRadius)
path.closeSubpath()
return path
}
// 计算从一点沿线段方向前进指定距离的点
private func pointAlongLine(from: CGPoint, to: CGPoint, distance: CGFloat) -> CGPoint {
let totalDistance = sqrt(pow(to.x - from.x, 2) + pow(to.y - from.y, 2))
let ratio = distance / totalDistance
let x = from.x + ratio * (to.x - from.x)
let y = from.y + ratio * (to.y - from.y)
return CGPoint(x: x, y: y)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment