How to draw SVG to an image? - flutter

I really need your help.
I'm pretty sure that using CustomPaint would be the solution here. but I can't find the source code of Flutter's CustomPaint video.
I'm also aware that I must use drawPath to achieve this. but I can't find any resources on how to convert my SVG to path.
my scenario is this:
I have an image, and I also have my SVG wrapped in Draggable so I can place it anywhere on the image.
I tried using RepaintBoundaries but it doesn't include the SVG even if I try to place it as a parent widget.
I'd appreciate any help.
EDIT :
I am converting specifically, A pdf file to images.
Stack(
children: <Widget>[
Positioned(
child: Text(
imageList.length == 0
? "$currentPage / --"
: "$currentPage / ${imageList.length}",
style: TextStyle(color: Colors.white),
),
top: 10,
right: 10,
),
FutureBuilder(
future: getDocument,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: FadingText(
'Rendering File ...',
style: TextStyle(color: Colors.black, fontSize: 20),
),
);
}
return CarouselSlider.builder(
itemCount: snapshot.data.length,
options: CarouselOptions(
viewportFraction: 1,
autoPlay: false,
aspectRatio: 0.5,
enableInfiniteScroll: false,
onPageChanged: (index, reason) {
setState(() {
currentPage = index + 1;
print(currentPage);
});
}),
itemBuilder: (context, index) {
return Container(
child: Image.memory(snapshot.data[index]),
);
},
);
}),
Positioned(
top: position.dy,
left: position.dx,
child: Center(
child: Container(
padding: EdgeInsets.all(10),
child: Draggable(
child: Container(
width: 120,
height: 70,
child: Center(
child: SvgPicture.asset("assets/signature.svg"),
),
),
childWhenDragging: Container(
width: 120,
height: 70,
child: Center(
child: Opacity(
opacity: 0.2,
child: SvgPicture.asset("assets/signature.svg"),
),
),
),
feedback: Container(
child: Center(
child: SvgPicture.asset("assets/signature.svg"),
),
width: 120,
height: 70,
),
onDraggableCanceled:
(Velocity velocity, Offset offset) {
setState(() => position = offset);
print(
"X Position : ${position.dx} | Y Position : ${position.dy}");
//_capturePng();
showDialog(
barrierDismissible: true,
context: context,
builder: (_) => ViewDocumentDialog(
x: double.parse((position.dx).toStringAsFixed(2)),
y: double.parse((position.dy).toStringAsFixed(2)),
images: encodeImageList,
page: currentPage,
),
);
},
),
),
),
)
],
)),

Related

How to keep my Curved Navigation Bar visible when navigating to another page?

