Flutter 贝塞尔曲线切割

摘要:
ClassCurvePageextendsStatesWidget{@overrideWidgetbuild{returnScaffold;}}在Scaffold中放置一个列容器,然后将ClipPath控件放入其中。ClipPath的子元素是容器控件container。CustomClipper剪裁路径我们的主要Bezier曲线路径是在getClip方法中编写的,它返回一个路径。二阶贝塞尔曲线需要一个控制点和一个端点。控制点就像磁铁,吸引直线形成完美的弧度。这个弧度就是贝塞尔曲线。让我们先熟悉切割路径和贝塞尔曲线,并制作最简单的贝塞尔曲线。

现在人们对于网站的美感要求是越来越高了,所以很多布局需要优美的曲线设计。当然最简单的办法是作一个PNG的透明图片,然后外边放一个Container.但其内容如果本身就不是图片,只是容器,这种放入图片的做法会让包体变大。其实我们完全可以使用贝塞尔曲线进行切割。

Flutter 贝塞尔曲线切割第1张

ClipPath 路径裁切控件

clipPath控件可以把其内部的子控件切割,它有两个主要属性(参数):

  • child :要切割的元素,可以是容器,图片.....
  • clipper : 切割的路径,这个要和CustomClipper对象配合使用。
class CurvePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('贝塞尔曲线切割')),
      body: Column(
        children: <Widget>[
          ClipPath( //路径裁切组件
            clipper: BottomClipper(), //路径
            child: Container(
              color: Colors.deepOrangeAccent,
              height: 200.0,
            ),
          ),
        ],
      ),
    );
  }
}

Scaffold里放置了一个列容器,然后把ClipPath控件放到了里边,ClipPath的子元素是一个容器控件ContainerBootomClipper是我们自定义的一个对象,里边主要就是切割的路径。

CustomClipper 裁切路径

我们主要的贝塞尔曲线路径就写在getClip方法里,它返回一段路径。

一个二阶的贝塞尔曲线是需要控制点和终点的,控制点就像一块磁铁,把直线吸引过去,形成一个完美的弧度,这个弧度就是贝塞尔曲线了。

我们先来熟悉一下裁切路径和贝塞尔曲线,作一个最简单的贝塞尔曲线出来。

全部代码如下:

import 'package:flutter/material.dart';

class CustomClipperDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false, //去掉debug图标
      theme: ThemeData(
        primarySwatch: Colors.red
      ),
      home: CurvePage(),
    );
  }
}

class CurvePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('贝塞尔曲线切割')),
      body: Column(
        children: <Widget>[
          ClipPath( //路径裁切组件
            clipper: BottomClipper(), //路径
            child: Container(
              color: Colors.deepOrangeAccent,
              height: 200.0,
            ),
          ),
        ],
      ),
    );
  }
}

class BottomClipper extends CustomClipper<Path>{

