【问题标题】:Flutter applying shadows to CustomPainted widgetFlutter 将阴影应用到 CustomPainted 小部件
【发布时间】:2019-12-05 01:30:50
【问题描述】:

简介

我使用 Flutter 的 CustomPaint Widget 绘制了一个自定义的 Tab-bar,它看起来像这样:

另外,这是我用来绘制小部件的代码:

class TabBarPainter extends CustomPainter {
  final Color paintColor = Colors.redAccent 
  @override
  void paint(Canvas canvas, Size size) {
    /// the thing that I called as a deleter circle is an imaginary circle that I used to delete a semicircle from my rectangular shape

    var diameter = 80; /// X value is the diameter(R) of the deleter circle;
    double topSpace = 2;
    double startCurve = (size.width-diameter)/2; /// Start point of the curve
    double endCurve = startCurve+diameter; // End Point of the curve


     /// Some math about my cubic bezier curve
    double xValueInset = diameter * 0.05; 
    double yValueOffset = (diameter/2) * 4.0 / 3.0; 

    Path path = Path();

    Paint paint = Paint();

    /// Points to make a semicircle approximation using Bezier Curve
    var firstendPoint = new Offset(endCurve, topSpace);
    var controlPoint1  = new Offset(startCurve+xValueInset,yValueOffset+topSpace);
    var controlPoint2  = new Offset((diameter-xValueInset)+startCurve,yValueOffset+topSpace);

    //! Start sketching Shape
    path.moveTo(0.0,topSpace);
    path.lineTo(startCurve, topSpace);
    path.cubicTo(controlPoint1.dx, controlPoint1.dy,
    controlPoint2.dx, controlPoint2.dy,
    firstendPoint.dx, firstendPoint.dy);
    path.lineTo(size.width, topSpace);
    path.lineTo(size.width, size.height);
    path.lineTo(0.0, size.height);
    path.close();
    //! End sketching Shape

    paint.color = paintColor;

    canvas.drawPath(path, paint);

  }

  @override
  bool shouldRepaint(TabBarPainter oldDelegate) =>  oldDelegate != this;
}

实验

我想在我的 CustomDrawen Shape 上应用一个影子,所以我尝试了 2 种方法:

第一种方法:我使用了一个经典的容器和 boxshadow 来遮蔽它,它看起来像这样: 我使用了以下代码:

Container(
  decoration: BoxDecoration(
    boxShadow: [
      BoxShadow(
        color : Colors.black.withOpacity(0.30),
        blurRadius: 3,
        ffset: new Offset(0, -3)
      )
    ]
  ),
  child: CustomPaint(           
    painter: TabBarPainter(),
  ),

第二种方法:我画了一个类似的黑色(不透明度(0.15))形状 它看起来像这样:

我在我的 CustomPainter 中添加了以下代码来绘制这个形状:

final Color shadowColor = Colors.black.withOpacity(0.15);

Path shadowPath = Path();
Paint shadowPaint = Paint();

/// Points to make a semicircle approximation using Bezier Curve

var shadowfirstendPoint = new Offset(endCurve-topSpace, 0.0);
var shadowcontrolPoint1  = new Offset(startCurve+xValueInset+topSpace,yValueOffset);
var shadowcontrolPoint2  = new Offset((diameter-xValueInset)+startCurve-topSpace,yValueOffset);

//! Start sketching Shadow   
shadowPath.lineTo(startCurve+topSpace, 0.0);
shadowPath.cubicTo(shadowcontrolPoint1.dx, shadowcontrolPoint1.dy,
shadowcontrolPoint2.dx, shadowcontrolPoint2.dy,
shadowfirstendPoint.dx, shadowfirstendPoint.dy);
shadowPath.lineTo(size.width, 0.0);
shadowPath.lineTo(size.width, size.height);
shadowPath.lineTo(0.0, size.height);
shadowPath.close();

//! End Sketching Shadow
shadowPaint.color = shadowColor;
canvas.drawPath(shadowPath, shadowPaint);

问题

在第一种方法中,空白区域 - 在小部件的顶部中心 - 被阴影填充

在第二种方法中,阴影不真实,因为即使它的不透明度很低,它也没有模糊,我找不到使其模糊的方法

结论

我需要另一种方法来正确地为我的小部件添加阴影或为我的类似阴影的自定义绘制形状添加模糊

由于 Flutter 对他们创建的每种类型的小部件都这样做,这似乎是可能的

我会感谢任何帮助的人

问候

【问题讨论】:

  • 使用drawShadow方法绘制阴影

标签: flutter dart shadow


【解决方案1】:

我发现一个更简单的方法是偏移路径

canvas.drawShadow(path.shift(Offset(0, -5)), Colors.black, 2.0, true);

【讨论】:

  • 谢谢!可以设置高度以自定义传播
【解决方案2】:

正如@pskink 提到的,有一个画布方法叫做drawShadow

所以将我的 shadowPath 的绘制方法更改为:

canvas.drawShadow(shadowPath, Colors.black, 2.0, true);

将解决问题,输出将是这样的:

谢谢大家!!

【讨论】:

    猜你喜欢
    • 2022-12-05
    • 2019-12-19
    • 2020-08-17
    • 1970-01-01
    • 2021-09-30
    • 2018-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多