Mirrored text in Flutter - dart

Is there any way to mirror your text or any widget in Flutter? Like in Android, I can do
scaleY = -1
scaleX = -1
I couldn't find anything similar to this in Flutter. I tried following but it simply rotates your text by 90˚
Transform.scale(scale: -1.0)

Check out this post, it may have something that could help you.
#override
Widget build(BuildContext context) {
return Transform( // Transform widget
transform: Matrix4.identity()
..setEntry(3, 2, 0.001) // perspective
..rotateX(_offset.dy)
..rotateY(_offset.dx),
alignment: FractionalOffset.center,
child: _defaultApp(context), // <<< set your widget here
);
}

Related

How to fix offset shift in GestureDetector.onScaleUpdate when lifting the finger after drag on iOS device?

When I finish dragging a Positioned widget I notice that there's a small shift in the final position when I lift the finger off the screen on the iOS device (iOS 14.6). This behaviour also present in the iOS emulator but very visible on the physical device:
– notice the slight position shift after the red cube stops moving.
Demo's source code:
import 'package:flutter/material.dart';
class GestureDemo extends StatefulWidget {
const GestureDemo({Key? key}) : super(key: key);
#override
GestureDemoState createState() => GestureDemoState();
}
class GestureDemoState extends State<GestureDemo> {
late Offset _startingFocalPoint;
late Offset _previousOffset;
Offset _offset = Offset.zero;
late double _previousZoom;
double _zoom = 1.0;
final containerSize = Size(100, 100);
void _handleScaleStart(ScaleStartDetails details) {
setState(() {
_startingFocalPoint = details.focalPoint;
_previousOffset = _offset;
_previousZoom = _zoom;
});
}
void _handleScaleUpdate(ScaleUpdateDetails details) {
setState(() {
_zoom = _previousZoom * details.scale;
// Ensure that item under the focal point stays in the same place despite zooming
final Offset normalizedOffset = (_startingFocalPoint - _previousOffset) / _previousZoom;
_offset = details.focalPoint - normalizedOffset * _zoom;
});
}
#override
Widget build(BuildContext context) {
return Stack(
fit: StackFit.expand,
children: <Widget>[
Positioned(
top: _offset.dy,
left: _offset.dx,
child: GestureDetector(
onScaleStart: _handleScaleStart,
onScaleUpdate:_handleScaleUpdate,
child: Container(
color: Colors.red,
width: containerSize.width * _zoom,
height: containerSize.height * _zoom,
),
)
),
],
);
}
}
void main() {
runApp(MaterialApp(
theme: ThemeData.dark(),
home: Scaffold(
appBar: AppBar(title: const Text('Gestures Demo')),
body: const GestureDemo(),
),
));
}
This is a simplified version of the official widget gestures example from Flutter.
When I log ScaleUpdateDetails, I see that the last details have a small shift
ScaleUpdateDetails(focalPoint: Offset(174.0, 260.5), localFocalPoint: Offset(28.5, 73.0), scale: 1.0, horizontalScale: 1.0, verticalScale: 1.0, rotation: 0.0, pointerCount: 1)
ScaleUpdateDetails(focalPoint: Offset(174.0, 260.0), localFocalPoint: Offset(28.5, 72.5), scale: 1.0, horizontalScale: 1.0, verticalScale: 1.0, rotation: 0.0, pointerCount: 1)
ScaleUpdateDetails(focalPoint: Offset(173.0, 258.0), localFocalPoint: Offset(27.5, 70.5), scale: 1.0, horizontalScale: 1.0, verticalScale: 1.0, rotation: 0.0, pointerCount: 1)
How to remove this position shift?

How to make suitable border and shadow for a widget created by CustomClipper

