Skip to content

Instantly share code, notes, and snippets.

@Mun0n
Created March 20, 2020 17:16
Show Gist options
  • Save Mun0n/f370a85d1bac1d043b27e5846e7f925b to your computer and use it in GitHub Desktop.
Save Mun0n/f370a85d1bac1d043b27e5846e7f925b to your computer and use it in GitHub Desktop.
Custom edge treatment to create a circle edge in a shape
import com.google.android.material.shape.EdgeTreatment
import com.google.android.material.shape.ShapePath
import kotlin.math.atan
import kotlin.math.sqrt
class CircleEdgeTreatment
(
private val radius: Float,
private val cradleRoundedCornerRadius: Float
) :
EdgeTreatment() {
override fun getEdgePath(
length: Float,
center: Float,
interpolation: Float,
shapePath: ShapePath
) {
val roundedCornerOffset = interpolation * this.cradleRoundedCornerRadius
val middle = length / 2.0f
val verticalOffset = (1.0f - interpolation) * radius
val verticalOffsetRatio = verticalOffset / radius
if (verticalOffsetRatio >= 1.0f) {
shapePath.lineTo(length, 0.0f)
} else {
val distanceBetweenCenters = radius + roundedCornerOffset
val distanceBetweenCentersSquared = distanceBetweenCenters * distanceBetweenCenters
val distanceY = verticalOffset + roundedCornerOffset
val distanceX =
sqrt((distanceBetweenCentersSquared - distanceY * distanceY).toDouble()).toFloat()
val leftRoundedCornerCircleX = middle - distanceX
val rightRoundedCornerCircleX = middle + distanceX
val cornerRadiusArcLength =
Math.toDegrees(atan((distanceX / distanceY).toDouble())).toFloat()
val cutoutArcOffset = 90.0f - cornerRadiusArcLength
shapePath.lineTo(leftRoundedCornerCircleX - roundedCornerOffset, 0.0f)
shapePath.addArc(
leftRoundedCornerCircleX - roundedCornerOffset,
0.0f,
leftRoundedCornerCircleX + roundedCornerOffset,
roundedCornerOffset * 2.0f,
270.0f,
cornerRadiusArcLength
)
shapePath.addArc(
middle - radius,
-radius - verticalOffset,
middle + radius,
radius - verticalOffset,
180.0f - cutoutArcOffset,
cutoutArcOffset * 2.0f - 180.0f
)
shapePath.addArc(
rightRoundedCornerCircleX - roundedCornerOffset,
0.0f,
rightRoundedCornerCircleX + roundedCornerOffset,
roundedCornerOffset * 2.0f,
270.0f - cornerRadiusArcLength,
cornerRadiusArcLength
)
shapePath.lineTo(length, 0.0f)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment