saket / telephoto

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

Question: Edge detection #56

Closed devs-gireeb closed 10 months ago

devs-gireeb commented 1 year 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 1 year 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 1 year 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 1 year 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 10 months ago

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