只想在 CustomClipper 边框上添加标高,而不是在下面的整个材质上添加标高

2023-12-30

我正在尝试使用材质的标高在自定义路径上添加标高,但看起来没有这样做 任何东西,我都尝试过其他方法,但得到了整个材料(矩形)的高度。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Colors.pink[300],
        body: Column(
          children: <Widget>[
            TopContainer(),
          ],
        ));
  }
}

class TopContainer extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ClipPath(
        clipper: ImageClipper(),
        child: Material(
          elevation: 15.0,
          child: Container(
            decoration: BoxDecoration(
              image: DecorationImage(
                fit: BoxFit.cover,
                image: NetworkImage(
                  'https://images.pexels.com/photos/3309467/pexels-photo-3309467.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260',
                ),
              ),
            ),
            constraints: BoxConstraints.expand(
              width: double.infinity,
              height: MediaQuery.of(context).size.height * 0.5,
            ),
          ),
        ));
  }
}

class ImageClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    var path = Path();
    path.lineTo(0.0, size.height);
    var firstControlPoint = Offset(size.width * 0.35, size.height * 0.75);
    var firstEndPoint = Offset(size.width * 0.65, size.height * 0.85);
    path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy,
        firstEndPoint.dx, firstEndPoint.dy);
    ///////////////////////////////////////////////
    var secondControlPoint = Offset(size.width * 0.85, size.height * 0.90);
    var secondEndPoint = Offset(size.width, size.height * 0.75);
    path.quadraticBezierTo(secondControlPoint.dx, secondControlPoint.dy,
        secondEndPoint.dx, secondEndPoint.dy);

    //    path.lineTo(size.width, size.height * 0.9);
    path.lineTo(size.width, 0.0);
    path.close();
    return path;
  }

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

我尝试使用材质的标高在自定义路径上添加标高,但看起来没有执行任何操作,我尝试了其他方法,但在整个材质(矩形)上获得了标高。


使用那个习惯ShapeBorder

class WaveShapeBorder extends ShapeBorder {
  @override EdgeInsetsGeometry get dimensions => EdgeInsets.zero;
  @override ui.Path getInnerPath(ui.Rect rect, {ui.TextDirection textDirection}) => null;

  @override
  ui.Path getOuterPath(ui.Rect rect, {ui.TextDirection textDirection}) {
    var ctrl1 = FractionalOffset(0.35, 0.75).withinRect(rect);
    var end1  = FractionalOffset(0.65, 0.85).withinRect(rect);
    var ctrl2 = FractionalOffset(0.85, 0.90).withinRect(rect);
    var end2  = FractionalOffset(1.0,  0.75).withinRect(rect);
    return Path()
      ..moveTo(rect.topLeft.dx, rect.topLeft.dy)
      ..lineTo(rect.bottomLeft.dx, rect.bottomLeft.dy)
      ..quadraticBezierTo(ctrl1.dx, ctrl1.dy, end1.dx, end1.dy)
      ..quadraticBezierTo(ctrl2.dx, ctrl2.dy, end2.dx, end2.dy)
      ..lineTo(rect.topRight.dx, rect.topRight.dy)
      ..close();
  }

  @override void paint(ui.Canvas canvas, ui.Rect rect, {ui.TextDirection textDirection}) {}
  @override ShapeBorder scale(double t) => this;
}

以及用于测试的示例代码:

class WaveShapeBorderTest extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        gradient: LinearGradient(
          colors: [Colors.teal, Colors.green],
          begin: Alignment.topRight,
          end: Alignment.centerLeft,
        ),
      ),
      child: Stack(
        children: [
          Material(
            elevation: 6,
            shape: WaveShapeBorder(),
            clipBehavior: Clip.antiAlias,
            child: Image.asset('images/someImage.png'),
          ),
        ],
      ),
    );
  }
}

当然,你可以自由选择如何使用它,但主要思想是使用Material.shape and Material.clipBehavior特性

这是最终结果:

EDIT如果您认为您的阴影太“亮”,您可以添加一个额外的阴影Container使用自定义阴影:

class WaveShapeBorderTest extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        gradient: LinearGradient(
          colors: [Colors.teal, Colors.green],
          begin: Alignment.topRight,
          end: Alignment.centerLeft,
        ),
      ),
      child: Stack(
        children: [
          Container(
            decoration: ShapeDecoration(
              shape: WaveShapeBorder(),
              shadows: [
                BoxShadow(color: Colors.black, blurRadius: 16, offset: Offset(2, 2), spreadRadius: 8),
              ]
            ),
            child: Material(
              clipBehavior: Clip.antiAlias,
              shape: WaveShapeBorder(),
              child: Image.asset('images/someImage.png',),
            ),
          ),
          Icon(Icons.photo, size: 64,),
        ],
      ),
    );
  }
}

你会看到这个:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

只想在 CustomClipper 边框上添加标高,而不是在下面的整个材质上添加标高 的相关文章

随机推荐