I'm making this music app and when I click my image of the 3D Perspective PageView, the new page shows up well but the Curved Navigation Bar isn't showing up. I tired to find every resources on the internet but they are all saying about how to redirect with clicking the bottom nav bar.
This is my main.dart file
import 'package:flutter/material.dart';
import 'package:secondlife_mobile/bottomnavbar.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
//title: 'Twitch Player Example',
//title: 'Perspective PageView',
theme: ThemeData(
useMaterial3: true,
),
home: const BottomNavBar(),
);
}
}
And this is my home.dart file.
import 'package:flutter/material.dart';
import 'package:secondlife_mobile/PageViewHolder.dart';
import 'package:provider/provider.dart';
import 'package:secondlife_mobile/screens/artist_1.dart';
import 'package:secondlife_mobile/screens/artist_2.dart';
import 'package:secondlife_mobile/screens/artist_3.dart';
import 'package:secondlife_mobile/screens/artist_4.dart';
import 'package:url_launcher/url_launcher.dart';
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final PageStorageBucket bucket = PageStorageBucket();
late PageViewHolder holder;
late PageController _controller;
double fraction =
0.57; // By using this fraction, we're telling the PageView to show the 50% of the previous and the next page area along with the main page
Future<void> _launchURL(String url) async {
final Uri uri = Uri(scheme: "https", host: url);
if (!await launchUrl(
uri,
mode: LaunchMode.inAppWebView,
)) {
throw 'Can not launch url';
}
}
#override
void initState() {
super.initState();
holder = PageViewHolder(value: 2.0);
_controller = PageController(initialPage: 2, viewportFraction: fraction);
_controller.addListener(() {
holder.setValue(_controller.page);
});
}
int index = 1;
int currentIndex = 0;
final PageController controller = PageController();
List<String> images = [
"https://i.ytimg.com/vi/PWADVtWyE9Q/hq720.jpg?sqp=-oaymwEcCNAFEJQDSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDcneFqOxHd28mCncQxT3jOErmk9Q",
"https://i.ytimg.com/vi/djzDWMy1z7k/hq720.jpg?sqp=-oaymwEcCNAFEJQDSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCHwD_IA2ERzpZVxNvxCEOGr4fyTw",
"https://i.ytimg.com/vi/n8OxyKNBsuQ/hqdefault.jpg?sqp=-oaymwEcCOADEI4CSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAtW45_cxRqEWfUVw19UMts_9Q0lQ",
"https://i.ytimg.com/vi/7bDFD_WcU9I/hq720.jpg?sqp=-oaymwEcCNAFEJQDSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAsgAH6VRN4w0HKtVc528WA5QSZ2w",
"https://i.ytimg.com/vi/_ABk7TmjnVk/hq720.jpg?sqp=-oaymwEcCNAFEJQDSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAxCeIml0HUbjJ3igi1FFe1esdwdg",
"https://i.ytimg.com/vi/-8m0XFea2zE/hq720.jpg?sqp=-oaymwEcCNAFEJQDSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDBOBRGDJeDjhT1HbRobSN2Tp6hMA",
"https://i.ytimg.com/vi/mXLS2IzZSdg/hq720.jpg?sqp=-oaymwE2CNAFEJQDSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARhdIFsoZTAP&rs=AOn4CLDS13MjaIBxjjhccIktpAb0azBG9g",
"https://i.ytimg.com/vi/HuzlYAMwwJY/hq720.jpg?sqp=-oaymwEcCNAFEJQDSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCmfMS9RENZuIJMQ8k2cf6MbHIpug",
"https://i.ytimg.com/vi/-nt_u4vo-DI/hq720.jpg?sqp=-oaymwEcCNAFEJQDSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAgUinltWhU-qqmgc_JroDLPt3OEg",
"https://i.ytimg.com/vi/tqtZIyN_Alg/hq720.jpg?sqp=-oaymwEcCNAFEJQDSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLD4woxvyiNXgmSile7PLz7uoRPQOQ",
];
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
backgroundColor: const Color.fromARGB(255, 223, 234, 244),
appBar: AppBar(
backgroundColor: Colors.transparent,
centerTitle: true,
title: const Text('AppBar'),
),
body: SingleChildScrollView(
child: SizedBox(
height: MediaQuery.of(context).size.height,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 30,
),
const Padding(
padding: EdgeInsets.symmetric(horizontal: 35),
child: Text(
'Playlist for you',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w400,
),
),
),
const SizedBox(height: 15),
Container(
child: Center(
child: AspectRatio(
aspectRatio: 1,
child: ChangeNotifierProvider<PageViewHolder>.value(
value: holder,
child: PageView.builder(
controller: _controller,
itemCount: 4,
physics: const BouncingScrollPhysics(),
itemBuilder: (context, index) {
if (index == 0) {
return InkWell(
//you should use InkWell for onTap or thing like that!!!
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const FirstArtist(),
),
);
},
child: MyPage(
number: index.toDouble(),
fraction: fraction,
),
);
}
if (index == 1) {
return InkWell(
//you should use InkWell for onTap or thing like that!!!
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const SecondArtist(),
),
);
},
child: MyPage(
number: index.toDouble(),
fraction: fraction,
),
);
}
if (index == 2) {
return InkWell(
//you should use InkWell for onTap or thing like that!!!
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const ThirdArtist(),
),
);
},
child: MyPage(
number: index.toDouble(),
fraction: fraction,
),
);
}
if (index == 3) {
return InkWell(
//you should use InkWell for onTap or thing like that!!!
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const FourthArtist(),
),
);
},
child: MyPage(
number: index.toDouble(),
fraction: fraction,
),
);
} else {
return const Text("Can't find anything");
}
},
),
),
),
),
),
Transform.translate(
offset: const Offset(0, -85),
child: const Padding(
padding: EdgeInsets.symmetric(horizontal: 35),
child: Text(
'Watch videos',
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.w600,
),
),
),
),
//https://www.youtube.com/watch?v=7a_RXHOkJLM
//https://github.com/Programmer9211/Flutter-Carousel-Slider/blob/main/lib/main.dart
Transform.translate(
offset: const Offset(0, -65),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
alignment: Alignment.center,
child: SizedBox(
height: 162,
width: 335,
child: PageView.builder(
controller: controller,
onPageChanged: (index) {
setState(() {
currentIndex = index % images.length;
});
},
itemBuilder: (context, index) {
return InkWell(
//you should use InkWell for onTap or thing like that!!!
onTap: () {
print("Tapped watch Videos Imageeeee");
},
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 35),
child: SizedBox(
height: 100,
width: 400,
child: Image.network(
images[index % images.length],
fit: BoxFit.fill,
),
),
),
);
},
),
),
),
],
),
),
////Your Playlist of the week text
Transform.translate(
offset: const Offset(0, -30),
child: const Padding(
padding: EdgeInsets.symmetric(horizontal: 35),
child: Text(
'Playlist of the week',
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.w600,
),
),
),
),
Transform.translate(
offset: const Offset(0, -15),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 35),
child: SingleChildScrollView(
child: Column(
children: [
SizedBox(
height: 150,
child: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
GestureDetector(
onTap: () {
_launchURL("www.google.com");
},
child: SizedBox(
height: 180.0,
width: 220.0,
child: Image.asset(
'assets/images/album1.jpg',
height: 180.0,
width: 220.0,
),
),
),
const SizedBox(
width: 30,
),
GestureDetector(
onTap: () {
_launchURL("www.google.com");
},
child: SizedBox(
height: 180.0,
width: 220.0,
child: Image.asset(
'assets/images/album2.jpg',
height: 180.0,
width: 220.0,
),
),
),
const SizedBox(
width: 30,
),
GestureDetector(
onTap: () {
_launchURL("www.google.com");
},
child: SizedBox(
height: 160.0,
width: 200.0,
child: Image.asset(
'assets/images/album3.jpg',
height: 160.0,
width: 200.0,
),
),
),
const SizedBox(
width: 30,
),
GestureDetector(
onTap: () {
_launchURL("www.google.com");
},
child: SizedBox(
height: 160.0,
width: 200.0,
child: Image.asset(
'assets/images/album4.jpg',
height: 160.0,
width: 200.0,
),
),
),
const SizedBox(
width: 30,
),
GestureDetector(
onTap: () {
_launchURL("www.google.com");
},
child: SizedBox(
height: 160.0,
width: 200.0,
child: Image.asset(
'assets/images/album5.jpg',
height: 160.0,
width: 200.0,
),
),
),
],
),
),
],
),
),
),
),
],
),
),
),
),
);
}
}
class MyPage extends StatelessWidget {
final number;
final double? fraction;
const MyPage({super.key, this.number, this.fraction});
#override
Widget build(BuildContext context) {
double? value = Provider.of<PageViewHolder>(context).value;
double diff = (number - value);
// diff is negative = left page
// diff is 0 = current page
// diff is positive = next page
//Matrix for Elements
final Matrix4 pvMatrix = Matrix4.identity()
..setEntry(3, 2, 1 / 0.9) //Increasing Scale by 90%
..setEntry(1, 1, fraction!) //Changing Scale Along Y Axis
..setEntry(3, 0, 0.004 * -diff); //Changing Perspective Along X Axis
final Matrix4 shadowMatrix = Matrix4.identity()
..setEntry(3, 3, 1 / 1.6) //Increasing Scale by 60%
..setEntry(3, 1, -0.004) //Changing Scale Along Y Axis
..setEntry(3, 0, 0.002 * diff) //Changing Perspective along X Axis
..rotateX(1.309); //Rotating Shadow along X Axis
return Stack(
fit: StackFit.expand,
alignment: FractionalOffset.center,
children: [
Transform.translate(
offset: const Offset(0.0, -47.5),
child: Transform(
transform: pvMatrix,
alignment: FractionalOffset.center,
child: Container(
decoration: BoxDecoration(boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
blurRadius: 11.0,
spreadRadius: 4.0,
offset: const Offset(
13.0, 35.0), // shadow direction: bottom right
)
]),
child: Image.asset(
"assets/images/image_${number.toInt() + 1}.jpg",
fit: BoxFit.fill),
),
),
),
],
);
}
}
There is a package called persistent_bottom_nav_bar 5.0.2.
Step1: Create a new StatefulWidget called PersistentNavBar that contains the CurvedNavigationBar widget:
Step2: Wrap your entire app with a PageView and set its children to the pages you want to navigate to. For each page, you can set its bottomNavigationBar to the PersistentNavBar widget.

