Homepage Change Log 06: Implementation Options for the Photography Aperture
The aperture went through overlay lines, SVG blades, clip-path sectors, and finally geometry-based insets. The stable version puts the gap inside the photo blade itself.
The final photography aperture looks like a set of photo sectors around a central aperture glyph. Getting there required trying several structures, each with a different failure mode.
The important lesson was not that one CSS feature is magic. The implementation has to match the future animation.
Option One: A Photo Disc with Overlay Separators
The most direct version was:
<div className="rounded-full overflow-hidden">
<PhotoSectors />
<SectorGuideLines />
</div>Each photo was clipped with clip-path: polygon(...), and the separators were drawn in an SVG layer on top.
This was easy to implement, but the separators were not part of the photos. On hover, the photo blade moved while the separator stayed behind. Lowering the separator layer helped only partially. It did not remove the structural conflict.
That is why SectorGuideLines was eventually removed.
Option Two: Drawing the Center with Lines
The center aperture also started as a set of lines: outer circle, inner hexagon, and six strokes from one to the other.
It looked more like a diagram than a real aperture. The reference shape is not built from strokes. Each blade sits against the next, and the center opening appears because no blade covers that region.
Line-based drawing created heavy seams and a fake center fill. It also made opening and closing animation harder.
Option Three: Six SVG Blade Paths
The center became much better once it was split into six SVG paths. Each blade has an outer arc and an inner edge. The center opening is derived from the blade geometry.
This made animation possible: changing the center radius, outer angles, and blade offset can move the glyph from closed to open.
It also made theme color easier, because the aperture body, blades, center opening, and ring each have clear paint roles.
Option Four: Inset Photo Sectors
The last important change was doing the same thing to the photos. Instead of drawing separators, each photo sector gives up a little space on both sides.
The old call was effectively:
twistedSectorClipPolygon(..., sideInset = 0)The final call uses:
twistedSectorClipPolygon(..., sideInset = PHOTO_SECTOR_GAP_WIDTH / 2)The inset is not a random angle. Each side boundary is shifted inward by a fixed distance, then intersected back with the inner and outer circles. Adjacent sectors each give up half the gap, so the background becomes the separator.
When a photo blade floats, no separate line can cross it.
Why Not Just Shrink the Angles
Adding a tiny angle to the start and subtracting it from the end would also create a gap, but the visible width would vary with radius. Near the center it would be narrow. Near the outer circle it would be wider.
The final version uses a parallel offset instead. That keeps the seam closer to a fixed-width gap and matches the idea of moving the long edge inward by a small distance.
What Stayed
The final structure keeps two pieces of math:
- Center aperture: six SVG blade paths.
- Outer photos: six clipped sectors with inset side edges.
The fixed outer rim and SVG separator layer were removed. They looked helpful in a static state, but they worked against hover and loading animation.

