Closed ZacSweers closed 9 months ago
Thank you for adjusting the library with Jetpack Compose.
I have the same request, could you pls give us the onclick event for this area(outside the target area), then the developer can decide to close the helping hand with onclick in this area or not !
Thank you in advance for taking care. cp-radhika-s Jimmy Sanghani Jan Bína
Best, Sepi
cp-radhika-s Jimmy Sanghani Jan Bína
If you just add the .clickable { onShowcaseCompleted() }
inside the TargetContent
function, it will fix the problem
Look :
@Composable
fun TargetContent(
target: IntroShowcaseTargets,
modifier: Modifier = Modifier,
onShowcaseCompleted: () -> Unit,
) {
val screenHeight = LocalConfiguration.current.screenHeightDp
val targetCords = target.coordinates
val gutterArea = 88.dp
val targetRect = targetCords.boundsInRoot()
val yOffset = with(LocalDensity.current) {
targetCords.positionInRoot().y.toDp()
}
val isTargetInGutter = gutterArea > yOffset || yOffset > screenHeight.dp.minus(gutterArea)
val maxDimension =
max(targetCords.size.width.absoluteValue, targetCords.size.height.absoluteValue)
val targetRadius = maxDimension / 2f + 40f
val animationSpec = infiniteRepeatable<Float>(
animation = tween(2000, easing = FastOutLinearInEasing),
repeatMode = RepeatMode.Restart,
)
var outerOffset by remember {
mutableStateOf(Offset(0f, 0f))
}
var outerRadius by remember {
mutableStateOf(0f)
}
val outerAnimatable = remember { Animatable(0.6f) }
val animatables = listOf(
remember { Animatable(0f) },
remember { Animatable(0f) }
)
LaunchedEffect(target) {
outerAnimatable.snapTo(0.6f)
outerAnimatable.animateTo(
targetValue = 1f,
animationSpec = tween(
durationMillis = 500,
easing = FastOutSlowInEasing,
),
)
}
animatables.forEachIndexed { index, animatable ->
LaunchedEffect(animatable) {
delay(index * 1000L)
animatable.animateTo(
targetValue = 1f, animationSpec = animationSpec
)
}
}
val dys = animatables.map { it.value }
Box {
Canvas(
modifier = modifier
.fillMaxSize()
.pointerInput(target) {
detectTapGestures { tapOffeset ->
if (targetRect.contains(tapOffeset)) {
onShowcaseCompleted()
}
}
}
.clickable { onShowcaseCompleted() }
.graphicsLayer(alpha = 0.99f)
) {
drawCircle(
color = target.style.backgroundColor,
center = outerOffset,
radius = outerRadius * outerAnimatable.value,
alpha = target.style.backgroundAlpha
)
dys.forEach { dy ->
drawCircle(
color = target.style.targetCircleColor,
radius = maxDimension * dy * 2f,
center = targetRect.center,
alpha = 1 - dy
)
}
drawCircle(
color = target.style.targetCircleColor,
radius = targetRadius,
center = targetRect.center,
blendMode = BlendMode.Xor
)
}
ShowCaseText(target, targetRect, targetRadius) { textCoords ->
val contentRect = textCoords.boundsInParent()
val outerRect = getOuterRect(contentRect, targetRect, isTargetInGutter)
val possibleOffset = getOuterCircleCenter(targetRect, contentRect, targetRadius)
outerOffset = if (isTargetInGutter) {
outerRect.center
} else {
possibleOffset
}
outerRadius = getOuterRadius(outerRect) + targetRadius
}
}
}
Alternatively, expose a method on IntroShowCaseState
for incrementing currentTargetIndex
. Something like this:
class IntroShowCaseState internal constructor(
initialIndex: Int,
) {
internal var targets = mutableStateMapOf<Int, IntroShowcaseTargets>()
var currentTargetIndex by mutableStateOf(initialIndex)
internal set
val currentTarget: IntroShowcaseTargets?
get() = targets[currentTargetIndex]
/* NEW METHOD */
fun onShowcaseStepCompleted() {
if (currentTarget != null) {
currentTargetIndex++
}
}
}
Closing this issue since this has been fixed in version 2.0.0. Thanks for reporting this issue!
Currently this library only dismisses targets if the user clicks the exact target space, but this isn't normal behavior when the target being showcased isn't normally clickable. It would be ideal if the library allowed dismissal of targets when tapping outside of the target area.