saket / telephoto

Building blocks for designing media experiences in Compose UI
https://saket.github.io/telephoto/
Apache License 2.0
869 stars 28 forks source link

Question: Edge detection #56

Closed devs-gireeb closed 5 months ago

devs-gireeb commented 7 months ago
val state = rememberZoomableState()
val painter = resourcePainter(R.drawable.example)

LaunchedEffect(painter.intrinsicSize) {
  state.setContentLocation(
    ZoomableContentLocation.scaledInsideAndCenterAligned(painter.intrinsicSize)
  )
}

I'm wondering if this (Edge detection Function) only works with painter or others like ( AsyncImage ) ?

saket commented 7 months ago

Modifier.zoomable() is designed for any kind of zoomable content, so no you aren't limited to painters. Edge detection will work for anything as long as you can provide the content size.

If you are displaying images with Coil then is there a reason you aren't using ZoomableAyncImage(), which handles this for you?

devs-gireeb commented 7 months ago

Modifier.zoomable() is designed for any kind of zoomable content, so no you aren't limited to painters. Edge detection will work for anything as long as you can provide the content size.

If you are displaying images with Coil then is there a reason you aren't using ZoomableAyncImage(), which handles this for you?

You right about ZoomableAyncImage 😄, Actually used both of them.

Kindly can you share an example other than painter?

saket commented 7 months ago

Hmmm I can only think of images. SubSamplingImage() doesn't technically use a painter, but it divides bitmaps into tiles and calculates their visual size:

https://github.com/saket/telephoto/blob/fe91eee397a88dc26760a099b9e7209d6207fd24/zoomable-image/sub-sampling-image/src/main/kotlin/me/saket/telephoto/subsamplingimage/SubSamplingImageState.kt#L96-L98

If you were drawing something to the canvas, I'd imagine it to look something along these lines:

  val density = LocalDensity.current
  val verticalSpacePx = density.run { 24.dp.toPx() }
  var canvasSize by remember { mutableStateOf(Size.Zero) }

  val state = rememberZoomableState()
  LaunchedEffect(state) {
    state.setContentLocation(
      ZoomableContentLocation.scaledInsideAndCenterAligned(
        canvasSize.copy(height = canvasSize.height - verticalSpacePx * 2)
      )
    )
  }

  Canvas(
    Modifier
      .fillMaxSize()
      .onSizeChanged { canvasSize = it.toSize() }
      .zoomable(state)
  ) {
    drawRect(
      color = Color.Yellow,
      topLeft = Offset(0f, verticalSpacePx),
      size = size.copy(height = size.height - verticalSpacePx * 2),
    )
  }

(I haven't actually tested this code).

saket commented 5 months ago

@devs-gireeb I'm going ahead and closing this issue, but please feel free to continue this discussion.