  @override
  Path getClip(Size size){
    var path = Path();
    path.lineTo(0, 0); //第1个点
    path.lineTo(0, size.height-50.0); //第2个点
    var firstControlPoint = Offset(size.width/2, size.height);
    var firstEdnPoint = Offset(size.width, size.height-50.0);
    path.quadraticBezierTo(
      firstControlPoint.dx, 
      firstControlPoint.dy, 
      firstEdnPoint.dx, 
      firstEdnPoint.dy
    );
    path.lineTo(size.width, size.height-50.0); //第3个点
    path.lineTo(size.width, 0); //第4个点

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

波浪形式的贝塞尔曲线

Flutter 贝塞尔曲线切割第2张

在上面代码的基础上修改为波浪式的贝塞尔曲线,波浪形式的只要把裁切变成两个对称的贝塞尔曲线就可以实现了。

代码如下:

//曲线路径
class BottomClipper extends CustomClipper<Path>{
  @override
  Path getClip(Size size){
    var path = Path(); //定义路径
    //path.lineTo(0, 0); //第1个点
    //path.lineTo(0, size.height-50.0); //第2个点
    //var firstControlPoint = Offset(size.width/2, size.height); //第一段曲线控制点
    //var firstEdnPoint = Offset(size.width, size.height-50.0); //第一段曲线结束点
    //path.quadraticBezierTo( //形成曲线
    //  firstControlPoint.dx, 
    //  firstControlPoint.dy, 
    //  firstEdnPoint.dx, 
    //  firstEdnPoint.dy
    //);
    //path.lineTo(size.width, size.height-50.0); //第3个点
    //path.lineTo(size.width, 0); //第4个点

    //波浪曲线路径
    path.lineTo(0, 0); //第1个点
    path.lineTo(0, size.height - 40.0); //第2个点
    var firstControlPoint = Offset(size.width/4, size.height); //第一段曲线控制点
    var firstEndPoint = Offset(size.width/2.25, size.height-30); //第一段曲线结束点
    path.quadraticBezierTo( //形成曲线
      firstControlPoint.dx, 
      firstControlPoint.dy, 
      firstEndPoint.dx, 
      firstEndPoint.dy);
    
    var secondControlPoint = Offset(size.width/4*3, size.height-90); //第二段曲线控制点
    var secondEndPoint = Offset(size.width, size.height-40); //第二段曲线结束点
    path.quadraticBezierTo( //形成曲线
      secondControlPoint.dx, 
      secondControlPoint.dy, 
      secondEndPoint.dx, 
      secondEndPoint.dy);
    
    path.lineTo(size.width, size.height-40);
    path.lineTo(size.width, 0);

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

免责声明:文章转载自《Flutter 贝塞尔曲线切割》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇[iis] 无法匿名访问问题FastReport VCL4.9发布下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

canvas基础2--绘制图形

栅格 绘制矩形 不同于SVG,HTML中的元素canvas只支持一种原生的图形绘制:矩形。所有其他的图形的绘制都至少需要生成一条路径。不过,我们拥有众多路径生成的方法让复杂图形的绘制成为了可能。 首先,我们回到矩形的绘制中。canvas提供了三种方法绘制矩形: fillRect(x, y, width, height) 绘制一个填充的矩形 strokeR...

ios 动画系列之六------UIBezierPath贝塞尔弧线常用方法记

//根据一个矩形画曲线 + (UIBezierPath*)bezierPathWithRect:(CGRect)rect //根据矩形框的内切圆画曲线 + (UIBezierPath*)bezierPathWithOvalInRect:(CGRect)rect //根据矩形画带圆角的曲线 + (UIBezierPath*)bezierPathWith...

穿过已知点画平滑曲线(3次贝塞尔曲线)

tyle="margin:20px 0px 0px; font-size:14px; line-height:26px; font-family:Arial; color:rgb(51,51,51)"> 为了把一串点连成光滑的曲线,先研究贝塞尔曲线,又搞B样条插值。。。。都没有成功(数学没那么强)。 后来在 “[翻译] AGG 之贝塞尔插值”http...

UIBezierPath精讲

前言 笔者在写本篇文章之前,也没有系统学习过贝塞尔曲线,只是曾经某一次的需求需要使用到,才临时百度看了一看而且使用最基本的功能。现在总算有时间停下来好好研究研究这个神奇而伟大的贝塞尔先生! 笔者在学习时,首先看了两遍UIBezierPath类头文件定义,熟悉了一下相关的属性和方法。 基础知识 使用UIBezierPath可以创建基于矢量的路径,此类是Cor...

iOS开发 贝塞尔曲线UIBezierPath(后记)

使用CAShapeLayer与UIBezierPath可以实现不在view的drawRect方法中就画出一些想要的图形 。 1:UIBezierPath: UIBezierPath是在 UIKit 中的一个类,继承于NSObject,可以创建基于矢量的路径.此类是Core Graphics框架关于path的一个OC封装。使用此类可以定义常见的圆形、多边形等...

在AutoCAD中生成贝塞尔曲线

贝赛尔曲线的定义  贝塞尔曲线(Bézier curve)是由法国雷诺公司的设计师Pierre Bézier设计。它的具体定义如下:                    其中Pi(i=0,1,2,...n)称作曲线的控制向量,他们组成的连续多段线叫做曲线的控制多边形; t ∈[0,1],即 t 从0连续变化到1时所生成的曲线就叫做贝赛尔曲线。而函数:...