images not taking full width in carousel

i created a carousel containing three different images. the problem is these images are not taking the full length of my current screen. i have tried setting the width in the image and even setting the aspect ratio and viewport in carousel options but the outcome is still the same. help would be very much appreciated. here is the code.
final List<Widget> _images = [
Stack(
children: [
Image.asset('assets/images/image 10.png'),
Padding(
padding: const EdgeInsets.only(left: 55.0, top: 230),
child: Text(
'Luxury \n Fashion \n &Accessories'.toUpperCase(),
style: TextStyle(
fontFamily: 'Bodoni',
fontSize: 40,
fontWeight: FontWeight.w500,
color: Colors.grey.shade700
),
),
),
Padding(
padding: const EdgeInsets.only(top: 400.0),
child: Center(
child:SvgPicture.asset('assets/iconImages/Button.svg'),
),
),
],
),
Image.asset('assets/images/leeloo.jpeg', width: double.infinity,),
Image.asset('assets/images/ayaka.jpeg', width: double.infinity,),
];
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 5,
child: Column(
children: [
Stack(
children: [
CarouselSlider.builder(
options: CarouselOptions(
viewportFraction: 1,
aspectRatio: 16/9,
height: MediaQuery.of(context).size.height*0.78,
autoPlay: false,
initialPage: 0,
enableInfiniteScroll: false,
enlargeCenterPage: true,
onPageChanged: (index, reason){
setState(() {
_activeIndex = index;
});
}
),
itemCount: _images.length,
itemBuilder: (BuildContext context, int index, int realIndex) {
return GestureDetector(
onTap: (){
Navigator.of(context).pushNamedAndRemoveUntil(BlackScreen.routeName, (route) => false);
},
child: Align(
alignment: Alignment.bottomCenter,
child:Container(
child: _images[index]
),
),
);
},
),
Set fit to your image like this:
Image.asset('assets/images/leeloo.jpeg', width: double.infinity,fit: BoxFit.cover),
Please try this
FittedBox(
child: Image.asset('foo.png'),
fit: BoxFit.fill,
)

Strange behavior of Flutter ImageFilter.blur

When I use this, the edges of the container are rendered incorrectly (blurred white edges)
Here is the screenshot
Only the image is blurry (centered), but for some reason a blurry white line is displayed at the very top.
Any help is welcome.
Here is the code
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.black,
toolbarHeight: 0,
elevation: 0,
),
body: SafeArea(
child: StatefulBuilder(builder: (ctx, _setState) {
return ColoredBox(
color: Colors.black,
child: Align(
alignment: Alignment.center,
child: GestureDetector(
onVerticalDragEnd: (details) {
if (details.velocity.pixelsPerSecond.dy < -100 ||
details.velocity.pixelsPerSecond.dy > 100) {
Get.back();
}
},
child: CarouselSlider(
options: CarouselOptions(
viewportFraction: 1,
height: double.infinity,
enableInfiniteScroll: false,
disableCenter: true,
autoPlayCurve: Curves.bounceOut,
initialPage: widget.activeSlide,
onPageChanged: (page, _reason) {
_setState(() => widget.activeSlide = page);
},
scrollPhysics: kDefaultScrollPhysics
),
items: widget.post.images.map((image) {
return Builder(
builder: (BuildContext context) => Stack(
children: [
Center(
child: Image.network(
ApiConfig.ensureUrl(image.original) + image.original,
width: double.infinity,
fit: BoxFit.cover,
),
),
Center(
child: ClipRect(
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5),
child: Container(
decoration: BoxDecoration(color: Colors.white.withOpacity(0.0)),
),
),
),
),
Center(
child: Image.network(
ApiConfig.ensureUrl(image.original) + image.original,
fit: BoxFit.contain,
),
),
],
),
);
}).toList(),
),
),
));
}),
),
);
I expect the image to blur correctly and the edges of the container to be completely black (like its background)

