我有一个图像(蓝色矩形)。我想通过路径(红色三角形)剪切图像的一部分,并创建一个较小的小部件(绿色矩形),显示图像的这一部分,其大小等于剪切路径的边界。我如何在Flutter中做到这一点?
我尝试使用ClipPath和CustomClipper<Path>,但我只能创建具有图像大小的小部件。
ClipPath
CustomClipper<Path>
jaql4c8m1#
由于您没有提供任何代码,我假设您希望拥有基于当前子对象小部件。如果是,您可以尝试IntrinsicWidth和IntrinsicHeight小部件。https://api.flutter.dev/flutter/widgets/IntrinsicWidth-class.htmlIntrinsicWidgth:创建一个小部件,该小部件将其子级的大小调整为该子级的固有宽度。此类非常有用,例如,当无限制宽度可用,而您希望将原本会尝试无限扩展的子级改为将其自身调整为更合理的宽度时。使用此小部件,将根据固有大小使用呈现子对象。
IntrinsicWidth
IntrinsicHeight
IntrinsicWidgth
oewdyzsn2#
你可以使用CustomPainter和drawAtlas,performant,显示图像的一部分。
CustomPainter
wwwo4jvm3#
我找到了这个解决方案:
import 'dart:typed_data'; import 'dart:ui' as ui; import 'package:flutter/material.dart'; class MyWidget extends StatelessWidget { final ui.Image _uiImage; final Path _clipPath; const MyWidget({ Key? key, required ui.Image uiImage, required Path clipPath, }) : _uiImage = uiImage, _clipPath = clipPath, super(key: key); @override Widget build(BuildContext context) { final bounds = _clipPath.getBounds(); final translateM = Float64List.fromList([ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -bounds.left, -bounds.top, 0, 1 ]); final localClipPath = _clipPath.transform(translateM); return ClipPath( clipper: _MyClipper(localClipPath), child: CustomPaint( painter: _MyPainter(_uiImage, bounds), child: SizedBox( width: bounds.width, height: bounds.height, ), ), ); } } class _MyClipper extends CustomClipper<Path> { final Path _clipPath; _MyClipper(this._clipPath); @override Path getClip(Size size) => _clipPath; @override bool shouldReclip(covariant CustomClipper<Path> oldClipper) => true; } class _MyPainter extends CustomPainter { final ui.Image _uiImage; final Rect _bounds; final _paint = Paint(); _MyPainter(this._uiImage, this._bounds); @override void paint(Canvas canvas, Size size) { canvas.drawAtlas( _uiImage, [ RSTransform.fromComponents( rotation: 0.0, scale: 1.0, // Center of the sprite relative to its rect anchorX: _bounds.width / 2, anchorY: _bounds.height / 2, // Location at which to draw the center of the sprite translateX: _bounds.width / 2, translateY: _bounds.height / 2, ) ], [_bounds], null, null, null, _paint, ); } @override bool shouldRepaint(_MyPainter oldDelegate) => false; }
3条答案
按热度按时间jaql4c8m1#
由于您没有提供任何代码,我假设您希望拥有基于当前子对象小部件。
如果是,您可以尝试
IntrinsicWidth
和IntrinsicHeight
小部件。https://api.flutter.dev/flutter/widgets/IntrinsicWidth-class.htmlIntrinsicWidgth
:创建一个小部件,该小部件将其子级的大小调整为该子级的固有宽度。
此类非常有用,例如,当无限制宽度可用,而您希望将原本会尝试无限扩展的子级改为将其自身调整为更合理的宽度时。
使用此小部件,将根据固有大小使用呈现子对象。
oewdyzsn2#
你可以使用
CustomPainter
和drawAtlas,performant,显示图像的一部分。wwwo4jvm3#
我找到了这个解决方案: