首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >颤动将阴影应用于CustomPainted构件

颤动将阴影应用于CustomPainted构件
EN

Stack Overflow用户
提问于 2019-07-27 01:19:09
回答 2查看 3.1K关注 0票数 2

引言

我使用Flutter的CustomPaint小部件绘制了一个自定义选项卡栏,如下所示:

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

代码语言:javascript
复制
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形状上应用一个阴影,所以我尝试了两种方法:

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

我使用了以下代码:

代码语言:javascript
复制
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中添加了以下代码:

代码语言:javascript
复制
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正在对他们创建的所有类型的小部件执行此操作,因此这似乎是可能的

我会感谢任何帮助我的人

问候

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-07-28 21:49:14

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

因此将我的shadowPath的绘制方法更改为:

代码语言:javascript
复制
canvas.drawShadow(shadowPath, Colors.black, 2.0, true);

将解决问题,输出将如下所示:

感谢大家!!

票数 3
EN

Stack Overflow用户

发布于 2020-02-28 04:33:00

我发现一种更简单的方法是对路径进行偏移

代码语言:javascript
复制
canvas.drawShadow(path.shift(Offset(0, -5)), Colors.black, 2.0, true);
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57224518

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档