should not be turned more than 90 degrees from above and below. Currently, the bottom part is working as expected, but the top part is lagging behind before. it should be fixed, that is, the upper part should be the same as the lower part.[enter image description here](https://i.sstatic.net/0bZ5H33C.png)
import 'package:flip_widget_flutter/flip_widget_flutter.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'dart:math' as math;
class BookPages extends StatefulWidget {
final String url;
final String title;
const BookPages({Key? key, required this.url, required this.title})
: super(key: key);
@override
State<BookPages> createState() => _BookPageState();
}
class _BookPageState extends State<BookPages> {
final List<String> pages = [
'Page 1',
'Page 2',
'Page 3',
// Add more pages as needed
];
double _minNumber = 0.008;
int currentPage = 0;
GlobalKey<FlipWidgetState> _flipKey = GlobalKey();
Offset _oldPosition = Offset.zero;
bool _isFlipping = false;
double _clampMin(double v) {
if (v < _minNumber && v > -_minNumber) {
if (v >= 0) {
v = _minNumber;
} else {
v = -_minNumber;
}
}
return v;
}
@override
Widget build(BuildContext context) {
Size size = Size(256, 256);
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: GestureDetector(
child: FlipWidget(
key: _flipKey,
textureSize: size * 6,
child: Stack(
children: [
_buildPage(currentPage),
_buildPage(currentPage + 1),
],
),
),
onHorizontalDragStart: (details) {
if (!_isFlipping) {
_oldPosition = details.globalPosition;
_flipKey.currentState?.startFlip();
}
},
onHorizontalDragUpdate: (details) {
if (!_isFlipping) {
Offset off = details.globalPosition - _oldPosition;
double tilt = 1 / _clampMin((-off.dy + 20) / 100);
double percent = math.max(0, -off.dx / (size.width * 1.4));
percent = math.min(1.0, percent);
percent = percent - percent / 2 * (1 - 1 / tilt);
// Ensure the flip does not exceed 90 degrees on either side
double maxFlipAngle = 90 / 90; // 90 degrees in radians
if (percent > maxFlipAngle) {
percent = maxFlipAngle;
}
_flipKey.currentState?.flip(percent, tilt);
}
},
onHorizontalDragEnd: (details) {
_completeFlip(details.velocity.pixelsPerSecond.dx);
},
onHorizontalDragCancel: () {
if (!_isFlipping) {
_flipKey.currentState?.stopFlip();
}
},
),
);
}
Widget _buildPage(int index) {
if (index >= pages.length) {
return Container(color: Colors.transparent);
}
return Container(
color: Colors.white,
child: Center(
child: Text(
pages[index],
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
),
);
}
void _completeFlip(double velocity) {
if (!_isFlipping) {
_isFlipping = true;
if (velocity.abs() > 500) {
if (velocity > 0 && currentPage > 0) {
setState(() {
currentPage--;
});
} else if (velocity < 0 && currentPage < pages.length - 1) {
setState(() {
currentPage++;
});
}
}
_flipKey.currentState?.stopFlip();
Future.delayed(Duration(milliseconds: 300), () {
setState(() {
_isFlipping = false;
});
});
}
}
}
New contributor
Dilshodjon Haydarov is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.