telophoto源码查看记录

目录

项目模块:

主要依赖

zoomable


compose的图片查看器不少,telophoto功能完善,文档详细,支持image外的控件缩放.

它支持多平台.

打算从它的源码入手,然后作一个自定义的view.

项目模块:

include(":benchmark:runner")

include(":flick")

include(":zoomable")

include(":zoomable-image:core")

include(":zoomable-image:coil")

include(":zoomable-image:coil3")

include(":zoomable-image:glide")

include(":zoomable-image:sub-sampling-image")

include(":zoomable-peek-overlay")

include(":sample")

include(":test-util")

主要依赖

include(":zoomable")

include(":zoomable-image:core")

include(":zoomable-image:sub-sampling-image")

这三个是图片查看器的核心,第一个包含了缩放,不只支持image.

第二个包含对image的缩放.

第三个是处理超大图的分块解码功能.

按依赖顺序是zoomable为基础库.

sub-sampling-image依赖zoomable

core依赖它们两个,它即支持普通的放大缩小,又支持分块加载.

在docs里面有对应的模块的文档.index.md是安装使用.recipes.md是教程,涉及一些具体特性

zoomable

commonMain这是多平台共享代码,下面有两个包.一个是根目录,另一个是internal

ZoomableContentTransformation 这个类定义了平移,转换,旋转,缩放等属性,它是一个接口.具体实现是internal/RealZoomableContentTransformation

ZoomableState,它是state,的接口,具体实现是RealZoomableState,提供了rememberZoomableState方法.

复制代码
sealed interface ZoomableState {
 
  val contentTransformation: ZoomableContentTransformation
 
  var autoApplyTransformations: Boolean
  
  var contentScale: ContentScale

  var contentAlignment: Alignment
  
  val transformedContentBounds: Rect
  
  val zoomFraction: Float?

  /** The zoom spec passed to [rememberZoomableState]. */
  val zoomSpec: ZoomSpec

  /** Whether any zoom, pan (or both) animation is in progress. */
  val isAnimationRunning: Boolean

  /** See [ZoomableContentLocation]. */
  fun setContentLocation(location: ZoomableContentLocation)

  suspend fun resetZoom(animationSpec: AnimationSpec<Float> = DefaultZoomAnimationSpec)

  suspend fun zoomBy(
    zoomFactor: Float,
    centroid: Offset = Offset.Unspecified,
    animationSpec: AnimationSpec<Float> = DefaultZoomAnimationSpec,
  )

  suspend fun zoomTo(
    zoomFactor: Float,
    centroid: Offset = Offset.Unspecified,
    animationSpec: AnimationSpec<Float> = DefaultZoomAnimationSpec,
  )

  suspend fun panBy(
    offset: Offset,
    animationSpec: AnimationSpec<Offset> = DefaultPanAnimationSpec,
  )

  @Deprecated(message = "Use resetZoom(AnimationSpec) instead")
  suspend fun resetZoom(withAnimation: Boolean) {
    if (withAnimation) {
      resetZoom()
    } else {
      resetZoom(animationSpec = SnapSpec())
    }
  }

  /** See [ZoomableContentLocation]. */
  @Deprecated(
    message = "Use setContentLocation() instead",
    replaceWith = ReplaceWith("setContentLocation"),
    level = DeprecationLevel.HIDDEN,
  )
  @Suppress("INAPPLICABLE_JVM_NAME")  // https://youtrack.jetbrains.com/issue/KT-31420
  @JvmName("setContentLocation")
  suspend fun setContentLocationSuspending(location: ZoomableContentLocation) {
    setContentLocation(location)
  }

  companion object {
    val DefaultZoomAnimationSpec: AnimationSpec<Float> get() = spring(stiffness = Spring.StiffnessMediumLow)
    val DefaultPanAnimationSpec: AnimationSpec<Offset> get() = spring(stiffness = Spring.StiffnessMediumLow)
    val DefaultSettleAnimationSpec: AnimationSpec<Float> get() = spring()
  }
}

ZoomableState包含的内容:

转换参数,动画规格,内容缩放类型,可见区域.定义了zoomTo,zoomBy,panBy等方法来处理转换.

ZoomableState最终作用于外部的view,把这些参数应用后对于view的graphicsLayer.所以它不局限于image,可以用于作用compose view.

