{"id":19521784,"url":"https://github.com/smarttoolfactory/compose-image","last_synced_at":"2025-04-07T06:11:59.775Z","repository":{"id":44032161,"uuid":"508594206","full_name":"SmartToolFactory/Compose-Image","owner":"SmartToolFactory","description":"🚀🏞💪 Collection of Images, Modifiers, utility functions for Jetpack Compose to expand and enrich displaying, manipulating, scaling, resizing, zooming, and getting cropped ImageBitmap based on selection area","archived":false,"fork":false,"pushed_at":"2023-07-18T10:39:25.000Z","size":10960,"stargazers_count":341,"open_issues_count":5,"forks_count":20,"subscribers_count":6,"default_branch":"develop","last_synced_at":"2025-03-31T05:04:41.026Z","etag":null,"topics":["android","image","image-manipulation","image-viewer","jetpack-compose","thumbnail","zoom","zoom-images","zoomable-images"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SmartToolFactory.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-06-29T07:41:41.000Z","updated_at":"2025-03-21T06:47:32.000Z","dependencies_parsed_at":"2024-11-11T00:34:59.872Z","dependency_job_id":"ea70c1db-2089-42d0-9730-56a115e69005","html_url":"https://github.com/SmartToolFactory/Compose-Image","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SmartToolFactory%2FCompose-Image","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SmartToolFactory%2FCompose-Image/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SmartToolFactory%2FCompose-Image/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SmartToolFactory%2FCompose-Image/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SmartToolFactory","download_url":"https://codeload.github.com/SmartToolFactory/Compose-Image/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247601448,"owners_count":20964864,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","image","image-manipulation","image-viewer","jetpack-compose","thumbnail","zoom","zoom-images","zoomable-images"],"created_at":"2024-11-11T00:34:55.346Z","updated_at":"2025-04-07T06:11:59.745Z","avatar_url":"https://github.com/SmartToolFactory.png","language":"Kotlin","readme":"# Compose Image on Steroids\n\n[![](https://jitpack.io/v/SmartToolFactory/Compose-Image.svg)](https://jitpack.io/#SmartToolFactory/Compose-Image)\n\nCollection of Images, Modifiers, utility functions for Jetpack Compose to expand\nand enrich displaying, manipulating, scaling, resizing, zooming, and\ngetting cropped `ImageBitmap` based on selection area, before/after image to with handle to\nshow partial of both images and more is cooking up\n\nhttps://user-images.githubusercontent.com/35650605/179715223-ba681886-6032-461f-806a-ea6a535d0627.mp4\n\nhttps://user-images.githubusercontent.com/35650605/186409295-14e967b5-a31c-4b2c-ab38-1990cbdce13a.mp4\n\n## Gradle Setup\n\nTo get a Git project into your build:\n\n* Step 1. Add the JitPack repository to your build file Add it in your root build.gradle at the end\n  of repositories:\n\n```\nallprojects {\n  repositories {\n      ...\n      maven { url 'https://jitpack.io' }\n  }\n}\n```\n\n* Step 2. Add the dependency\n\n```\ndependencies {\n    implementation 'com.github.SmartToolFactory:Compose-Image:\u003cversion\u003e'\n}\n```\n\n## Image\n\n### ImageWithConstraints\n\nA composable that lays out and draws a given `ImageBitmap`. This will attempt to  \nsize the composable according to the `ImageBitmap`'s given width and height.\n\n`ImageScope` returns constraints, width and height of the drawing area based on `contentScale`\nand rectangle of `imageBitmap` drawn. When a bitmap is displayed scaled to fit area of Composable\nspace used for drawing image is represented with `ImageScope.imageWidth` and\n`ImageScope.imageHeight`. When we display a bitmap 1000x1000px with `ContentScale.Crop` if it's\ncropped to 500x500px `ImageScope.rect` returns `IntRect(250,250,750,750)`.\n\nThis composable enables building other `Image` based Composables that require you to know\nspaces around `ImageBitmap` based on `ContentScale ` or which section of Bitmap is drawn to `Canvas`\n\n```kotlin\n@Composable\nfun ImageWithConstraints(\n    modifier: Modifier = Modifier,\n    imageBitmap: ImageBitmap,\n    alignment: Alignment = Alignment.Center,\n    contentScale: ContentScale = ContentScale.Fit,\n    contentDescription: String? = null,\n    alpha: Float = DefaultAlpha,\n    colorFilter: ColorFilter? = null,\n    filterQuality: FilterQuality = DrawScope.DefaultFilterQuality,\n    drawImage: Boolean = true,\n    content: @Composable ImageScope.() -\u003e Unit = {}\n) {\n    imageScope: ImageScope-\u003e\n\n}\n```\n\nreturns `ImageScope` which is\n\n```\n@Stable\ninterface ImageScope {\n    /**\n     * The constraints given by the parent layout in pixels.\n     *\n     * Use [minWidth], [maxWidth], [minHeight] or [maxHeight] if you need value in [Dp].\n     */\n    val constraints: Constraints\n\n    /**\n     * The minimum width in [Dp].\n     *\n     * @see constraints for the values in pixels.\n     */\n    val minWidth: Dp\n\n    /**\n     * The maximum width in [Dp].\n     *\n     * @see constraints for the values in pixels.\n     */\n    val maxWidth: Dp\n\n    /**\n     * The minimum height in [Dp].\n     *\n     * @see constraints for the values in pixels.\n     */\n    val minHeight: Dp\n\n    /**\n     * The maximum height in [Dp].\n     *\n     * @see constraints for the values in pixels.\n     */\n    val maxHeight: Dp\n\n    /**\n     * Width of area inside BoxWithConstraints that is scaled based on [ContentScale]\n     * This is width of the [Canvas] draws [ImageBitmap]\n     */\n    val imageWidth: Dp\n\n    /**\n     * Height of area inside BoxWithConstraints that is scaled based on [ContentScale]\n     * This is height of the [Canvas] draws [ImageBitmap]\n     */\n    val imageHeight: Dp\n\n    /**\n     * [IntRect] that covers boundaries of [ImageBitmap]\n     */\n    val rect: IntRect\n}\n```\n\n* drawImage param is to set whether this Composable should draw on Canvas. `ImageWithConstraints`\n  can be used not only for drawing but providing required info for its `content` or child\n  Composables so child can draw `ImageBitmap` as required by developer.\n\n### ImageWithThumbnail\n\n`ImageWithThumbnail` displays thumbnail of bitmap it draws in corner specified\nby `ThumbnailState.position`. When touch position is close to thumbnail position\nif `ThumbnailState.dynamicPosition` is set to true moves thumbnail\nto corner specified by `ThumbnailState.moveTo`\n\n```kotlin\n@Composable\nfun ImageWithThumbnail(\n    modifier: Modifier = Modifier,\n    imageBitmap: ImageBitmap,\n    contentScale: ContentScale = ContentScale.Fit,\n    alignment: Alignment = Alignment.Center,\n    contentDescription: String?,\n    thumbnailState: ThumbnailState = rememberThumbnailState(),\n    alpha: Float = DefaultAlpha,\n    colorFilter: ColorFilter? = null,\n    filterQuality: FilterQuality = DrawScope.DefaultFilterQuality,\n    drawOriginalImage: Boolean = true,\n    onDown: ((Offset) -\u003e Unit)? = null,\n    onMove: ((Offset) -\u003e Unit)? = null,\n    onUp: (() -\u003e Unit)? = null,\n    onThumbnailCenterChange: ((Offset) -\u003e Unit)? = null,\n    content: @Composable ImageScope.() -\u003e Unit = {}\n) {\n\n}\n```\n\n## Transform\n\nThese Composables and Modifiers are for scaling or resizing Image or Composable and move\nfrom current position using handles.\n\n### TransformLayout\n\nComposable that changes scale of its content with handles, translates its position\nwhen dragged inside bounds.\n\n```kotlin\n@Composable\nfun TransformLayout(\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    handleRadius: Dp = 15.dp,\n    handlePlacement: HandlePlacement = HandlePlacement.Corner,\n    onDown: (Transform) -\u003e Unit = {},\n    onMove: (Transform) -\u003e Unit = {},\n    onUp: (Transform) -\u003e Unit = {},\n    content: @Composable () -\u003e Unit\n) {\n\n}\n```\n\n### MorphLayout\n\nComposable that changes dimensions of its content with handles, translates its position\nwhen dragged inside bounds.\n\n⚠️ Be careful about maximum dimension can be assigned to this Composable with handles\nbecause maximum width and height depends on how a Composable,\nColumn for instance, lays out its children. It can be expanded up to remaining space if other\nsiblings occupy rest of the parent's available space set with parent `Layout`\n\n```kotlin\n@Composable\nfun MorphLayout(\n    modifier: Modifier = Modifier,\n    containerModifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    handleRadius: Dp = 15.dp,\n    handlePlacement: HandlePlacement = HandlePlacement.Corner,\n    updatePhysicalSize: Boolean = false,\n    onDown: () -\u003e Unit = {},\n    onMove: (DpSize) -\u003e Unit = {},\n    onUp: () -\u003e Unit = {},\n    content: @Composable () -\u003e Unit\n) {\n}\n```\n\n## Zoom\n\nZoom feature provides zooming in or out Image, or Composables with animations and\ngetting data about current transform or image Using Callbacks.\n\n### Modifier.zoom()\n\nModifier that zooms, pans, and rotates any Composable it set to. when [clip] is true\n`Modifier.clipToBounds()` is used to limit content inside Composable bounds\n`consume` param is for `Modifier.pointerInput` to consume current events to prevent other\ngestures like scroll, drag or transform to initiate.\nCallbacks notify user that gesture has started, going on finished with [ZoomData] that\ncontains current transformation information\n\n```kotlin\nfun Modifier.zoom(\n    key: Any? = Unit,\n    consume: Boolean = true,\n    clip: Boolean = true,\n    zoomState: ZoomState,\n    onGestureStart: ((ZoomData) -\u003e Unit)? = null,\n    onGesture: ((ZoomData) -\u003e Unit)? = null,\n    onGestureEnd: ((ZoomData) -\u003e Unit)? = null\n)\n```\n\n#### Parameters\n\n* **key/key1-key2/keys** are used for restarting `Modifier.pointerInput(*keys)` and remember\n  for getting `ZoomState`\n* **consume** flag to prevent other gestures such as scroll, drag or transform to get\n* **clip** when set to true clips to parent bounds. Anything outside parent bounds is not drawn\n  empty space on sides or edges of parent.\n* **zoomState** State of the zoom that contains option to set initial, min, max zoom, enabling\n  rotation, pan or zoom and contains current [ZoomData]event propagations\n* **onGestureStart** callback to to notify gesture has started and return current ZoomData of this\n  modifier\n* **onGesture** callback to notify about ongoing gesture and return current ZoomData of this\n  modifier\n* **onGestureEnd** callback to notify that gesture finished and return current ZoomData of this\n  modifier\n\n### ZoomState\n\nCreate and [remember] the [ZoomState] based on the currently appropriate transform configuration to\nallow changing pan, zoom, and rotation.\n\n```kotlin\n@Composable\nfun rememberZoomState(\n    initialZoom: Float = 1f,\n    initialRotation: Float = 0f,\n    minZoom: Float = 1f,\n    maxZoom: Float = 5f,\n    zoomable: Boolean = true,\n    pannable: Boolean = true,\n    rotatable: Boolean = false,\n    limitPan: Boolean = false,\n    key1: Any? = Unit\n): ZoomState {\n    return remember(key1) {\n        ZoomState(\n            initialZoom = initialZoom,\n            initialRotation = initialRotation,\n            minZoom = minZoom,\n            maxZoom = maxZoom,\n            zoomable = zoomable,\n            pannable = pannable,\n            rotatable = rotatable,\n            limitPan = limitPan\n        )\n    }\n}\n```\n\n#### Parameters\n\n* **initialZoom** zoom set initially\n* **initialRotation** rotation set initially\n* **minZoom** minimum zoom value\n* **maxZoom** maximum zoom value\n* **limitPan** limits pan to bounds of parent Composable. Using this flag prevents creating empty\n  space on sides or edges of parent\n* **zoomable** when set to true zoom is enabled\n* **pannable** when set to true pan is enabled\n* **rotatable** when set to true rotation is enabled\n\n### ZoomableImage\n\nZoomable image that zooms in and out in [ [minZoom], [maxZoom] ] interval and translates\nzoomed image based on pointer position.\nDouble tap gestures reset image translation and zoom to default values with animation.\nCallbacks notify user that gesture has started, going on finished with [ZoomData] that\ncontains current transformation information\n\n```kotlin\n@Composable\nfun ZoomableImage(\n    modifier: Modifier = Modifier,\n    imageBitmap: ImageBitmap,\n    alignment: Alignment = Alignment.Center,\n    contentScale: ContentScale = ContentScale.Fit,\n    contentDescription: String? = null,\n    alpha: Float = DefaultAlpha,\n    colorFilter: ColorFilter? = null,\n    filterQuality: FilterQuality = DrawScope.DefaultFilterQuality,\n    initialZoom: Float = 1f,\n    minZoom: Float = 1f,\n    maxZoom: Float = 5f,\n    limitPan: Boolean = true,\n    zoomable: Boolean = true,\n    pannable: Boolean = true,\n    rotatable: Boolean = false,\n    clip: Boolean = true,\n    clipTransformToContentScale: Boolean = false,\n    consume: Boolean = true,\n    onGestureStart: (ZoomData) -\u003e Unit = {},\n    onGesture: (ZoomData) -\u003e Unit = {},\n    onGestureEnd: (ZoomData) -\u003e Unit = {}\n)\n```\n\n#### Parameters\n\n* **initialZoom** zoom set initially\n* **minZoom** minimum zoom value this Composable can possess\n* **maxZoom** maximum zoom value this Composable can possess\n* **clip** whether image should be clip to bounds of Image\n* **clipTransformToContentScale** when set true zoomable image takes borders of image drawn while\n  zooming in. [contentScale] determines whether will be empty spaces on edges of Composable\n* **limitPan** limits pan to bounds of parent Composable. Using this flag prevents creating empty\n  space on sides or edges of parent.\n* **consume** flag to prevent other gestures such as scroll, drag or transform to get event\n  propagations\n* **zoomable** when set to true zoom is enabled\n* **pannable** when set to true pan is enabled\n* **rotatable** when set to true rotation is enabled\n* **onGestureStart** callback to to notify gesture has started and return current ZoomData of this\n  modifier\n* **onGesture** callback to notify about ongoing gesture and return current ZoomData of this\n  modifier\n* **onGestureEnd** callback to notify that gesture finished and return current ZoomData of this\n  modifier\n\n### Modifier.enhancedZoom()\n\nModifier that zooms in or out of Composable set to. This zoom modifier has option to move back to\nbounds with an animation or option to have fling gesture when user removes from screen while\nvelocity is higher than threshold to have smooth touch effect.\n\n```kotlin\nfun Modifier.enhancedZoom(\n    key: Any? = Unit,\n    clip: Boolean = true,\n    enhancedZoomState: EnhancedZoomState,\n    enabled: (Float, Offset, Float) -\u003e Boolean = DefaultEnabled,\n    zoomOnDoubleTap: (ZoomLevel) -\u003e Float = enhancedZoomState.DefaultOnDoubleTap,\n    onGestureStart: ((EnhancedZoomData) -\u003e Unit)? = null,\n    onGesture: ((EnhancedZoomData) -\u003e Unit)? = null,\n    onGestureEnd: ((EnhancedZoomData) -\u003e Unit)? = null,\n)\n```\n\n#### Parameters\n\n* **key** is used for [Modifier.pointerInput] to restart closure when any keys assigned change\n* **clip** when set to true clips to parent bounds. Anything outside parent bounds is not drawn\n  empty space on sides or edges of parent.\n* **enhancedZoomState** State of the zoom that contains option to set initial, min, max zoom,\n  enabling rotation, pan or zoom and contains current [EnhancedZoomData]event propagations. Also\n  contains [Rect] of visible area based on pan, zoom and rotation\n* **zoomOnDoubleTap** lambda that returns current [ZoomLevel] and based on current level enables\n  developer to define zoom on double tap gesture\n* **enabled** lambda can be used selectively enable or disable pan and intercepting with scroll,\n  drag or lists or pagers using current zoom, pan or rotation values\n* **onGestureStart** callback to to notify gesture has started and return current [EnhancedZoomData]\n  of this modifier\n* **onGesture** callback to notify about ongoing gesture and return current [EnhancedZoomData]  of\n  this modifier\n* **onGestureEnd** callback to notify that gesture finished return current [EnhancedZoomData]  of\n  this modifier\n\n### EnhancedZoomState\n\nCreate and [remember] the [EnhancedZoomState] based on the currently appropriate transform\nconfiguration to allow changing pan, zoom, and rotation.\nAllows to change zoom, pan, translate, or get current state by calling methods on this object. To be\nhosted and passed to [Modifier.enhancedZoom].\nAlso contains [EnhancedZoomData] about current transformation area of Composable and visible are of\nimage being zoomed, rotated, or panned. If any animation is going on\ncurrent [EnhancedZoomState.isAnimationRunning] is true and [EnhancedZoomData] returns rectangle that\nbelongs to end of animation.\n\n```kotlin\nfun Modifier.enhancedZoom(\n    key: Any? = Unit,\n    clip: Boolean = true,\n    enhancedZoomState: EnhancedZoomState,\n    enabled: (Float, Offset, Float) -\u003e Boolean = DefaultEnabled,\n    zoomOnDoubleTap: (ZoomLevel) -\u003e Float = enhancedZoomState.DefaultOnDoubleTap,\n    onGestureStart: ((EnhancedZoomData) -\u003e Unit)? = null,\n    onGesture: ((EnhancedZoomData) -\u003e Unit)? = null,\n    onGestureEnd: ((EnhancedZoomData) -\u003e Unit)? = null,\n)\n```\n\n#### Parameters\n\n* **initialZoom** zoom set initially\n* **minZoom** minimum zoom value\n* **maxZoom** maximum zoom value\n* **fling** when set to true dragging pointer builds up velocity. When last pointer leaves\n  Composable a movement invoked against friction till velocity drops below to threshold\n* **moveToBounds** when set to true if image zoom is lower than initial zoom or panned out of image\n  boundaries moves back to bounds with animation.\n* **zoomable** when set to true zoom is enabled\n* **pannable** when set to true pan is enabled\n* **rotatable** when set to true rotation is enabled\n* **limitPan** limits pan to bounds of parent Composable. Using this flag prevents creating empty\n  space on sides or edges of parent\n\n### EnhancedZoomableImage\n\nZoomable image that zooms in and out in [ [minZoom], [maxZoom] ] interval and pans zoomed image\nbased on pointer position. Double tap gestures reset image translation and zoom to default values\nwith animation. Difference between `ZoomaableImage` and `EnhancedZoomableImage` is this version\ncan animate back to bounds and have fling gesture that doesn't stop movement when last pointer\nis up but continues motion agains friction.\n\n`moveToBound` is true image moves to bounds when moved out of bounds. When\n`fling` is set to true image moves until velocity drops below threshold.\n\n```kotlin\n@Composable\nfun EnhancedZoomableImage(\n    modifier: Modifier = Modifier,\n    imageBitmap: ImageBitmap,\n    alignment: Alignment = Alignment.Center,\n    contentScale: ContentScale = ContentScale.Fit,\n    contentDescription: String? = null,\n    alpha: Float = DefaultAlpha,\n    colorFilter: ColorFilter? = null,\n    filterQuality: FilterQuality = DrawScope.DefaultFilterQuality,\n    initialZoom: Float = 1f,\n    minZoom: Float = .5f,\n    maxZoom: Float = 5f,\n    limitPan: Boolean = true,\n    fling: Boolean = false,\n    moveToBounds: Boolean = true,\n    zoomable: Boolean = true,\n    pannable: Boolean = true,\n    rotatable: Boolean = false,\n    clip: Boolean = true,\n    enabled: (Float, Offset, Float) -\u003e Boolean = DefaultEnabled,\n    zoomOnDoubleTap: (ZoomLevel) -\u003e Float = DefaultOnDoubleTap,\n    clipTransformToContentScale: Boolean = false,\n    onGestureStart: ((EnhancedZoomData) -\u003e Unit)? = null,\n    onGesture: ((EnhancedZoomData) -\u003e Unit)? = null,\n    onGestureEnd: ((EnhancedZoomData) -\u003e Unit)? = null\n)\n```\n\n#### Parameters\n\n* **initialZoom** zoom set initially\n* **minZoom** minimum zoom value this Composable can possess\n* **maxZoom** maximum zoom value this Composable can possess\n* **limitPan** limits pan to bounds of parent Composable. Using this flag prevents creating empty\n  space on sides or edges of parent.\n* **fling** when set to true dragging pointer builds up velocity. When last pointer leaves\n  Composable a movement invoked against friction till velocity drops down to threshold\n* **moveToBounds** when set to true if image zoom is lower than initial zoom or panned out of image\n  boundaries moves back to bounds with animation.\n* **zoomable** when set to true zoom is enabled\n* **pannable** when set to true pan is enabled\n* **rotatable** when set to true rotation is enabled\n* **clip** when set to true clips to parent bounds. Anything outside parent bounds is not drawn\n* **clipTransformToContentScale** when set true zoomable image takes borders of image drawn while\n  zooming in. [contentScale] determines whether will be empty spaces on edges of Composable\n* **zoomOnDoubleTap** lambda that returns current [ZoomLevel] and based on current level enables\n  developer to define zoom on double tap gesture\n* **enabled** lambda can be used selectively enable or disable pan and intercepting with scroll,\n  drag or lists or pagers using current zoom, pan or rotation values\n* **onGestureStart** callback to to notify gesture has started and return current ZoomData of this\n  modifier\n* **onGesture** callback to notify about ongoing gesture and return current ZoomData of this\n  modifier\n* **onGestureEnd** callback to notify that gesture finished and return current ZoomData of this\n  modifier\n\n### Modifier.animatedZoom()\n\nModifier that zooms in or out of Composable set to. This zoom modifier has option to move back to\nbounds with an animation or option to have fling gesture when user removes from screen while\nvelocity is higher than threshold to have smooth touch effect.\n\nDifference between `Modifier.enhancedZoom()` and `Modifier.animatedZoom()` is enhanced zoom\nuses Bitmap dimensions and returns a callback that returns [EnhancedZoomData] that contains\nvisible image area which is suitable for crop while `Modifier.animatedZoom()` requires\ndimensions of Composable to have valid pan limiting behavior. More suitable for zooming\nComposables while enhanced zoom is more suitable for image zooming.\n\n```kotlin\nfun Modifier.animatedZoom(\n    vararg keys: Any?,\n    clip: Boolean = true,\n    animatedZoomState: AnimatedZoomState,\n    enabled: (Float, Offset, Float) -\u003e Boolean = DefaultEnabled,\n    zoomOnDoubleTap: (ZoomLevel) -\u003e Float = animatedZoomState.DefaultOnDoubleTap,\n)\n```\n\n#### Parameters\n\n* **keys** are used for [Modifier.pointerInput] to restart closure when any keys assigned change\n* **clip** when set to true clips to parent bounds. Anything outside parent bounds is not drawn\n* **animatedZoomState** State of the zoom that contains option to set initial, min, max zoom,\n  enabling rotation, pan or zoom\n* **zoomOnDoubleTap** lambda that returns current [ZoomLevel] and based on current level enables\n  developer to define zoom on double tap gesture\n* **enabled** lambda can be used selectively enable or disable pan and intercepting with scroll,\n  drag or lists or pagers using current zoom, pan or rotation values\n\n### AnimatedZoomState\n\nCreate and [remember] the [AnimatedZoomState] based on the currently appropriate transform\nconfiguration to allow changing pan, zoom, and rotation.\n\nAllows to change zoom, pan, translate, or get current state by calling methods on this object. To be\nhosted and passed to [Modifier.animatedZoom].\n\n```kotlin\n@Composable\nfun rememberAnimatedZoomState(\n    contentSize: DpSize = DpSize.Zero,\n    initialZoom: Float = 1f,\n    minZoom: Float = 1f,\n    maxZoom: Float = 5f,\n    fling: Boolean = true,\n    moveToBounds: Boolean = false,\n    zoomable: Boolean = true,\n    pannable: Boolean = true,\n    rotatable: Boolean = false,\n    limitPan: Boolean = true,\n    key1: Any? = Unit\n)\n```\n\n#### Parameters\n\n* **contentSize** when the content that will be zoomed is not parent pass child size to bound\n  content correctly inside parent. If parent doesn't have any content this parameter is not required\n* **initialZoom** zoom set initially\n* **minZoom** minimum zoom value\n* **maxZoom** maximum zoom value\n* **fling** when set to true dragging pointer builds up velocity. When last\n* pointer leaves Composable a movement invoked against friction till velocity drops below to\n  threshold\n* **moveToBounds** when set to true if image zoom is lower than initial zoom or panned out of image\n  boundaries moves back to bounds with animation.\n* **zoomable** when set to true zoom is enabled\n* **pannable** when set to true pan is enabled\n* **rotatable** when set to true rotation is enabled\n* **limitPan** limits pan to bounds of parent Composable. Using this flag prevents creating empty\n  space on sides or edges of parent\n\n### AnimatedZoomLayout\n\nLayout that can zoom, rotate, pan its content with fling and moving back to bounds animation.\n\n```kotlin\n@Composable\nfun AnimatedZoomLayout(\n    modifier: Modifier = Modifier,\n    clip: Boolean = true,\n    initialZoom: Float = 1f,\n    minZoom: Float = 1f,\n    maxZoom: Float = 3f,\n    fling: Boolean = true,\n    moveToBounds: Boolean = false,\n    zoomable: Boolean = true,\n    pannable: Boolean = true,\n    rotatable: Boolean = false,\n    limitPan: Boolean = true,\n    enabled: (Float, Offset, Float) -\u003e Boolean = DefaultEnabled,\n    zoomOnDoubleTap: (ZoomLevel) -\u003e Float = DefaultOnDoubleTap,\n    content: @Composable () -\u003e Unit\n)\n```\n\n#### Parameters\n\n* **clip** when set to true clips to parent bounds. Anything outside parent bounds is not\n* drawn\n* **minZoom** minimum zoom value\n* **maxZoom** maximum zoom value\n* **fling** when set to true dragging pointer builds up velocity. When last pointer leaves\n  Composable a movement invoked against friction till velocity drops below to threshold\n* **moveToBounds** when set to true if image zoom is lower than initial zoom or panned out of image\n  boundaries moves back to bounds with animation.\n* **zoomable** when set to true zoom is enabled\n* **pannable** when set to true pan is enabled\n* **rotatable** when set to true rotation is enabled\n* **limitPan** limits pan to bounds of parent Composable. Using this flag prevents creating empty\n  space on sides or edges of parent\n* **zoomOnDoubleTap** lambda that returns current [ZoomLevel] and based on current level enables\n  developer to define zoom on double tap gesture\n* **enabled** lambda can be used selectively enable or disable pan and intercepting with scroll,\n  drag or lists or pagers using current zoom, pan or rotation values\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmarttoolfactory%2Fcompose-image","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmarttoolfactory%2Fcompose-image","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmarttoolfactory%2Fcompose-image/lists"}