Skip to content

Instantly share code, notes, and snippets.

@demirdev
Last active January 3, 2023 08:58
Show Gist options
  • Save demirdev/ad0feac2af8b97d97f7c342abe3e3d40 to your computer and use it in GitHub Desktop.
Save demirdev/ad0feac2af8b97d97f7c342abe3e3d40 to your computer and use it in GitHub Desktop.
pinch to scale double values, for example change text size with fingers
import 'package:flutter/material.dart';
// learned from: https://copyprogramming.com/howto/flutter-gesturedetector-how-to-pinch-in-out-or-zoom-in-out-text-using-two-fingers
class PinchToScaleValue extends StatefulWidget {
final Widget child;
PinchToScaleValue(
{Key? key,
required this.child,
required this.currentValue,
required this.onValueChanged,
required this.baseValue,
this.ratioForUpdateValueUp = 1.1,
this.ratioForUpdateValueDown = 0.9})
: super(key: key);
final double baseValue;
final double ratioForUpdateValueUp;
final double ratioForUpdateValueDown;
final double Function() currentValue;
final Function(double newFontSize) onValueChanged;
@override
State<PinchToScaleValue> createState() => _PinchToScaleValueState();
}
class _PinchToScaleValueState extends State<PinchToScaleValue> {
late final double baseSize;
double baseScale = 1.0;
double scale = 1.0;
double size = 24.0;
@override
void initState() {
baseSize = widget.baseValue;
size = widget.currentValue();
baseScale = size / baseSize;
super.initState();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onScaleStart: (details) {
baseScale = scale;
},
onScaleUpdate: (details) {
if (details.scale == 1.0) {
return;
}
final _fontScale = (baseScale * details.scale).clamp(0.5, 15.0);
final _value = _fontScale * baseSize;
final _currentValue = widget.currentValue();
//
final thresoldCurrentFontSizeUp =
(widget.ratioForUpdateValueUp * _currentValue);
final thresoldCurrentFontSizeDown =
(widget.ratioForUpdateValueDown * _currentValue);
//
if (_value <= thresoldCurrentFontSizeDown ||
_value >= thresoldCurrentFontSizeUp) {
size = _value;
scale = _fontScale;
widget.onValueChanged(_value);
}
},
child: widget.child);
}
}
class TextSizeExample extends StatelessWidget {
TextSizeExample({Key? key}) : super(key: key);
final fontSize = ValueNotifier<double>(20);
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: PinchToScaleValue(
baseValue: 20,
currentValue: () {
return fontSize.value;
},
onValueChanged: (double newFontSize) {
fontSize.value = newFontSize;
},
child: SingleChildScrollView(
child: Center(
child: ValueListenableBuilder<double>(
valueListenable: fontSize,
builder: (context, fontSize, child) {
return Text(
r'''As soon as Shams Zakhour started working as a Dart writer at Google in December 2013, she started advocating for a Dart mascot. After documenting Java for 14 years, she had observed how beloved the Java mascot, Duke, had become, and she wanted something similar for Dart.
But the idea didn’t gain momentum until 2017, when one of the Flutter engineers, Nina Chen, suggested it on an internal mailing list. The Flutter VP at the time, Joshy Joseph, approved the idea and asked the organizer for the 2018 Dart Conference, Linda Rasmussen, to make it happen.
Once Shams heard about these plans, she rushed to Linda and asked to own and drive the project to produce the plushies for the conference. Linda had already elicited some design sketches, which she handed off. Starting with the sketches, Shams located a vendor who could work within an aggressive deadline (competing with Lunar New Year), and started the process of creating the specs for the plushy.
That’s right, Dash was originally a Dart mascot, not a Flutter mascot.
Here are some early mockups and one of the first prototypes:''',
style: TextStyle(fontSize: fontSize),
);
},
),
),
),
)),
);
}
}
void main() {
runApp(MaterialApp(home:TextSizeExample()));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment