Skip to content

Commit

Permalink
Support rotation3DEffect
Browse files Browse the repository at this point in the history
  • Loading branch information
aabewhite committed Nov 14, 2024
1 parent 22fda64 commit 33b0455
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 2 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1471,6 +1471,17 @@ Support levels:
</details>
</td>
</tr>
<tr>
<td>🟢</td>
<td>
<details>
<summary><code>.rotation3DEffect</code></summary>
<ul>
<li><code>func rotation3DEffect(_ angle: Angle, axis: (x: CGFloat, y: CGFloat, z: CGFloat), perspective: CGFloat = 1.0) -> some View</code></li>
</ul>
</details>
</td>
</tr>
<tr>
<td>🟢</td>
<td>
Expand Down
2 changes: 1 addition & 1 deletion Sources/SkipUI/SkipUI/Layout/Presentation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ let overlayPresentationCornerRadius = 16.0
// Draw the drag handle and the presentation root content area below it
androidx.compose.foundation.layout.Spacer(modifier: Modifier.height(inset - handleHeight - handlePadding))
Row(modifier: Modifier.fillMaxWidth(), horizontalArrangement: Arrangement.Center) {
Capsule().fill(Color.primary.opacity(0.2)).frame(width: 60.0, height: Double(handleHeight.value)).Compose(context: context)
Capsule().fill(Color.primary.opacity(0.4)).frame(width: 60.0, height: Double(handleHeight.value)).Compose(context: context)
}
androidx.compose.foundation.layout.Spacer(modifier: Modifier.height(handlePadding))
} else if !isEdgeToEdge {
Expand Down
27 changes: 26 additions & 1 deletion Sources/SkipUI/SkipUI/View/View.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.draw.scale
import androidx.compose.ui.graphics.TransformOrigin
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
#elseif canImport(CoreGraphics)
Expand Down Expand Up @@ -917,9 +919,32 @@ extension View {
#endif
}

@available(*, unavailable)
public func rotation3DEffect(_ angle: Angle, axis: (x: CGFloat, y: CGFloat, z: CGFloat), anchor: UnitPoint = .center, anchorZ: CGFloat = 0.0, perspective: CGFloat = 1.0) -> some View {
#if SKIP
return ComposeModifierView(targetView: self) { context in
let animatable = Float(angle.degrees).asAnimatable(context: context)
// Try to approximate SwiftUI's perspective adaptation to view size
let size = remember { mutableStateOf(IntSize.Zero) }
let dimension = max(size.value.width * axis.y, size.value.height * axis.x)
let distance = max(Float(0.1), Float(dimension / 65)) / Float(perspective)
context.modifier = context.modifier
.onGloballyPositioned { size.value = $0.size }
.graphicsLayer(
transformOrigin: TransformOrigin(pivotFractionX: Float(anchor.x), pivotFractionY: Float(anchor.y)),
rotationX: Float(axis.x) * animatable.value,
rotationY: Float(axis.y) * animatable.value,
rotationZ: Float(axis.z) * animatable.value,
cameraDistance: distance
)
return ComposeResult.ok
}
#else
return self
#endif
}

public func rotation3DEffect(_ angle: Angle, axis: (x: Int, y: Int, z: Int), perspective: CGFloat = 1.0) -> some View {
return rotation3DEffect(angle, axis: (CGFloat(axis.x), CGFloat(axis.y), CGFloat(axis.z)), perspective: perspective)
}

@available(*, unavailable)
Expand Down

0 comments on commit 33b0455

Please sign in to comment.