I made a container in which we scale, rotate, and shrink the widget but I want to limit the scale and shrink factor.
Here is my code.
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
File imageMock;
class StoryKaran extends StatefulWidget {
@override
_StoryKaranState createState() => _StoryKaranState();
}
class _StoryKaranState extends State<StoryKaran> {
EditableItem _activeItem;
Offset _initPos;
Offset _currentPos;
Size screenSize;
double _currentScale;
double _currentRotation;
bool _inAction = false;
File _image;
final picker = ImagePicker();
@override
void initState() {
super.initState();
setState(() {
imageMock = _image;
});
}
Future getImage() async {
final pickedFile = await picker.getImage(source: ImageSource.camera);
setState(() {
if (pickedFile != null) {
_image = File(pickedFile.path);
} else {
print('No image selected.');
}
});
}
@override
Widget build(BuildContext context) {
final screen = MediaQuery.of(context).size;
setState(() {
screenSize = screen;
});
return Scaffold(
appBar: AppBar(
title: Text('Image Picker Example'),
),
body: GestureDetector(
onScaleStart: (details) {
if (_activeItem == null) return;
_initPos = details.focalPoint;
_currentPos = _activeItem.position;
_currentScale = _activeItem.scale;
_currentRotation = _activeItem.rotation;
},
onScaleUpdate: (details) {
if (_activeItem == null) return;
final delta = details.focalPoint - _initPos;
final left = (delta.dx / screen.width) + _currentPos.dx;
final top = (delta.dy / screen.height) + _currentPos.dy;
setState(() {
_activeItem.position = Offset(left, top);
_activeItem.rotation = details.rotation + _currentRotation;
_activeItem.scale = details.scale * _currentScale;
});
},
child: Stack(
children: [
Container(color: Colors.black26),
...mockData.map(_buildItemWidget).toList(),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: getImage,
tooltip: 'Pick Image',
child: Icon(Icons.add_a_photo),
),
);
}
Widget _buildItemWidget(EditableItem e) {
var widget;
switch (e.type) {
case ItemType.Text:
widget = Text(
e.value.toString(),
style: TextStyle(color: Colors.white),
);
break;
case ItemType.Image:
widget = Container(
width: screenSize.width,
height: screenSize.height,
child: _image == null
? Center(
child: new Text('No image selected.'),
)
: Image.file(_image, fit: BoxFit.cover),
);
}
return Positioned(
top: e.position.dy * screenSize.height,
left: e.position.dx * screenSize.width,
child: Transform.scale(
scale: e.scale,
child: Transform.rotate(
angle: e.rotation,
child: Listener(
onPointerDown: (details) {
if (_inAction) return;
_inAction = true;
_activeItem = e;
_initPos = details.position;
_currentPos = e.position;
_currentScale = e.scale;
_currentRotation = e.rotation;
},
onPointerUp: (details) {
_inAction = false;
},
child: widget,
),
),
),
);
}
}
enum ItemType { Image, Text }
class EditableItem {
Offset position = Offset(0.0, 0.0);
double scale = 1.0;
double rotation = 0.0;
ItemType type;
File value;
}
final mockData = [
EditableItem()
..type = ItemType.Image
..value = imageMock,
// EditableItem()
// ..type = ItemType.Text
// ..value = 'Hello',
// EditableItem()
// ..type = ItemType.Text
// ..value = 'World',
];