zoomable

是一个自定义的 Modifier 扩展函数,用于为 Compose UI 提供缩放和手势处理的功能。

  • 捏合缩放(Pinch to Zoom):允许用户通过双指捏合操作来放大或缩小内容。
  • 双击缩放(Double Click to Zoom):通过双击屏幕实现快速缩放。
  • 单指缩放(Single Finger Zoom):支持双击后按住并拖动进行更精细的缩放。
  • 触觉反馈(Haptic Feedback):当缩放超出范围时,提供触觉反馈以提醒用户。
  • 兼容嵌套滚动(Nested Scrolling Compatibility):确保与其他滚动组件协同工作。
  • 点击事件监听(Click Listeners):支持点击、长按等交互事件。

ZoomableElement 是一个自定义的 ModifierNodeElement,用于封装和管理缩放手势相关的逻辑。它的主要作用是:

  • 创建手势节点 :通过 create() 方法生成一个 ZoomableNode 实例,负责处理捏合缩放、双击缩放、点击等交互事件。
  • 更新状态 :通过 update() 方法动态更新手势节点的状态,确保手势逻辑能够根据外部参数的变化实时调整。

ZoomableNode,由ZoomableElement创建.ZoomableElement 是一个关键的中间层,连接了 Modifier.zoomable() 和实际的手势处理逻辑。它通过封装 ZoomableNode,实现了对捏合缩放、双击缩放、点击等交互事件的统一管理。

ZoomableElement的参数从外部的Zoomable传来,单击,双击,还有一个state.

ZoomableNode 是一个自定义的 DelegatingNode,负责处理缩放手势的核心逻辑。它的主要作用是:

  • 管理手势事件:捕获和处理捏合缩放、双击缩放、点击、长按等交互事件。
  • 状态更新:根据用户操作实时更新缩放状态(如缩放比例、平移位置等)。
  • 触觉反馈与动画:在特定情况下(如缩放超出范围)提供触觉反馈,并触发相应的动画效果。

单击,双击这些是往外传.

state:缩放状态管理对象,存储当前的缩放、平移等信息

它的主要方法是update(),里面有一个TransformableElement对象

  1. 手势节点的组合

    • TappableAndQuickZoomableNode:处理点击、长按、双击和快速缩放事件。
    • TransformableNode:处理捏合缩放和平移操作。
    • 这两个节点通过 delegate() 方法组合在一起,形成完整的手势处理链。

ZoomableNodeZoomableElement 创建的核心手势节点,封装了所有与缩放相关的手势逻辑。它通过组合多个子节点(TappableAndQuickZoomableNode 和 TransformableElement),

Compose 中的节点委托模式,使得手势逻辑既模块化又易于扩展,一路委托过来真正提供这些平移,转换的是在TransformableElement**,它处理了手势,**RealZoomableState包含了状态变化.

于是,总结一下,zoomable是Modifiter的扩展,要实现手势管理,需要ModifierNodeElement的子类注册上.于是有ZoomableElement.而具体要处理手势,它又是通过ZoomableNode来管理.最终由TransformableElement来处理手势,而RealZoomableState包含了这些状态的变化内容.它应用于view上.

相关推荐
键盘不能没有CV键7 分钟前
【日志链路】⭐️SpringBoot 整合 TraceId 日志链路追踪!
java·git·intellij-idea
_丿丨丨_9 分钟前
linux下的目录文件管理和基本文件管理的基本操作
linux·运维·服务器
咪库咪库咪14 分钟前
CSS过渡与动画
前端
zbqice00714 分钟前
网络问题之TCP/UDP协议
服务器·网络·tcp/ip
路在脚下@15 分钟前
RabbitMQ惰性队列的工作原理、消息持久化机制、同步刷盘的概念、延迟插件的使用方法
java·rabbitmq
前端康师傅18 分钟前
CSS基础教程-性能优化
前端·css
掘金用户897222 分钟前
微信小程序 扫码+拍照
前端
麓殇⊙23 分钟前
Mybatis-缓存详解
java·缓存·mybatis
睡不着的可乐23 分钟前
Ant Design Vue 表格复杂数据合并单元格
前端·vue.js·ant design
upsilon24 分钟前
React-router V7(配置路由)
前端·react.js