-1

I have an image (blue rect). I want to cut a part of the image by path (red triangle) and create a smaller widget (green rect) that shows this part of the image and has size which equals bounds of cutting path. How can I do it in Flutter?

Example

I tried to use ClipPath and CustomClipper<Path>, but I was able to create only widget which has size of the image.

acbelter
  • 447
  • 5
  • 10

3 Answers3

0

since you are not provide any code, I assume you want to have widget based on current child.

if yes, you may try IntrinsicWidth and IntrinsicHeight widget. https://api.flutter.dev/flutter/widgets/IntrinsicWidth-class.html

IntrinsicWidgth:

Creates a widget that sizes its child to the child's intrinsic width.

This class is useful, for example, when unlimited width is available and you would like a child that would otherwise attempt to expand infinitely to instead size itself to a more reasonable width.

With this widget, the child will rendered with based on intrinsic size.

pmatatias
  • 3,491
  • 3
  • 10
  • 30
0

you can use CustomPainter with drawAtlas , performant, show part of the image. I use this to make animation like sprites Animation

Sayyid J
  • 1,215
  • 1
  • 4
  • 18
0

I found this solution:

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;
}
acbelter
  • 447
  • 5
  • 10