Draggable object cannot be moved in DragTarget widget flutter

I am trying to move/drag drop widget inside DragTarget but don't know what is the issue. Here is my code:
return Scaffold(
drawer: DrawerWidget(),
appBar: AppBar(
backgroundColor: Colors.white,
title: Text(
'Table Layout',
style: Theme.of(context).textTheme.title.merge(
TextStyle(letterSpacing: 1.3),
),
),
centerTitle: true,
elevation: 0,
),
body: Container(
child: Row(
children: [
Container(
color: Colors.blue[100],
width: MediaQuery.of(context).size.width * 0.30,
child: ListView.separated(
padding: const EdgeInsets.all(16.0),
itemCount: 3,
separatorBuilder: (context, index) {
return const SizedBox(
height: 12.0,
);
},
itemBuilder: (context, index) {
return Draggable<String>(
data: images[index],
dragAnchor: DragAnchor.pointer,
feedback: MenuListItem(
photoProvider: images[index],
),
child: MenuListItem(
photoProvider: images[index],
),
);
},
),
),
Expanded(
child: Container(
height: double.infinity,
width: double.infinity,
color: Colors.grey,
child: DragTarget<String>(
builder: (context, candidateItems, rejectedItems) {
return Stack(
children: targetList.map((image) {
return Draggable<String>(
data: image,
dragAnchor: DragAnchor.pointer,
childWhenDragging: Container(),
feedback: MenuListItem(
photoProvider: image,
),
child: MenuListItem(
photoProvider: image,
),
);
}).toList(),
);
},
onWillAccept: (data) {
return true;
},
onAccept: (item) {
},
),
),
),
],
),
),
);
When I run the app the element appears at the top left corner. I am trying to place that widget anywhere inside DragTarget by dragging but after dragging it return to its original place.
Can anyone help me please.
Thanks