I have a Container widget inside of a ClipPath which uses a CustomClipper. Everything works fine, I have the desired widget shape.
However, I could not find a way to make a shadow for this custom shaped Widget.
Also, I want to have an outline(border) that follows the edges of this custom widget automatically.
Again no luck. I tried BoxDecoration:border, BoxDecoration:boxShadow, ShapeDecoration:shape, ShapeDecoration:shadows, Material:Elevation, etc..
based on #Bohdan Uhrynovskiy I investigated further and came up with this solution:
CustomPaint(
painter: BoxShadowPainter(),
child: ClipPath(
clipper: MyClipper(), //my CustomClipper
child: Container(), // my widgets inside
)));
class BoxShadowPainter extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
Path path = Path();
// here are my custom shapes
path.moveTo(size.width, size.height * 0.14);
path.lineTo(size.width, size.height * 1.0);
path.lineTo(size.width - (size.width *0.99) , size.height);
path.close();
canvas.drawShadow(path, Colors.black45, 3.0, false);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
You must need to provide your own custom paths in paint() method of BoxShadowPainter
Look at source code of the library. Feature implemented in this library seems very similar to your task.
You have to implement CustomPainter that draws shadows and borders.
return AspectRatio(
aspectRatio: 1.0,
child: CustomPaint(
painter: BoxShadowPainter(specs, boxShadows),
child: ClipPath(
clipper: Polygon(specs),
child: child,
)));

How to make flutter widgets adaptive to different screen sizes

