zoukankan      html  css  js  c++  java
  • Flutter 贝塞尔曲线切割

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

    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;
      }
    }

    波浪形式的贝塞尔曲线

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

    代码如下:

    //曲线路径
    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;
      }
    }
  • 相关阅读:
    keyset与entryset
    solr4.9r+ Eclipse 4.3+ tomcat 7.5 +winds7(二)
    如何解决This system is not registered with RHN.
    堆和栈的差别(转过无数次的文章)
    墨菲定律、二八法则、马太效应、手表定理、“不值得”定律、彼得原理、零和游戏、华盛顿合作规律、酒与污水定律、水桶定律、蘑菇管理原理、钱的问题、奥卡姆剃刀等13条是左右人生的金科玉律
    atitit.软件开发GUI 布局管理优缺点总结java swing wpf web html c++ qt php asp.net winform
    漫谈并发编程(二):java线程的创建与基本控制
    exosip
    PostgreSQL服务端监听设置及client连接方法
    APK反编译。
  • 原文地址:https://www.cnblogs.com/joe235/p/11235838.html
Copyright © 2011-2022 走看看