Comments (6)
Thank you for your prompt response and assistance. I'd like to provide some updates and clarifications regarding my earlier query:
Callback for Current ZoomableState Updates: It appears that the functionality is already in place within the library. My earlier challenges might have been related to using the Preview mode, but as of now, everything seems to be functioning correctly. This is no longer an issue.
Restricting Zoom and Scroll to X-Axis: I am looking to limit zoom and pan actions strictly to the X-axis, in a manner akin to how graphicsLayer only applies scaleX and translationX, leaving the Y-axis unaffected. Here is an example of what I am aiming for:
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.Divider
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.tooling.preview.Preview
import me.saket.telephoto.zoomable.ZoomSpec
import me.saket.telephoto.zoomable.rememberZoomableState
import me.saket.telephoto.zoomable.zoomable
import kotlin.math.sin
@Preview
@Composable
fun ZoomTest() {
val state = rememberZoomableState(zoomSpec = ZoomSpec(10f))
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.White)
) {
Column(
Modifier
.fillMaxSize(0.5f)
.align(Alignment.Center)
) {
Text("Top Limit")
Divider()
SineWave(
modifier = Modifier
.weight(1f)
.fillMaxWidth()
.zoomable(state, clipToBounds = false)
)
Divider()
Text("Bottom Limit")
Divider()
Row(Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Absolute.SpaceBetween) {
repeat(5) {
Text(text = it.toString())
}
}
}
Column(modifier = Modifier.align(Alignment.BottomCenter)) {
Text(
text = "Zoom rate : x${state.contentTransformation.scale.scaleX}",
color = Color.Black,
)
Text(
text = "offset x : ${state.contentTransformation.offset.x}",
color = Color.Black,
)
Text(
text = "offset y : ${state.contentTransformation.offset.y}",
color = Color.Black,
)
}
}
}
@Composable
fun SineWave(modifier: Modifier) {
val infiniteTransition = rememberInfiniteTransition(label = "")
val phaseShift by infiniteTransition.animateFloat(
initialValue = 0f,
targetValue = 2f * Math.PI.toFloat(),
animationSpec = infiniteRepeatable(
animation = tween(durationMillis = 2000, easing = LinearEasing),
repeatMode = RepeatMode.Restart
), label = ""
)
Canvas(
modifier = modifier
) {
val amplitude = size.height / 2
val frequency = 0.05f
val strokeWidth = 5f
var previousPoint = Offset(0f, size.height / 2)
for (x in 1..size.width.toInt()) {
val y = size.height / 2 + amplitude * sin(frequency * x + phaseShift)
val currentPoint = Offset(x.toFloat(), y)
drawLine(
color = Color.Blue,
start = previousPoint,
end = currentPoint,
strokeWidth = strokeWidth,
cap = StrokeCap.Round
)
previousPoint = currentPoint
}
}
}
Demo : https://youtube.com/shorts/DyyTLcdGzS0?feature=share
If there are any issues in executing this code, I will organize a simple project on GitHub to demonstrate it more clearly.
Thank you for your attention to these matters.
from telephoto.
@Mett-Barr did you mean to post this to #59?
from telephoto.
@Mett-Barr did you mean to post this to #59?
Sorry, I replied in the wrong place.
from telephoto.
In response to the onClickOutside feature for a zoomable image, it seems to me that the requirement itself falls outside the scope of the Zoomable API. This is because the action to be taken when clicking outside is inherently external to the functionalities of the Zoomable API. Incorporating this capability directly into the Zoomable API could potentially violate the Single Responsibility Principle (SRP), suggesting that it might not be the best approach to include it within the API.
A more fitting solution could be to use a combination of other components, like using a container with clickable and padding properties. This would effectively handle the onClickOutside behavior without overloading the Zoomable API with responsibilities beyond its intended purpose. Such an approach maintains a cleaner separation of concerns and aligns more closely with SRP.
Like this:
Box(modifier = Modifier.clickable { /* onClickOutside */ }.padding(10.dp)) {
YourZoomableImage()
}
from telephoto.
@Mett-Barr unfortunately, that doesn't work for full sized images where clicks received outside the visual edges of an image will get intercepted by telephoto. You could work around this by using Modifier.wrapContent()
, but it's not great either as it'll prevent you from making gestures outside the image bounds.
from telephoto.
Addressed by 0347c53.
Usage:
implementation("me.saket.telephoto:zoomable-image-coil:0.8.0-SNAPSHOT")
val state = rememberZoomableImageState()
Zoomable*Image(
modifier = Modifier.fillMaxSize(),
state = state,
onClick = { offset ->
val wasClickedOutside = offset !in state.zoomableState.transformedContentBounds
},
…
)
from telephoto.
Related Issues (20)
- Telephoto internal NPE HOT 7
- Incorrect fling velocity on zoom gesture end with Compose 1.7.0-alpha02 HOT 1
- Zoomable modifier looses state after ZoomableState gets disposed and recreated HOT 12
- Allow disabling "Double tap to zoom" & "Pinch to zoom" separately HOT 2
- Content padding HOT 2
- Keyboard support HOT 2
- IllegalStateException: maximumVelocity should be a positive value HOT 21
- IllegalStateException: Coil returned a null cache snapshot HOT 5
- Gif Not Working HOT 5
- Individual Zoom for Canvas Rectangles using rememberZoomState. HOT 2
- Add mouse wheel zoom support HOT 5
- Different double tap/zoom functionality HOT 1
- Need SubsamplingScaleImageView.visibleFileRect(Rect fRect) analog HOT 4
- Fatal Exception: java.io.FileNotFoundException: No content provider: url HOT 4
- Lower minSDK to 21 HOT 6
- NullPointerException in RealZoomableState HOT 4
- sub-sampling didn't work when use SubSamplingImage HOT 4
- IllegalStateException: getWidth called on recycled region decoder HOT 6
- IllegalStateException: another transformation is already in progress HOT 2
- Crash: IllegalStateException Invalid velocity = (NaN, NaN) px/sec HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from telephoto.