I`m using width and height params of Container to determine widget size. but the widget is not adaptive if tested on other devices. I came from native android where i used to use density independent pixels(dp) that is adaptive to any screen size. what is the equivalent to dp in flutter ?
I dont want to use MediaQuery every time to calculate screen width and height.
You can use the SizeBox.expand widget to let your widget expand to take the available space regardless of size documentation
SizedBox.expand(
child:MyButton(),
),
And if you want to keep an aspect ratio regardless of screen size you can use the AspectRatio widget documentation
AspectRatio(
aspectRatio: 3/2,
child:MyButton(),
),
If your widgets are just in a row or column and you want to add weights among them to fill the spaces you can use the Expanded widget
Expanded(
flex: 1,//weight for the widget
child: Container(
color: Colors.amber,
height: 100,
),
)
,
You can set the size of your UI widgets this way:
width: 100.0 * MediaQuery.of(context).devicPixelRatio ,
the function MediaQuery.of(context).devicPixelRatio will return the actual number of pixel in each logical pixel, so you'll be sure that the same 100.0 pixel on your test device are typical to those of the user whatever screen density they have.
i applied this way :
class SizeConfig {
static MediaQueryData _mediaQueryData;
static double screenWidth;
static double screenHeight;
static double blockSizeHorizontal;
static double blockSizeVertical;
void init(BuildContext context) {
_mediaQueryData = MediaQuery.of(context);
screenWidth = _mediaQueryData.size.width;
screenHeight = _mediaQueryData.size.height;
blockSizeHorizontal = screenWidth / 100;
blockSizeVertical = screenHeight / 100;
}
}
class HomeScreen extends StatelessWidget { #override Widget
build(BuildContext context) { SizeConfig().init(context); … } }
#override
Widget build(BuildContext context) {
return Center(
child: Container(
height: SizeConfig.blockSizeVertical * 20,
width: SizeConfig.blockSizeHorizontal * 50,
color: Colors.orange,
),
);
}
https://medium.com/flutter-community/flutter-effectively-scale-ui-according-to-different-screen-sizes-2cb7c115ea0a

TextScaleFactor for TextField in Flutter?

Was wondering is there a way to control textscalefactor for TextField widget in flutter. Basically I want to limit a text field from growing too large when a user increase font/text size in their devices accessibility settings.
Thanks.
You can wrap it with a MediaQuery with a custom textScaleFactor
Widget build(BuildContext context) {
final mqData = MediaQuery.of(context);
final mqDataNew = mqData.copyWith(textScaleFactor: mqData.textScaleFactor > 5.0 ? 5.0 : mqData.textScaleFactor)
return MediaQuery(data: mqDataNew, child: TextField());
}
The TextField does not need to be a direct child of MediaQuery.
You can set lower and upper bounds for the textScaleFactor of your entire app.
return MaterialApp(
builder: (context, child) {
const lowerLimit = 1.0;
const upperLimit = 1.2;
final mediaQueryData = MediaQuery.of(context);
final scale = mediaQueryData.textScaleFactor.clamp(lowerLimit, upperLimit);
return MediaQuery(
child: child,
data: MediaQuery.of(context).copyWith(textScaleFactor: scale),
);
},
);

How do I rotate something 15 degrees in Flutter?

The Flutter docs show an example of rotating a "div" by 15 degrees, both for HTML/CSS and Flutter code:
The Flutter code is:
var container = new Container( // gray box
child: new Center(
child: new Transform(
child: new Text(
"Lorem ipsum",
),
alignment: FractionalOffset.center,
transform: new Matrix4.identity()
..rotateZ(15 * 3.1415927 / 180),
),
),
);
And the relevant parts are new Transform and alignment: FractionalOffset.center and transform: new Matrix4.identity()..rotateZ(15 * 3.1415927 / 180)
I'm curious, is there a simpler way to rotate a Container in Flutter? Is there a short-hand for the case of "15 degrees" ?
Thanks!
In mobile apps, I think it's kind of rare to have things start out rotated 15 degrees and just stay there forever. So that may be why Flutter's support for rotation is better if you're planning to adjust the rotation over time.
It feels like overkill, but a RotationTransition with an AlwaysStoppedAnimation would accomplish exactly what you want.
new RotationTransition(
turns: new AlwaysStoppedAnimation(15 / 360),
child: new Text("Lorem ipsum"),
)
If you want to rotate something 90, 180, or 270 degrees, you can use a RotatedBox.
new RotatedBox(
quarterTurns: 1,
child: new Text("Lorem ipsum")
)
You can use Transform.rotate to rotate your widget. I used Text and rotated it with 45˚ (π/4)
Example:
import 'dart:math' as math;
Transform.rotate(
angle: -math.pi / 4,
child: Text('Text'),
)
If you are working with a canvas (as in a CustomPaint widget), you can rotate 15 degrees like this:
import 'dart:math' as math;
class MyPainter extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
canvas.save();
// rotate the canvas
final degrees = 15;
final radians = degrees * math.pi / 180;
canvas.rotate(radians);
// draw the text
final textStyle = TextStyle(color: Colors.black, fontSize: 30);
final textSpan = TextSpan(text: 'Hello, world.', style: textStyle);
TextPainter(text: textSpan, textDirection: TextDirection.ltr)
..layout(minWidth: 0, maxWidth: size.width)
..paint(canvas, Offset(0, 0));
canvas.restore();
}
#override
bool shouldRepaint(CustomPainter old) {
return false;
}
}
However, if you are doing something simple then I would use a RotatedBox or Transform.rotate as suggested by the other answers.
There is Two Main Flutter Widget available for this functionality, RotationTransition and Transform.rotate
another supported option is RotatedBox but this rotate widget only
supports quarter turns, which means they support vertical and only horizontal orientation.
and if you rotate already created widgets like Container so for the container by transformAlignmentyou can rotate widget.
RotationTransition: which animates the rotation of a widget, mainly we prefer when we need rotation with animation transition.https://api.flutter.dev/flutter/widgets/RotationTransition-class.html
Transform.rotate: which applies a rotation paint effect, they Create a widget that transforms its child using a rotation around the center.
RotationTransition Widget example:-
RotationTransition(
turns: AlwaysStoppedAnimation(15 / 360),
child: Text("flutter is awesome")
)
Transform.rotate Widget example :-
Transform.rotate(
angle: 15 * math.pi / 180,
child: Text("flutter is awesome")
)
Container(
decoration: BoxDecoration(borderRadius: BorderRadius.circular(50), color: Color(0xffF6F8FF),),
width: MediaQuery.of(context).size.width*0.6,
height: MediaQuery.of(context).size.height*0.4,
alignment:
new Alignment(0, 0),
transform:
new Matrix4.translationValues(MediaQuery.of(context).size.width * 0.55, -250.0, 0.0)
..rotateZ(28 * 3.1415927 / 180),
),

Resources