问题描述
我希望能够构建拼贴,为此我尝试使用 CustomPaint
绘制形状,然后用 image
填充该形状。这是我试过的:
Container(
height: 300,width: 300,decoration: Boxdecoration(
borderRadius: BorderRadius.circular(10.0),border: Border.all(color: Colors.white,width: 5),),child: CustomPaint(
painter: DrawTriangleShape(color: Colors.blue),child: Image.asset('assets/images/exampleImage.jpg'),
还有我的DrawTriangleShape
:
class DrawTriangleShape extends CustomPainter {
Paint painter;
DrawTriangleShape({color: Colors}) {
painter = Paint()
..color = color
..style = PaintingStyle.fill;
}
@override
void paint(Canvas canvas,Size size) {
var path = Path();
path.moveto(size.width / 1,0);
path.lineto(0,size.height);
path.lineto(size.height,size.width);
path.close();
canvas.drawPath(path,painter);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}
结果:
正如您所看到的,这并不是真正想要的结果,因为图像没有填充形状。我没有找到任何关于此的信息。甚至有可能吗?如果没有,使用自定义形状构建拼贴画的最佳方法是什么?
如果您需要更多信息,请告诉我!
解决方法
使用 CustomPaint
小部件代替 ClipPath
。
使用与您的 CustomPaint
相同的路径:
完整源代码
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,title: 'Flutter Demo',home: HomePage(),),);
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ClipPath(
clipper: CustomClipperImage(),child: Image.asset('images/abstract.jpg'),);
}
}
class CustomClipperImage extends CustomClipper<Path> {
@override
getClip(Size size) {
return Path()
..moveTo(size.width / 1,0)
..lineTo(0,size.height)
..lineTo(size.height,size.width)
..close();
}
@override
bool shouldReclip(CustomClipper oldClipper) {
return false;
}
}
带有白色边框和缩放图像的附加示例。
完整源代码
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,);
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final width = MediaQuery.of(context).size.width * .8;
final height = width * .7;
return Scaffold(
body: Container(
color: Colors.black54,child: Center(
child: Stack(
children: [
CustomPaint(
painter: MyPainter(),child: Container(width: width,height: height),ClipPath(
clipper: CustomClipperImage(),child: Transform.scale(
scale: 3,child: Image.asset('images/abstract.jpg',width: width,],);
}
}
class CustomClipperImage extends CustomClipper<Path> {
@override
getClip(Size size) {
return Path()
..moveTo(size.width,size.height)
..close();
}
@override
bool shouldReclip(CustomClipper oldClipper) {
return false;
}
}
class MyPainter extends CustomPainter {
@override
void paint(Canvas canvas,Size size) {
final path = Path()
..moveTo(size.width,size.height)
..close();
final paint = Paint()
..color = Colors.white
..strokeWidth = 8.0
..style = PaintingStyle.stroke;
canvas.drawPath(path,paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
对图像进行缩放和平移的解决方案
使用 GestureDetector
检测 scale
和 localFocalPoint
的变化。然后使用 Matrix4
Transform
我们的 Image.asset
:
完整源代码:
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,);
}
class HomePage extends HookWidget {
@override
Widget build(BuildContext context) {
final _width = MediaQuery.of(context).size.width * .8;
final _height = _width * .6;
final _zoom = useState<double>(1.0);
final _previousZoom = useState<double>(1.0);
final _offset = useState<Offset>(Offset.zero);
final _previousOffset = useState<Offset>(Offset.zero);
final _startingFocalPoint = useState<Offset>(Offset.zero);
return Scaffold(
body: Container(
color: Colors.black54,child: Center(
child: GestureDetector(
onScaleStart: (details) {
_startingFocalPoint.value = details.localFocalPoint;
_previousOffset.value = _offset.value;
_previousZoom.value = _zoom.value;
},onScaleUpdate: (details) {
_zoom.value = _previousZoom.value * details.scale;
final Offset normalizedOffset =
(_startingFocalPoint.value - _previousOffset.value) /
_previousZoom.value;
_offset.value =
details.localFocalPoint - normalizedOffset * _zoom.value;
},child: Stack(
children: [
CustomPaint(
painter: MyPainter(),child: Container(width: _width,height: _height),ClipPath(
clipper: CustomClipperImage(),child: Transform(
transform: Matrix4.identity()
..translate(_offset.value.dx,_offset.value.dy)
..scale(_zoom.value),// ..rotateZ(_rotation.value),child: Image.asset('images/milkyway.jpg',width: _width,paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}