compose multiplatform reader3

compose multiplatform reader3

前面都介绍过解码,布局等

现在介绍手势.桌面端

目录

手势

手势完成后,就是翻页

桌面端

国际化


手势

Canvas(
            modifier = Modifier
                .fillMaxSize()
                .background(Color.Transparent)
                .pointerInput(Unit) {
                    awaitEachGesture {
                        var zooming = false
                        var dragging = false
                        // pan惯性
                        val panVelocityTracker = VelocityTracker()
                        var pan: Offset
                        var totalDrag = Offset.Zero
                        val down = awaitFirstDown(requireUnconsumed = false)
                        val wasFlingActive = flingJob?.isActive == true // 记录按下时是否有fling动画
                        try {
                            pan = Offset.Zero
                            totalDrag = Offset.Zero
                            panVelocityTracker.resetTracking()
                            flingJob?.cancel()
                            isFlingActive = false
                            do {
                                val event = awaitPointerEvent()
                                val pointerCount = event.changes.size
                                val zoomChange = event.calculateZoom()
                                val panChange = event.calculatePan()
                                val centroid = event.calculateCentroid()
                                // 采集pan速度
                                val uptime =
                                    event.changes.maxByOrNull { it.uptimeMillis }?.uptimeMillis
                                        ?: 0L
                                pan += panChange
                                totalDrag += panChange
                                panVelocityTracker.addPosition(uptime, pan)

                                // 检测是否开始拖拽
                                if (totalDrag.getDistance() > 10f) {
                                    dragging = true
                                }
                                if (pointerCount > 1) {
                                    zooming = true
                                    val newZoom = (zoomChange * vZoom).coerceIn(1f, 10f)
                                    val zoomFactor = newZoom / vZoom

                                    // 计算缩放中心点:手势中心相对于内容的位置
                                    // centroid 是手势中心在视图中的位置
                                    // 需要将其转换为相对于内容的位置
                                    val contentCenterX = centroid.x - offset.x
                                    val contentCenterY = centroid.y - offset.y

                                    // 计算新的偏移量,保持内容中心点不变
                                    val newOffsetX = centroid.x - contentCenterX * zoomFactor
                                    val newOffsetY = centroid.y - contentCenterY * zoomFactor

                                    vZoom = newZoom
                                    offset = Offset(newOffsetX, newOffsetY)

                                    // 边界检查
                                    if (orientation == Vertical) {
                                        val scaledWidth = viewSize.width * vZoom
                                        // 在缩放过程中,需要根据当前缩放比例调整总高度
                                        val scaleRatio = vZoom / pdfViewState.vZoom
                                        val scaledHeight = pdfViewState.totalHeight * scaleRatio
                                        val minX = minOf(0f, viewSize.width - scaledWidth)
                                        val maxX = 0f
                                        val minY =
                                            if (scaledHeight > viewSize.height) viewSize.height - scaledHeight else 0f
                                        val maxY = 0f
                                        offset = Offset(
                                            offset.x.coerceIn(minX, maxX),
                                            offset.y.coerceIn(minY, maxY)
                                        )
                                    } else {
                                        val scaledHeight = viewSize.height * vZoom
                                        val scaleRatio = vZoom / pdfViewState.vZoom
                                        val scaledWidth = pdfViewState.totalWidth * scaleRatio
                                        val minY = minOf(0f, viewSize.height - scaledHeight)
                                        val maxY = 0f
                                        val minX =
                                            if (scaledWidth > viewSize.width) viewSize.width - scaledWidth else 0f
                                        val maxX = 0f
                                        offset = Offset(
                                            offset.x.coerceIn(minX, maxX),
                                            offset.y.coerceIn(minY, maxY)
                                        )
                                    }
                                    pdfViewState.updateOffset(offset)
                                    event.changes.fastForEach { if (it.positionChanged()) it.consume() }
                                } else {
                                    // 单指拖动
                                    if (!zooming) {
                                        offset += panChange
                                        if (orientation == Vertical) {
                
转载请说明出处内容投诉
CSS教程网 » compose multiplatform reader3

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买