Bug Description
I am building a custom drawing/annotation layer (CustomPaint) that sits visually on top of SfPdfViewer, driven by PdfViewerController.scrollOffset and PdfViewerController.zoomLevel to keep the overlay aligned with the rendered PDF page during pan/zoom.
PdfViewerController.scrollOffset updates live, every frame, during a gesture.
PdfViewerController.zoomLevel, however, does not update during an active two-finger pinch gesture. It stays frozen at its pre-gesture value and is only updated once synchronously when the gesture ends.
Because there is no public way to read the live scale factor while a pinch gesture is in progress, any external widget that needs to stay visually locked to the PDF's current zoom level (annotations, custom markers, etc.) has no ground-truth scale to read mid-gesture. This causes visible misalignment/drift between the PDF layer and the overlay layer for the duration of the gesture.
Requested fix: Expose the live scale factor during an active gesture (e.g., updating zoomLevel continuously or adding an onZoomLevelChanging stream) so external overlays can stay pixel-locked mid-gesture.
Steps to Reproduce
- Run the minimal reproduction code below on a physical device (not an emulator).
- Perform a two-finger pinch-zoom (in or out) on the PDF.
- Keep your fingers on the screen (mid-gesture) and look at the live HUD overlay.
- Observe: The Scroll Offset updates instantly, but the Zoom Level stays completely frozen until you lift your fingers.
Minimal Repro Code:
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart';
void main() => runApp(const MaterialApp(home: ZoomIssueRepro()));
class ZoomIssueRepro extends StatefulWidget {
const ZoomIssueRepro({Key? key}) : super(key: key);
@override
State<ZoomIssueRepro> createState() => _ZoomIssueReproState();
}
class _ZoomIssueReproState extends State<ZoomIssueRepro> with SingleTickerProviderStateMixin {
final PdfViewerController _pdfViewerController = PdfViewerController();
late AnimationController _ticker;
double _currentZoom = 1.0;
Offset _currentScroll = Offset.zero;
@override
void initState() {
super.initState();
_ticker = AnimationController(vsync: this, duration: const Duration(seconds: 1))
..addListener(() {
if (mounted) {
setState(() {
_currentZoom = _pdfViewerController.zoomLevel;
_currentScroll = _pdfViewerController.scrollOffset;
});
}
})
..repeat();
}
@override
void dispose() {
_ticker.dispose();
_pdfViewerController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Zoom Level Frozen Repro')),
body: Stack(
children: [
SfPdfViewer.network(
'[https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf](https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf)',
controller: _pdfViewerController,
canShowScrollHead: false,
),
Positioned(
top: 20,
left: 20,
child: Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.black87,
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Live Controller Values (Every Frame):', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)),
const SizedBox(height: 8),
Text('Scroll Offset: ${_currentScroll.dx.toStringAsFixed(1)},${_currentScroll.dy.toStringAsFixed(1)}', style: const TextStyle(color: Colors.greenAccent, fontSize: 16)),
Text('Zoom Level: ${_currentZoom.toStringAsFixed(3)}', style: const TextStyle(color: Colors.redAccent, fontSize: 16)),
const SizedBox(height: 12),
const Text('Try two-finger pinch zoom.\nNotice the Zoom Level freezes mid-gesture!', style: TextStyle(color: Colors.white70, fontSize: 12)),
],
),
),
),
],
),
);
}
}
https://github.com/user-attachments/assets/baf938b1-0469-4df8-bef8-fe24a43935bb
Bug Description
I am building a custom drawing/annotation layer (
CustomPaint) that sits visually on top ofSfPdfViewer, driven byPdfViewerController.scrollOffsetandPdfViewerController.zoomLevelto keep the overlay aligned with the rendered PDF page during pan/zoom.PdfViewerController.scrollOffsetupdates live, every frame, during a gesture.PdfViewerController.zoomLevel, however, does not update during an active two-finger pinch gesture. It stays frozen at its pre-gesture value and is only updated once synchronously when the gesture ends.Because there is no public way to read the live scale factor while a pinch gesture is in progress, any external widget that needs to stay visually locked to the PDF's current zoom level (annotations, custom markers, etc.) has no ground-truth scale to read mid-gesture. This causes visible misalignment/drift between the PDF layer and the overlay layer for the duration of the gesture.
Requested fix: Expose the live scale factor during an active gesture (e.g., updating
zoomLevelcontinuously or adding anonZoomLevelChangingstream) so external overlays can stay pixel-locked mid-gesture.Steps to Reproduce
Minimal Repro Code: