Image clip using the container position in flutter

ghz 8months ago ⋅ 53 views

In this code one image container with black border and on this container one movable container using the movable container when click save button clip the image of using the movable container top and left position.

but when click on save button not clip image in proper way how to solve this?

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Image with Movable Container on Double Tap'),
        ),
        body: Center(
          child: MyImageWidget(),
        ),
        bottomNavigationBar: BottomAppBar(
          child: Padding(
            padding: EdgeInsets.all(16.0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,

            ),
          ),
        ),
      ),
    );
  }
}

class MyImageWidget extends StatefulWidget {
  @override
  _MyImageWidgetState createState() => _MyImageWidgetState();
}

class _MyImageWidgetState extends State<MyImageWidget> {
  bool showContainer = false;
  // Offset containerPosition = Offset(50, 100);
  double top = 100;
  double left = 50;
  double width = 300;
  double hight = 200;
  double foretop = 100;
  double foreleft = 50;
  double forewidth = 100;
  double foreheight = 100;
  double cliptop = 0;
  double clipleft = 0;
  double clipheight = 200;
  double clipwidth = 300;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        setState(() {
          showContainer = !showContainer;
        });
      },
      onDoubleTap: () {
        setState(() {
          showContainer = !showContainer;
        });
      },
      onPanUpdate: (details) {
        setState(() {
          foreleft += details.delta.dx;
          foretop += details.delta.dy;
        });
      },
      child: Stack(
        children: [
          Positioned(
              top: top,
              left: left,
        child:  Container(
            decoration: BoxDecoration(
              border: Border.all(
                color: Colors.black, // Border color
                width: 2.0, // Border width
              ),
            ),
            child :ClipRect(
              clipper: MyCustomClipper( clipleft, cliptop, clipwidth, clipheight),
            child: Image.asset(
              'images/rose1.png', // URL to your image
              width: width, // Width of the image
              height: hight, // Height of the image
              fit: BoxFit.cover, // Adjust the image within the container
            ),
          ),
        ),
      ),
          if (showContainer)
            Positioned(
              left: foreleft,
              top: foretop,
              child: Container(
                width: forewidth,
                height: foreheight,
                decoration: BoxDecoration(border: Border.all(color: Colors.black)),
              ),
            ),
          Positioned(
            bottom: 20,
            right: 20,
            child: ElevatedButton(
              onPressed: () {
                setState(() {
                  clipheight =  foreheight;
                  clipwidth = forewidth;
                  cliptop = foretop;
                  clipleft =  foreleft;
                  width = forewidth;
                  hight = foreheight;
                  top = foretop;
                  left = foreleft;
                 
                });
              },
              child: Text('Save'),
            ),
          ),
        ],
      ),
    );
  }
}
class MyCustomClipper extends CustomClipper<Rect> {
  // Define the left, top, width, and height of the clipping region
  final double left;
  final double top;
  final double width;
  final double height;

  MyCustomClipper(this.left, this.top, this.width, this.height);

  @override
  Rect getClip(Size size) {
    return Rect.fromLTWH(left, top, width, height);
  }

  @override
  bool shouldReclip(covariant CustomClipper<Rect> oldClipper) {
    return true;
  }
}

In this code one image container with black border and on this container one movable container using the movable container when click save button clip the image of using the movable container top and left position.

but when click on save button not clip image in proper way how to solve this?

enter image description here enter image description here

Answers

To properly clip the image based on the position of the movable container, you need to calculate the clipping parameters correctly. Currently, your code sets the clipping parameters directly to the position and size of the movable container, which may not produce the desired result.

Instead, you should calculate the clipping parameters based on the relative position of the movable container within the image container. Here's how you can modify your code to achieve this:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Image with Movable Container on Double Tap'),
        ),
        body: Center(
          child: MyImageWidget(),
        ),
        bottomNavigationBar: BottomAppBar(
          child: Padding(
            padding: EdgeInsets.all(16.0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
            ),
          ),
        ),
      ),
    );
  }
}

class MyImageWidget extends StatefulWidget {
  @override
  _MyImageWidgetState createState() => _MyImageWidgetState();
}

class _MyImageWidgetState extends State<MyImageWidget> {
  bool showContainer = false;
  double top = 100;
  double left = 50;
  double width = 300;
  double height = 200;
  double movableTop = 100;
  double movableLeft = 50;
  double movableWidth = 100;
  double movableHeight = 100;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        setState(() {
          showContainer = !showContainer;
        });
      },
      onDoubleTap: () {
        setState(() {
          showContainer = !showContainer;
        });
      },
      onPanUpdate: (details) {
        setState(() {
          movableLeft += details.delta.dx;
          movableTop += details.delta.dy;
        });
      },
      child: Stack(
        children: [
          Positioned(
            top: top,
            left: left,
            child: Container(
              decoration: BoxDecoration(
                border: Border.all(
                  color: Colors.black,
                  width: 2.0,
                ),
              ),
              child: ClipRect(
                clipper: MyCustomClipper(movableLeft - left, movableTop - top,
                    movableWidth, movableHeight),
                child: Image.asset(
                  'images/rose1.png',
                  width: width,
                  height: height,
                  fit: BoxFit.cover,
                ),
              ),
            ),
          ),
          if (showContainer)
            Positioned(
              left: movableLeft,
              top: movableTop,
              child: GestureDetector(
                onPanUpdate: (details) {
                  setState(() {
                    movableLeft += details.delta.dx;
                    movableTop += details.delta.dy;
                  });
                },
                child: Container(
                  width: movableWidth,
                  height: movableHeight,
                  decoration: BoxDecoration(
                    border: Border.all(color: Colors.black),
                  ),
                ),
              ),
            ),
          Positioned(
            bottom: 20,
            right: 20,
            child: ElevatedButton(
              onPressed: () {
                setState(() {
                  // Update the clipping parameters
                  width = movableWidth;
                  height = movableHeight;
                  top = movableTop;
                  left = movableLeft;
                });
              },
              child: Text('Save'),
            ),
          ),
        ],
      ),
    );
  }
}

class MyCustomClipper extends CustomClipper<Rect> {
  final double left;
  final double top;
  final double width;
  final double height;

  MyCustomClipper(this.left, this.top, this.width, this.height);

  @override
  Rect getClip(Size size) {
    return Rect.fromLTWH(left, top, width, height);
  }

  @override
  bool shouldReclip(covariant CustomClipper<Rect> oldClipper) {
    return true;
  }
}

In this modified code, the clipping parameters are calculated relative to the position of the movable container within the image container. This ensures that the clipped region corresponds to the position of the movable container.