import { HStack, Navigation, NavigationStack, Path2D, PathShape, Rectangle, Script, ScrollView, Text, useState, VStack } from "scripting"
// 一个可复用的三角形(绝对坐标),演示构建 + 几何查询 + clip。
const triangle = new Path2D(p => {
p.move({ x: 150, y: 20 })
p.addLine({ x: 20, y: 260 })
p.addLine({ x: 280, y: 260 })
p.closeSubpath()
})
function Example() {
const [probeInside, setProbeInside] = useState(false)
const rect = triangle.boundingRect()
return <NavigationStack>
<ScrollView>
<VStack
navigationTitle={"Path2D"}
navigationBarTitleDisplayMode={"inline"}
spacing={28}
padding
>
<Text font={"caption"} foregroundStyle={"secondaryLabel"}>
{`\`Path2D\` mirrors SwiftUI's \`Path\`: build it with line / curve commands, then render it
with \`<PathShape>\` (fill / stroke / modifiers), query its geometry, or use it as a clip
shape. Points are {"{ x, y }"}, angles are radians.`}
</Text>
{/* 1. Static path: fill + stroke */}
<VStack alignment={"leading"} spacing={8}>
<Text font={"headline"}>1. Build + fill / stroke</Text>
<PathShape
path={triangle}
fill={"systemOrange"}
stroke={{ shapeStyle: "label", strokeStyle: { lineWidth: 3 } }}
frame={{ width: 300, height: 280 }}
/>
</VStack>
{/* 2. Curves */}
<VStack alignment={"leading"} spacing={8}>
<Text font={"headline"}>2. Quadratic + cubic curves</Text>
<PathShape
fill={"systemPink"}
frame={{ width: 300, height: 220 }}
draw={(p, size) => {
p.move({ x: size.width / 2, y: 30 })
p.addCurve(
{ x: size.width / 2, y: size.height - 20 },
{ x: 0, y: size.height * 0.6 },
{ x: size.width * 0.3, y: size.height },
)
p.addCurve(
{ x: size.width / 2, y: 30 },
{ x: size.width * 0.7, y: size.height },
{ x: size.width, y: size.height * 0.6 },
)
}}
/>
</VStack>
{/* 3. Arc + rounded rect, stroked */}
<VStack alignment={"leading"} spacing={8}>
<Text font={"headline"}>3. Arc + rounded rect</Text>
<PathShape
stroke={{ shapeStyle: "systemBlue", strokeStyle: { lineWidth: 4 } }}
frame={{ width: 300, height: 160 }}
draw={(p) => {
p.addRoundedRect({ rect: { x: 20, y: 20, width: 120, height: 120 }, cornerRadius: 24 })
p.addArc({ center: { x: 230, y: 80 }, radius: 55, startAngle: 0, endAngle: Math.PI * 1.5 })
}}
/>
</VStack>
{/* 4. Geometry query */}
<VStack alignment={"leading"} spacing={8}>
<Text font={"headline"}>4. Geometry</Text>
<Text font={"caption"} foregroundStyle={"secondaryLabel"}>
boundingRect = {"{"} x: {rect.x.toFixed(0)}, y: {rect.y.toFixed(0)}, w:{" "}
{rect.width.toFixed(0)}, h: {rect.height.toFixed(0)} {"}"}
</Text>
<HStack spacing={12}>
<Text>contains (150, 200): {String(triangle.contains({ x: 150, y: 200 }))}</Text>
</HStack>
<Text>contains (10, 10): {String(triangle.contains({ x: 10, y: 10 }))}</Text>
</VStack>
{/* 5. As a clip shape */}
<VStack alignment={"leading"} spacing={8}>
<Text font={"headline"}>5. clipShape</Text>
<Rectangle
fill={"systemTeal"}
frame={{ width: 300, height: 280 }}
clipShape={triangle}
/>
</VStack>
</VStack>
</ScrollView>
</NavigationStack>
}
async function run() {
await Navigation.present({ element: <Example /> })
Script.exit()
}
run()