gpt4 book ai didi

Flutter:倒置 ClipOval

转载 作者:IT老高 更新时间:2023-10-28 12:36:35 28 4
gpt4 key购买 nike

我是 Flutter 的新手,我正在尝试编写一个库来允许用户平移/缩放他们的个人资料图片。

为了使其视觉化,我想用“倒置”的 ClipOval 堆叠他们的图片,以显示边界。

到目前为止,这是我得到的结果:

enter image description here

这显示了边界,但这不是用户友好的,我想“反转” ClipOval,以便剪辑的中心“清晰”而外部变灰(类似于蒙版)。

有什么办法可以做到吗?

这是我目前的代码(部分来自 flutter_zoomable_image):

import 'dart:ui' as ui;
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

class ImagePanner extends StatefulWidget {
ImagePanner(this.image, {Key key}) : super(key: key);

/// The image to be panned
final ImageProvider image;

@override
_ImagePannerState createState() => new _ImagePannerState();
}

class _ImagePannerState extends State<ImagePanner> {
ImageStream _imageStream;
ui.Image _image;
double _zoom = 1.0;
Offset _offset = Offset.zero;
double _scale = 16.0;

@override
void didChangeDependencies() {
_resolveImage();
super.didChangeDependencies();
}

@override
void reassemble() {
_resolveImage();
super.reassemble();
}

@override
Widget build(BuildContext context) {
if (_image == null) {
return new Container();
}
return new Container(
width: double.INFINITY,
color: Colors.amber,
child: new Padding(
padding: new EdgeInsets.all(50.0),
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new AspectRatio(
aspectRatio: 1.0,
child: new Stack(
children: [
_child(),
new Opacity(
opacity: 0.5,
child: new ClipOval(
child: new Container(
color: Colors.black,
),
),
),
],
),
),
],
)),
);
}


Widget _child() {
Widget bloated = new CustomPaint(
child: new Container(),
painter: new _ImagePainter(
image: _image,
offset: _offset,
zoom: _zoom / _scale,
),
);

bloated = new Stack(
children: [
new Container(
),
bloated
],
);

return new Transform(
transform: new Matrix4.diagonal3Values(_scale, _scale, _scale),
child: bloated);
}

void _resolveImage() {
_imageStream = widget.image.resolve(createLocalImageConfiguration(context));
_imageStream.addListener(_handleImageLoaded);
}

void _handleImageLoaded(ImageInfo info, bool synchronousCall) {
print("image loaded: $info $synchronousCall");
setState(() {
_image = info.image;
});
}
}

class _ImagePainter extends CustomPainter {
const _ImagePainter({this.image, this.offset, this.zoom});

final ui.Image image;
final Offset offset;
final double zoom;

@override
void paint(Canvas canvas, Size size) {
paintImage(canvas: canvas, rect: offset & (size * zoom), image: image);
}

@override
bool shouldRepaint(_ImagePainter old) {
return old.image != image || old.offset != offset || old.zoom != zoom;
}
}

我想要获得的结果如下,以便用户可以直接看到边界,并能够在椭圆内居中、平移、缩放他们的个人资料图片。

enter image description here

(我是通过 Photoshop 制作的,因为我不知道如何使用 Flutter 来实现)

非常感谢您的帮助。

最佳答案

还有其他几种方法可以做到这一点 - 您可以使用具有圆形和矩形的路径在 CustomCanvas 中简单地绘制叠加层,因为您真正需要的是一个带有孔的矩形半透明矩形。但是您也可以使用 CustomClipper,它可以在将来为您提供更大的灵 active ,而无需手动绘制内容。

void main() {
int i = 0;
runApp(new MaterialApp(
home: new SafeArea(
child: new Stack(
children: <Widget>[
new GestureDetector(
onTap: () {
print("Tapped! ${i++}");
},
child: new Container(
color: Colors.white,
child: new Center(
child: new Container(
width: 400.0,
height: 300.0,
color: Colors.red.shade100,
),
),
),
),
new IgnorePointer(
child: new ClipPath(
clipper: new InvertedCircleClipper(),
child: new Container(
color: new Color.fromRGBO(0, 0, 0, 0.5),
),
),
)
],
),
),
));
}

class InvertedCircleClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
return new Path()
..addOval(new Rect.fromCircle(
center: new Offset(size.width / 2, size.height / 2),
radius: size.width * 0.45))
..addRect(new Rect.fromLTWH(0.0, 0.0, size.width, size.height))
..fillType = PathFillType.evenOdd;
}

@override
bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}

IgnorePointer 是必需的,否则事件不会通过半透明部分传播(假设您需要触摸事件)。

它的工作原理是clipPath使用的Path是一个中间的圆(你需要手动调整大小),一个矩形占据了整个大小。 fillType = PathFillType.evenOdd 很重要,因为它告诉路径的填充应该在圆形和矩形之间。

如果您想改用 customPainter,路径将相同,您只需绘制它即可。

这一切都会导致:enter image description here

关于Flutter:倒置 ClipOval,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49374893/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com