### Instagram-Style Snap Back Zoomable Image Source: https://context7.com/usuiat/zoomable/llms.txt Applies a 'snap back' zoom effect to a local drawable image, similar to Instagram's zoom behavior. The `snapBackZoomable` modifier allows pinch-to-zoom, but the image automatically animates back to its original size when the finger is lifted. It also includes example callbacks for tap and long-press gestures. ```kotlin import net.engawapg.lib.zoomable.rememberZoomState import net.engawapg.lib.zoomable.snapBackZoomable @Composable fun SnapBackZoomImage() { val painter = painterResource(resource = R.drawable.photo) val zoomState = rememberZoomState(contentSize = painter.intrinsicSize) Image( painter = painter, contentDescription = "Snap back zoomable image", contentScale = ContentScale.Fit, modifier = Modifier .fillMaxSize() .snapBackZoomable( zoomState = zoomState, zoomEnabled = true, onTap = { position -> println("Tapped at $position") }, onLongPress = { position -> println("Long pressed at $position") } ) ) } // Result: Pinch to zoom, but automatically animates back to 1.0x when finger lifts // One-finger zoom and mouse wheel are disabled for snap back mode ``` -------------------------------- ### Zoomable with HorizontalScroll (Kotlin) Source: https://github.com/usuiat/zoomable/blob/main/README.md This example shows how to combine the zoomable modifier with horizontal scrolling. The zoomable modifier should be positioned before the horizontalScroll modifier in the modifier chain to ensure correct behavior. It allows zooming of a horizontally scrolling component. ```Kotlin Column( modifier = Modifier .fillMaxSize() .zoomableWithScroll(rememberZoomState()) .horizontalScroll(rememberScrollState()) ) { repeat(100) { Text("Item $it") } } ``` -------------------------------- ### ZoomState Creation and Management Source: https://context7.com/usuiat/zoomable/llms.txt Explains how to create and manage `ZoomState` for controlling zoom behavior, including default and advanced configurations. ```APIDOC ## ZoomState Creation and Management ### Description Provides methods to create and configure `ZoomState`, which holds the current zoom level, pan position, and animation properties. It persists state across recompositions. ### Method `rememberZoomState()` function ### Endpoint N/A ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```kotlin import androidx.compose.animation.core.exponentialDecay import androidx.compose.runtime.Composable import androidx.compose.ui.geometry.Size import net.engawapg.lib.zoomable.ZoomState import net.engawapg.lib.zoomable.rememberZoomState @Composable fun CreateZoomState() { // Basic zoom state with defaults val basicZoomState = rememberZoomState() // Advanced zoom state with custom configuration val advancedZoomState = rememberZoomState( maxScale = 10f, // Maximum zoom level (default: 5f) contentSize = Size(1920f, 1080f), // Content dimensions in pixels velocityDecay = exponentialDecay(), // Fling animation decay initialScale = 2f // Starting zoom level (default: 1f) ) // Access current state values val currentScale: Float = advancedZoomState.scale val currentOffsetX: Float = advancedZoomState.offsetX val currentOffsetY: Float = advancedZoomState.offsetY } ``` ### Response #### Success Response (200) N/A (This is a UI state management function, not an API endpoint) #### Response Example N/A ### Notes `ZoomState` is remembered across recompositions and survives configuration changes when using `rememberZoomState()`. ``` -------------------------------- ### Add Zoomable Library Dependency to Gradle Project (Groovy) Source: https://context7.com/usuiat/zoomable/llms.txt Instructions for adding the Zoomable library as a dependency in a project using Gradle with Groovy syntax. It shows how to configure repositories and declare the implementation dependency in the build.gradle file. ```gradle // build.gradle (Groovy) repositories { mavenCentral() } dependencies { implementation "net.engawapg.lib:zoomable:2.0.0" } ``` -------------------------------- ### Create and configure ZoomState for zoom control in Kotlin Source: https://context7.com/usuiat/zoomable/llms.txt Shows creation of ZoomState objects using rememberZoomState() with both default and custom configurations. Configures maxScale, contentSize, velocity decay animation, and initialScale properties. Demonstrates accessing current zoom and offset values, with state persistence across recompositions. ```kotlin import androidx.compose.animation.core.exponentialDecay import androidx.compose.runtime.Composable import androidx.compose.ui.geometry.Size import net.engawapg.lib.zoomable.ZoomState import net.engawapg.lib.zoomable.rememberZoomState @Composable fun CreateZoomState() { // Basic zoom state with defaults val basicZoomState = rememberZoomState() // Advanced zoom state with custom configuration val advancedZoomState = rememberZoomState( maxScale = 10f, // Maximum zoom level (default: 5f) contentSize = Size(1920f, 1080f), // Content dimensions in pixels velocityDecay = exponentialDecay(), // Fling animation decay initialScale = 2f // Starting zoom level (default: 1f) ) // Access current state values val currentScale: Float = advancedZoomState.scale val currentOffsetX: Float = advancedZoomState.offsetX val currentOffsetY: Float = advancedZoomState.offsetY } // ZoomState is remembered across recompositions and survives configuration changes // when using rememberZoomState(). The state persists zoom level and pan position. ``` -------------------------------- ### Load Remote Images with Coil and Zoomable Modifier Source: https://context7.com/usuiat/zoomable/llms.txt Demonstrates how to load remote images asynchronously using Coil's `AsyncImage` and apply the `zoomable` modifier for pinch-to-zoom functionality. It shows two approaches: using `rememberAsyncImagePainter` and directly within `AsyncImage` with `setContentSize` for accurate zoom bounds. ```kotlin import coil3.compose.AsyncImage import coil3.compose.rememberAsyncImagePainter import net.engawapg.lib.zoomable.rememberZoomState import net.engawapg.lib.zoomable.zoomable @Composable fun CoilAsyncImageZoomable() { // Using rememberAsyncImagePainter val painter = rememberAsyncImagePainter("https://example.com/image.jpg") val zoomState = rememberZoomState(contentSize = painter.intrinsicSize) Image( painter = painter, contentDescription = "Remote zoomable image", contentScale = ContentScale.Fit, modifier = Modifier .fillMaxSize() .zoomable(zoomState) ) // Using AsyncImage with setContentSize callback val zoomState2 = rememberZoomState() AsyncImage( model = "https://example.com/image.jpg", contentDescription = "Remote zoomable image", contentScale = ContentScale.Fit, onSuccess = { // Update zoom state with actual image dimensions zoomState2.setContentSize(state.painter.intrinsicSize) }, modifier = Modifier .fillMaxSize() .zoomable(zoomState2) ) } // setContentSize() optimizes offset bounds for the content dimensions ``` -------------------------------- ### Basic Zoomable Image with Kotlin Compose Source: https://github.com/usuiat/zoomable/blob/main/README.md Applies basic zoomability to an Image composable using Modifier.zoomable and rememberZoomState. It takes a painter and optionally a contentSize for offset optimization. Outputs a zoomable image; limited to single images without asynchronous loading. ```kotlin val painter = painterResource(id = R.drawable.penguin) val zoomState = rememberZoomState(contentSize = painter.intrinsicSize) Image( painter = painter, contentDescription = "Zoomable image", contentScale = ContentScale.Fit, modifier = Modifier .fillMaxSize() .zoomable(zoomState), ) ``` -------------------------------- ### Zoomable AsyncImage with Content Size Callback in Kotlin Source: https://github.com/usuiat/zoomable/blob/main/README.md Uses AsyncImage from Coil with zoomable modifier, setting contentSize on image load success. Takes a URL model as input and calls setContentSize in onSuccess. Produces a zoomable image; suitable for Coil's AsyncImage with manual size setting. ```kotlin val zoomState = rememberZoomState() AsyncImage( model = "https://example.com/image.jpg", contentDescription = "Zoomable image", contentScale = ContentScale.Fit, onSuccess = { state -> zoomState.setContentSize(state.painter.intrinsicSize) }, modifier = Modifier .fillMaxSize() .zoomable(zoomState), ) ``` -------------------------------- ### Add Zoomable Library Dependency to Gradle Project (Kotlin) Source: https://context7.com/usuiat/zoomable/llms.txt Instructions for adding the Zoomable library as a dependency in a Kotlin Multiplatform project using Gradle. It includes configuring repositories and declaring the implementation dependency in the build.gradle.kts file. ```gradle // build.gradle.kts repositories { mavenCentral() } dependencies { // For Kotlin Multiplatform projects implementation("net.engawapg.lib:zoomable:2.0.0") } // settings.gradle.kts dependencyResolutionManagement { repositories { mavenCentral() } } ``` -------------------------------- ### Zoomable Images in HorizontalPager Gallery Source: https://context7.com/usuiat/zoomable/llms.txt Implements a zoomable image gallery using Jetpack Compose's `HorizontalPager`. Each page displays a local drawable image, and the `zoomable` modifier is applied to enable pinch-to-zoom within each image. It also demonstrates `ScrollGesturePropagation.ContentEdge` to allow swiping to the next page only when the zoomed content reaches an edge. ```kotlin import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.rememberPagerState import net.engawapg.lib.zoomable.ScrollGesturePropagation import net.engawapg.lib.zoomable.rememberZoomState import net.engawapg.lib.zoomable.zoomable @Composable fun ZoomableImageGallery() { val images = listOf( R.drawable.image1, R.drawable.image2, R.drawable.image3 ) val pagerState = rememberPagerState { images.size } HorizontalPager( state = pagerState, modifier = Modifier.fillMaxSize() ) { page -> val painter = painterResource(resource = images[page]) val zoomState = rememberZoomState(contentSize = painter.intrinsicSize) Image( painter = painter, contentDescription = "Image $page", contentScale = ContentScale.Fit, modifier = Modifier .fillMaxSize() .zoomable( zoomState = zoomState, scrollGesturePropagation = ScrollGesturePropagation.ContentEdge // Swipe to next page only when zoomed content reaches edge ) ) } } // Each page maintains independent zoom state // ScrollGesturePropagation.NotZoomed: swipe to next page only when scale is 1.0f ``` -------------------------------- ### Simplest Zoomable Image in Kotlin Compose Source: https://github.com/usuiat/zoomable/blob/main/README.md Makes an Image composable zoomable with a single modifier line using rememberZoomState. Requires a painter resource as input. Produces a zoomable image with default gestures; no customizations or content size specified. ```kotlin Image( painter = painterResource(id = R.drawable.penguin), contentDescription = null, modifier = Modifier.zoomable(rememberZoomState()), ) ``` -------------------------------- ### Add Zoomable Dependency in Gradle Source: https://github.com/usuiat/zoomable/blob/main/README.md This Gradle script adds the Zoomable library as a dependency from Maven Central. It requires a repositories block with mavenCentral() and an implementation dependency specifying the library artifact and version. Ensure the version is up to date; no inputs or outputs beyond successful compilation. ```gradle repositories { mavenCentral() } dependencies { implementation "net.engawapg.lib:zoomable:$version" } ``` -------------------------------- ### Basic Zoomable Modifier Source: https://context7.com/usuiat/zoomable/llms.txt Demonstrates how to apply the `zoomable` modifier to an Image composable for basic zoom and pan functionality. ```APIDOC ## Basic Zoomable Modifier ### Description Applies the `zoomable` modifier to an `Image` composable to enable pinch-to-zoom, double-tap to toggle zoom levels, and mouse wheel zoom. ### Method Extension function on `Modifier` ### Endpoint N/A ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```kotlin import androidx.compose.foundation.Image import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.ui.Modifier import androidx.compose.ui.layout.ContentScale import net.engawapg.lib.zoomable.rememberZoomState import net.engawapg.lib.zoomable.zoomable @Composable fun BasicZoomableImage() { val painter = painterResource(id = R.drawable.penguin) val zoomState = rememberZoomState(contentSize = painter.intrinsicSize) Image( painter = painter, contentDescription = "Zoomable image", contentScale = ContentScale.Fit, modifier = Modifier .fillMaxSize() .zoomable(zoomState) ) } ``` ### Response #### Success Response (200) N/A (This is a UI modifier, not an API endpoint) #### Response Example N/A ``` -------------------------------- ### Zoomable with Asynchronous Image Loading in Kotlin Source: https://github.com/usuiat/zoomable/blob/main/README.md Integrates Modifier.zoomable with Coil's rememberAsyncImagePainter for loading images from URLs. Takes a URL string as input and sets contentSize for optimization. Outputs a zoomable image; depends on Coil library and handles loading asynchronously. ```kotlin val painter = rememberAsyncImagePainter("https://example.com/image.jpg") val zoomState = rememberZoomState(contentSize = painter.intrinsicSize) Image( painter = painter, contentDescription = "Zoomable image", contentScale = ContentScale.Fit, modifier = Modifier .fillMaxSize() .zoomable(zoomState), ) ``` -------------------------------- ### Programmatic Zoom Control with Animations Source: https://context7.com/usuiat/zoomable/llms.txt Demonstrates controlling zoom state programmatically with animation specifications like spring and tween. Uses coroutineScope to launch suspending zoom functions. Supports toggling scale, changing to a specific scale, resetting, and centering content. ```kotlin import androidx.compose.animation.core.spring import androidx.compose.animation.core.tween import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.geometry.Offset import kotlinx.coroutines.launch import net.engawapg.lib.zoomable.ZoomState import net.engawapg.lib.zoomable.changeScale import net.engawapg.lib.zoomable.toggleScale @Composable fun ProgrammaticZoomControl() { val zoomState = rememberZoomState() val coroutineScope = rememberCoroutineScope() // Toggle between target scale and 1.0x Button(onClick = { coroutineScope.launch { zoomState.toggleScale( targetScale = 3f, position = Offset(500f, 500f), animationSpec = spring() ) } }) { Text("Toggle Zoom") } // Change to specific scale Button(onClick = { coroutineScope.launch { zoomState.changeScale( targetScale = 4f, position = Offset.Zero, // Zoom around center animationSpec = tween(durationMillis = 500) ) } }) { Text("Zoom to 4x") } // Reset zoom to initial state Button(onClick = { coroutineScope.launch { zoomState.reset() // Returns to initialScale with zero offset } }) { Text("Reset") } // Center content by content coordinates Button(onClick = { coroutineScope.launch { zoomState.centerByContentCoordinate( offset = Offset(960f, 540f), // Point in content space scale = 3f, animationSpec = tween(700) ) } }) { Text("Center on Point") } } // All zoom methods are suspending functions that complete when animation finishes ``` -------------------------------- ### Stepped Double-Tap Scaling in Zoomable Kotlin Source: https://github.com/usuiat/zoomable/blob/main/README.md Implements custom double-tap logic to switch scale in steps using changeScale. Checks current scale and sets target accordingly. Outputs new zoom scale; allows multi-step zooming instead of binary toggle. ```kotlin zoomable( zoomState = zoomState, onDoubleTap = { position -> val targetScale = when { zoomState.scale < 2f -> 2f zoomState.scale < 4f -> 4f else -> 1f } zoomState.changeScale(targetScale, position) } ) ``` -------------------------------- ### Handle Gestures and Enable One-Finger Zoom in Zoomable Source: https://context7.com/usuiat/zoomable/llms.txt Configures gesture callbacks (tap, double-tap, long-press) and enables one-finger zoom (double-tap and drag) for the Zoomable composable. All callbacks receive the gesture position as an Offset. Dependencies include androidx.compose.ui and net.engawapg.lib.zoomable. ```kotlin import androidx.compose.ui.geometry.Offset import net.engawapg.lib.zoomable.rememberZoomState import net.engawapg.lib.zoomable.zoomable @Composable fun GestureCallbacksExample() { val zoomState = rememberZoomState() var lastTapPosition by remember { mutableStateOf(null) } var longPressDetected by remember { mutableStateOf(false) } Image( painter = painterResource(id = R.drawable.photo), contentDescription = null, modifier = Modifier .fillMaxSize() .zoomable( zoomState = zoomState, zoomEnabled = true, enableOneFingerZoom = true, // Double-tap and drag to zoom onTap = { position: Offset -> lastTapPosition = position println("Single tap at $position") }, onDoubleTap = { position: Offset -> println("Double tap at $position") zoomState.toggleScale(2.5f, position) }, onLongPress = { position: Offset -> longPressDetected = true println("Long press at $position") } ) ) // Disable one-finger zoom (double-tap and drag) Image( painter = painterResource(id = R.drawable.photo), contentDescription = null, modifier = Modifier .fillMaxSize() .zoomable( zoomState = zoomState, enableOneFingerZoom = false ) ) } // Callbacks: onTap, onDoubleTap (suspend), onLongPress // All callbacks receive the gesture position as Offset ``` -------------------------------- ### Configure Mouse Wheel Zoom in Compose Zoomable Modifier Source: https://context7.com/usuiat/zoomable/llms.txt Demonstrates how to configure mouse wheel zoom behavior for the `zoomable` modifier in Jetpack Compose. Supports various configurations like enabling zoom with Ctrl key, Shift key, or disabling it entirely. Requires net.engawapg.lib.zoomable and androidx.compose.ui dependencies. ```kotlin import net.engawapg.lib.zoomable.MouseWheelZoom import net.engawapg.lib.zoomable.rememberZoomState import net.engawapg.lib.zoomable.zoomable @Composable fun MouseWheelZoomOptions() { val zoomState = rememberZoomState() // Default: Ctrl + Wheel to zoom Image( painter = painterResource(id = R.drawable.photo), contentDescription = null, modifier = Modifier .fillMaxSize() .zoomable( zoomState = zoomState, mouseWheelZoom = MouseWheelZoom.EnabledWithCtrlKey // Default ) ) // Alternative configurations Image( painter = painterResource(id = R.drawable.photo), contentDescription = null, modifier = Modifier .fillMaxSize() .zoomable( zoomState = zoomState, mouseWheelZoom = MouseWheelZoom.Disabled // No mouse wheel zoom ) ) Image( painter = painterResource(id = R.drawable.photo), contentDescription = null, modifier = Modifier .fillMaxSize() .zoomable( zoomState = zoomState, mouseWheelZoom = MouseWheelZoom.Enabled // Wheel alone zooms ) ) Image( painter = painterResource(id = R.drawable.photo), contentDescription = null, modifier = Modifier .fillMaxSize() .zoomable( zoomState = zoomState, mouseWheelZoom = MouseWheelZoom.EnabledWithShiftKey // Shift + Wheel ) ) } // Options: Disabled, Enabled, EnabledWithCtrlKey, EnabledWithShiftKey, // EnabledWithAltKey, EnabledWithMetaKey (Command on Mac) ``` -------------------------------- ### Apply zoomable modifier to Image composable in Kotlin Source: https://context7.com/usuiat/zoomable/llms.txt Demonstrates basic usage of the zoomable modifier with an Image composable. Creates a ZoomState tied to the painter's intrinsic size and applies it via Modifier.zoomable. Supports pinch, double-tap, double-tap-drag, and Ctrl+mouse wheel zoom gestures. ```kotlin import androidx.compose.foundation.Image import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.ui.Modifier import androidx.compose.ui.layout.ContentScale import net.engawapg.lib.zoomable.rememberZoomState import net.engawapg.lib.zoomable.zoomable @Composable fun BasicZoomableImage() { val painter = painterResource(id = R.drawable.penguin) val zoomState = rememberZoomState(contentSize = painter.intrinsicSize) Image( painter = painter, contentDescription = "Zoomable image", contentScale = ContentScale.Fit, modifier = Modifier .fillMaxSize() .zoomable(zoomState) ) } // Result: Image supports pinch zoom, double-tap (toggles between 1.0x and 2.5x), // double-tap and drag (one finger zoom), and mouse wheel zoom with Ctrl key ``` -------------------------------- ### Zoomable with LazyColumn (Kotlin) Source: https://github.com/usuiat/zoomable/blob/main/README.md Demonstrates how to apply the zoomable modifier to a LazyColumn, enabling zooming within a scrollable list. This integrates the zoomable functionality with a common scrolling container found in Compose applications. The zoomable modifier is applied before the scroll modifier. ```Kotlin LazyColumn( modifier = Modifier.zoomableWithScroll(rememberZoomState()) ) { items(100) { Text("Item $it") } } ``` -------------------------------- ### Zoomable with LazyColumn and LazyRow in Compose Source: https://context7.com/usuiat/zoomable/llms.txt Integrates zoomable behavior into LazyColumn and LazyRow layouts using the `zoomableWithScroll` modifier. This allows for zooming within scrollable lists. Ensure `zoomableWithScroll` is placed before scroll modifiers like `horizontalScroll` for correct gesture coordination. Requires androidx.compose.foundation and net.engawapg.lib.zoomable dependencies. ```kotlin import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.rememberScrollState import net.engawapg.lib.zoomable.ExperimentalZoomableApi import net.engawapg.lib.zoomable.rememberZoomState import net.engawapg.lib.zoomable.zoomableWithScroll @OptIn(ExperimentalZoomableApi::class) @Composable fun ZoomableLazyColumn() { LazyColumn( modifier = Modifier .fillMaxSize() .zoomableWithScroll(rememberZoomState()) ) { items(100) { Text( text = "Item $index", modifier = Modifier .fillMaxWidth() .padding(16.dp) ) } } } @OptIn(ExperimentalZoomableApi::class) @Composable fun ZoomableScrollableRow() { // For Modifier.horizontalScroll or verticalScroll, // place zoomableWithScroll BEFORE the scroll modifier Row( modifier = Modifier .fillMaxSize() .zoomableWithScroll(rememberZoomState()) .horizontalScroll(rememberScrollState()) ) { repeat(50) { Text( text = "Item $index", modifier = Modifier.padding(16.dp) ) } } } // zoomableWithScroll uses nested scroll to coordinate zoom and scroll gestures ``` -------------------------------- ### Control Scroll Gesture Propagation with Zoomable Source: https://context7.com/usuiat/zoomable/llms.txt Demonstrates controlling scroll gesture propagation to parent composables using the zoomable modifier. It showcases two behaviors: 'ContentEdge' which propagates scroll when content edges are reached, and 'NotZoomed' which propagates scroll only when the scale is 1.0f. This is useful for nested scrolling scenarios like image galleries within a pager. ```kotlin import net.engawapg.lib.zoomable.ScrollGesturePropagation import net.engawapg.lib.zoomable.rememberZoomState import net.engawapg.lib.zoomable.zoomable @Composable fun ScrollPropagationDemo() { val pagerState = rememberPagerState { 5 } HorizontalPager(state = pagerState) { page -> val zoomState = rememberZoomState() // ContentEdge: Propagate scroll when content edge is reached Image( painter = painterResource(id = R.drawable.photo), contentDescription = null, modifier = Modifier .fillMaxSize() .zoomable( zoomState = zoomState, scrollGesturePropagation = ScrollGesturePropagation.ContentEdge ) ) // Behavior: When zoomed in, swipe pager only after reaching content edge // NotZoomed: Propagate scroll only when not zoomed Image( painter = painterResource(id = R.drawable.photo), contentDescription = null, modifier = Modifier .fillMaxSize() .zoomable( zoomState = zoomState, scrollGesturePropagation = ScrollGesturePropagation.NotZoomed ) ) // Behavior: Swipe pager only when scale is exactly 1.0f } } // ContentEdge: More intuitive for browsing zoomed images in gallery // NotZoomed: Prevents accidental page changes when zoomed ``` -------------------------------- ### Custom Double-Tap Zoom Behavior Source: https://context7.com/usuiat/zoomable/llms.txt Illustrates customizing double-tap gesture actions within the zoomable modifier. Allows defining custom zoom levels or disabling the double-tap action entirely by providing an empty lambda. The onDoubleTap lambda is a suspend function. ```kotlin import androidx.compose.ui.geometry.Offset import net.engawapg.lib.zoomable.rememberZoomState import net.engawapg.lib.zoomable.zoomable @Composable fun CustomDoubleTapImage() { val zoomState = rememberZoomState() // Three-step zoom progression on double-tap Image( painter = painterResource(id = R.drawable.photo), contentDescription = null, modifier = Modifier .fillMaxSize() .zoomable( zoomState = zoomState, onDoubleTap = { position: Offset -> val targetScale = when { zoomState.scale < 2f -> 2f zoomState.scale < 4f -> 4f else -> 1f } zoomState.changeScale(targetScale, position) } ) ) // Disable double-tap by providing empty lambda Image( painter = painterResource(id = R.drawable.photo), contentDescription = null, modifier = Modifier .fillMaxSize() .zoomable( zoomState = zoomState, onDoubleTap = {} // Double-tap does nothing ) ) // Custom target scale for default toggle behavior Image( painter = painterResource(id = R.drawable.photo), contentDescription = null, modifier = Modifier .fillMaxSize() .zoomable( zoomState = zoomState, onDoubleTap = { position -> zoomState.toggleScale(5.0f, position) } ) ) } // onDoubleTap is a suspend function executed in a coroutine scope ``` -------------------------------- ### Custom Double-Tap Scale Toggle in Zoomable Kotlin Source: https://github.com/usuiat/zoomable/blob/main/README.md Customizes double-tap to toggle to a specific scale using onDoubleTap callback. Takes a target scale and position; changes zoom scale cyclically. Outputs modified zoom state; overrides default 1.0f to 2.5f toggle. ```kotlin zoomable( zoomState = zoomState, onDoubleTap = { position -> zoomState.toggleScale(targetScale, position) } ) ``` -------------------------------- ### Disable Double-Tap in Zoomable Kotlin Source: https://github.com/usuiat/zoomable/blob/main/README.md Disables double-tap zoom action by setting onDoubleTap to an empty function. Takes no inputs; prevents scale changes on double-tap. Suitable when only other gestures are desired. ```kotlin zoomable( zoomState = zoomState, onDoubleTap = {} ) ``` -------------------------------- ### Disable One-Finger Zoom in Zoomable Kotlin Source: https://github.com/usuiat/zoomable/blob/main/README.md Disables one-finger zoom (tap and vertical drag) by setting enableOneFingerZoom to false. Takes a boolean setting; restricts zoom to multi-touch or other gestures. Outputs modified zoom behavior without one-finger input. ```kotlin zoomable( zoomState = zoomState, enableOneFingerZoom = false, ) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.