How to change position of Container inside Stack?

Im trying to displaying a button inside my stack but it not getting the correct position. The button is the reply Button . I added a foot how it looks at the moment you can check it what I want is displaying it on the right side of the window at the bottom with a bit of spacing between bottom and the button.
Hope anyone can help. if you need more information please leave a comment .
#override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
try {
return Scaffold(
body: StreamBuilder(
stream: mystreamofallvideos,
builder: (context, snapshot) {
if (snapshot.hasData &&
snapshot.connectionState != ConnectionState.waiting) {
return PageView.builder(
itemCount: snapshot.data.docs.length,
controller:
PageController(initialPage: 0, viewportFraction: 1),
scrollDirection: Axis.vertical,
itemBuilder: (context, index) {
DocumentSnapshot videos = snapshot.data.docs[index];
return Stack(children: [
Videoplayeritem(widget.videoid),
Column(children: [
Align(
alignment: Alignment.bottomLeft,
child: Container(
height: 100,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
IconButton(
icon: Icon(
Icons.close,
color: Colors.white,
size: 35,
),
onPressed: () {
Navigator.of(context).pop();
}),
SizedBox(
width: 190,
),
],
),
),
),
Container(
color: Colors.red,
width: 210,
height: 94,
//color: Colors.blue.withOpacity(0.5),
child: InkWell(
onTap: () => sharevideo(
widget.videoid, videos.data()['id']),
child: Icon(Icons.reply,
size: 55, color: Colors.white),
),
),
]),
//starssonthe right
]);
});
} else {
return Center(child: CircularProgressIndicator());
}
}),
);
} catch (e) {
e.toString();
}
}
}
This is how it looks
enter image description here
Wrap it in an align and add a padding to the bottom:
Align(
alignment: Alignment.bottomRight,
child: Container(
height: 40,
padding: const EdgeInsets.only(bottom: 16),
child: OutlinedButton(
onPressed: () {},
child: Text('mybutton'),
),
)
you can wrap your container with either Positioned or Align widgets
like :
Positioned(
top: 0.0,
left: 0.0,
child: Icon(Icons.message,
size: 128.0, color: Colors.greenAccent[400]), //Icon
),