Flutter 贝塞尔曲线切割

Stella981
• 阅读 948

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

Flutter 贝塞尔曲线切割

ClipPath 路径裁切控件

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

  • child :要切割的元素,可以是容器,图片.....

  • clipper : 切割的路径,这个要和CustomClipper对象配合使用。

    class CurvePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('贝塞尔曲线切割')), body: Column( children: [ 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 贝塞尔曲线切割

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

代码如下:

//曲线路径
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;
  }
}
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
晴空闲云 晴空闲云
3年前
svg中path贝塞尔曲线和圆弧图文详解
最近研究了一下svg的path标签,功能非常强大,理论上来讲path标签可以画出任意图形。自己记性不太好,记录一下path的使用语法和自己的理解。path介绍path用d属性来描述路径,语法格式大概如下:html其中路径描述包含如下命令:Mmoveto移动到某点。Llineto画一条直线到某点。Hhorizontallineto
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Stella981 Stella981
3年前
Android 贝塞尔曲线实战之网易云音乐鲸云特效
作者:哈哈将个推Android高级开发工程师前言APP开发市场已经告别“野蛮生长”时代,人们不再满足于APP外形创新,而将目光转向全方面的用户体验上。在这过程中,动效化作为移动互联网产品的新趋势,如何实现酷炫丝滑的动画效果已然成为开发者们的新课题。实现方式其实很简单。本文将为你剖析理论基础以及具体应用。咱们日常使用的APP的时候,
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
Ubuntu 安装 ImageMagick 库
ImageMagick介绍ImageMagick是一个用来创建、编辑、合成图片的软件。它可以读取、转换、写入多种格式的图片。图片切割、颜色替换、各种效果的应用,图片的旋转、组合,文本,直线,多边形,椭圆,曲线,附加到图片伸展旋转。ImageMagick是免费软件:全部源码开放,可以自由使用,复制,修改,发布。支持
Stella981 Stella981
3年前
Flutter 之贝塞尔曲线(一)
贝塞尔曲线简介!(https://oscimg.oschina.net/oscnet/863784996212c918a1feef7a916bce28f31.png"bezier1.png")bezier1.png由上图可以看出:A,C依据控制点B不断的取点使得AD:ABBE:BCDF:DE,构成一个二阶贝塞尔曲线。AD:
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Flutter贝塞尔曲线之水波纹与球形进度(二)
续上篇,再用贝塞尔曲线绘制一个循环水波纹,一个水波纹进度球,先看效果,以下效果的实现用的都是二阶贝塞尔曲线。效果图!(https://oscimg.oschina.net/oscnet/db689ecfebdfa10dbc59b588184913f7c6f.gif"bezierShow4.gif")bezierShow4.