Home > OS >  How to fit the text inside a specific area of custom clipPath
How to fit the text inside a specific area of custom clipPath

Time:02-01

I have created this UI enter image description here

the problem is right now that the text is not displayed fully. How can i put the text for example inside the upper part of the ui so that the text is not covered by the clipped area of the ui, so that it can ignore somehow the bottom part of the ui where i have marked as red container in this picture

enter image description here

this is my complete code

class QuoteWidget extends StatelessWidget {
  const QuoteWidget({super.key, required this.child});
  final Widget child;

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.only(top: 20),
      alignment: Alignment.center,
      child: AppCustomClipPath(
        shadow: Shadow(
          color: Colors.grey.withOpacity(0.5), //color of shadow
          blurRadius: 15, // blur radius
          offset: const Offset(0, 2),
        ),
        clipper: CustomQuotePainter(),
        child: Container(
          constraints: BoxConstraints(
            maxHeight: MediaQuery.of(context).size.height * 0.6,
            maxWidth: MediaQuery.of(context).size.width,
          ),
          color: Colors.white,
          padding: const EdgeInsets.only(
            bottom: 60,
            top: 15,
            left: 15,
            right: 15,
          ),
          child: Text(
            "Lorem Impsum Lorem Impsum Lorem Impsum Lorem Impsum  Lorem Impsum Lorem    Impsum Lorem Impsum Lorem Impsum Lorem Impsum Lorem Impsum Lorem Impsum Lorem Impsum Lorem       Impsum",
            style: Theme.of(context)
                .textTheme
                .displaySmall!
                .copyWith(color: Colors.black),
          ),
        ),
      ),
    );
  }
}

class CustomQuotePainter extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    Path path0 = Path();
    path0.moveTo(size.width * 0.0001600, size.height * 0.0004800);
    path0.lineTo(size.width * 1.0015800, size.height * -0.0002800);
    path0.lineTo(size.width * 1.0015800, size.height * 0.6996800);
    path0.lineTo(size.width * 0.4008200, size.height * 0.7007400);
    path0.lineTo(size.width * 0.2009700, size.height * 0.9068600);
    path0.lineTo(size.width * 0.2006800, size.height * 0.6992200);
    path0.lineTo(size.width * -0.0002100, size.height * 0.7003800);
    path0.lineTo(size.width * 0.0001600, size.height * 0.0004800);
    path0.close();

    return path0;
  }

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
    return false;
  }
}

@immutable
class AppCustomClipPath extends StatelessWidget {
  final Shadow? shadow;
  final CustomClipper<Path>? clipper;
  final Widget? child;

  const AppCustomClipPath({
    super.key,
    @required this.shadow,
    @required this.clipper,
    @required this.child,
  });

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      key: UniqueKey(),
      painter: _ClipShadowShadowPainter(
        clipper: clipper!,
        shadow: shadow!,
      ),
      child: ClipPath(child: child, clipper: this.clipper),
    );
  }
}

class _ClipShadowPainter extends CustomPainter {
  final Shadow? shadow;
  final CustomClipper<Path>? clipper;

  _ClipShadowPainter({@required this.shadow, @required this.clipper});

  @override
  void paint(Canvas canvas, Size size) {
    var paint = shadow!.toPaint();
    var clipPath = clipper!.getClip(size).shift(shadow!.offset);
    canvas.drawPath(clipPath, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}

CodePudding user response:

Try this ShapeBorder

class CustomShapeBorder extends ShapeBorder {
  @override
  EdgeInsetsGeometry get dimensions =>
      EdgeInsets.only(left: 8, right: 9, bottom: 20, top: 8); //todo

  @override
  Path getInnerPath(Rect rect, {TextDirection? textDirection}) {
    Path path0 = Path();
    path0.addRect(rect);
    Path bottomCurve = Path()
      ..moveTo(rect.bottomLeft.dx   rect.width * .2, rect.bottom)
      ..lineTo(rect.bottomLeft.dx   rect.width * .2, rect.bottom   40)
      ..lineTo(rect.bottomLeft.dx   rect.width * .2   80, rect.bottom);

    path0.close();
    return Path.combine(PathOperation.union, path0, bottomCurve);
  }

  @override
  Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
    return getInnerPath(rect);
  }

  @override
  void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) {}

  @override
  ShapeBorder scale(double t) => this;
}

And use it like

Container(
  constraints: BoxConstraints(
    maxHeight: MediaQuery.of(context).size.height * 0.6,
    maxWidth: MediaQuery.of(context).size.width,
  ),
  decoration:
      ShapeDecoration(shape: CustomShapeBorder(), color: Colors.green),
  child: Text(
    "Lorem Impsum Lorem Impsum Lorem Impsum Lorem Impsum  Lorem Impsum Lorem    Impsum Lorem Impsum Lorem Impsum Lorem Impsum Lorem Impsum Lorem Impsum Lorem Impsum Lorem       Impsum",
    style: Theme.of(context)
        .textTheme
        .displaySmall!
        .copyWith(color: Colors.black),
  ),
),
  • Related