Welcome π
In this article, weβll create a dynamic DNA Helix animation with Jetpack Compose in just 5 minutes βοΈ
Stay tuned, and letβs dive in! π
The Function
Letβs start by defining the DNAHelix
composable function and exploring its parameters for customization:
@Composable
fun DNAHelix(
modifier: Modifier,
firstColor: Color,
secondColor: Color,
pointSize: Dp = 5.dp,
lineWidth: Dp = 1.5.dp,
spacing: Dp = 10.dp,
shifting: Dp = 0.dp,
curvature: Float = 16f,
cycleDuration: Int = 3000,
lineBrush: (firstPoint: Offset, secondPoint: Offset) -> Brush = { fp, sp ->
Brush.linearGradient(
colors = listOf(firstColor, secondColor),
start = fp,
end = sp
)
}
)
Parameters:
𧬠modifier π Modifier to be applied to the Canvas.
𧬠firstColor π Color of the first set of points.
𧬠secondColor π Color of the second set of points.
𧬠pointSize π Diameter of the points.
𧬠lineWidth π Width of the lines connecting the points.
𧬠spacing π Distance between consecutive points.
𧬠shifting π Horizontal shift for the points. Allows distortion of the helix.
𧬠curvature π Curvature of the helix. Affects how often curls repeat.
𧬠cycleDuration π Duration of one animation cycle in milliseconds.
𧬠lineBrush π Function to define the brush for the lines. Default is a linear gradient from firstColor
to secondColor
Implementation
Coordinates Utility
Before implementing the logic, letβs define a utility function that calculates coordinates based on the current angle and point placement:
private fun calculateCoordinates(angle: Float, radius: Float, centerX: Float, centerY: Float): Offset {
val y = centerY + radius * sin(Math.toRadians(angle.toDouble())).toFloat()
return Offset(centerX, y)
}
Animation Handling
To create an infinite animation, we can use rememberInfiniteTransition()
along with animateFloat()
to animate the angle from 0
to 360
degrees:
val helixTransition = rememberInfiniteTransition()
val animatedAngle by helixTransition.animateFloat(
initialValue = 0f,
targetValue = 360f,
animationSpec = infiniteRepeatable(
animation = tween(durationMillis = cycleDuration, easing = LinearEasing),
repeatMode = RepeatMode.Restart
)
)
Drawing Logic
Finally, letβs draw the helix using the Canvas
:
Canvas(modifier) {
val spacingPx = spacing.toPx()
val pointsCount = (size.width / spacingPx).toInt()
val helixRadius = size.height / 2
val pointRadiusPx = pointSize.toPx() / 2
val lineWidthPx = lineWidth.toPx()
val shiftingPx = shifting.toPx()
// Loop through each point to draw the helix
for (i in 1 until pointsCount) {
// Calculate the current angle for the helix animation
val currentAngle = (animatedAngle + i * curvature) % 360
// Calculate the x offset for the current point
val xOffset = i * spacingPx
// Calculate the coordinates of the first point
val firstPoint = calculateCoordinates(currentAngle, helixRadius, xOffset - shiftingPx, helixRadius)
// Calculate the coordinates of the second point (180 degrees apart)
val secondPoint = calculateCoordinates(currentAngle + 180, helixRadius, xOffset + shiftingPx, helixRadius)
// Draw the line connecting the two points
drawLine(
brush = lineBrush(firstPoint, secondPoint),
strokeWidth = lineWidthPx,
start = firstPoint,
end = secondPoint
)
// Draw the first point
drawCircle(
color = firstColor,
radius = pointRadiusPx,
center = firstPoint
)
// Draw the second point
drawCircle(
color = secondColor,
radius = pointRadiusPx,
center = secondPoint
)
}
}
Congratulations π₯³! Weβve successfully built it π. For the complete code implementation, you can access it on GitHub Gist π§βπ». Now, letβs explore how we can put it to use.
Are you learning a foreign language and struggling with new vocabulary?
Then, I strongly recommend you check out this words-learning application, which will make your journey easy and convenient!
Usage πββοΈ
Letβs explore different ways to use the DNAHelix
function:
Simple Helix
Create a basic helix with default settings:
DNAHelix(
firstColor = Color.Red,
secondColor = Color.Blue,
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
)
White Lines
Customize the lines to be white instead of a gradient:
DNAHelix(
firstColor = Color.Red,
secondColor = Color.Blue,
lineBrush = { _, _ ->
SolidColor(Color.White)
},
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
)
Distortions
Apply horizontal shifting
and adjust curvature
for a distorted helix:
DNAHelix(
firstColor = Color.Red,
secondColor = Color.Blue,
shifting = 10.dp,
curvature = 12f,
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.rotate(-15f)
)
You might also like π
Thank you for reading this article! β€οΈ If you found it enjoyable and valuable, show your appreciation by clapping π and following Kappdev for more exciting articles π
Consider subscribing to my email notifications π to stay updated with my latest content.
Happy coding!