flutter 按路径切割组件ClipPath、绘制贝塞尔曲线

按路径切割组件
    ClipPath(
     clipper:继承了CustomClipper的类且重写了两个方法 ,   裁切路径
     child: 待切割组件
   )

切割类
	class BottomClipper extends CustomClipper{
	  
	  Path getClip(Size size){
	     var path=Path();
	
	(1)根据坐标点绘制,size包含了子组件宽高
	(2)若不是被贝塞尔曲线,依次直线相连lineTo设置的坐标路径剪裁
	(3)若使用了贝塞尔曲线,则贝塞尔曲线的首尾点的前后的点先连也是贝塞尔曲线
	
	贝塞尔绘制弧线
		 path.lineTo(0, 0);    
	     path.lineTo(0,size.height-30);
	    
	    贝塞尔曲线的两个坐标,根据高低通过弧线相连
	     var firstPoint=Offset(size.width/2,size.height);
	     var endPoint=Offset(size.width,size.height-30);
		绘制贝塞尔曲线
	     path.quadraticBezierTo(firstPoint.dx, firstPoint.dy, endPoint.dx, endPoint.dy);
	
	     path.lineTo(size.width, 0);
     
	贝塞尔绘制波浪线
	    path.lineTo(0,0);
	    path.lineTo(0,size.height-40);
	
	   波浪线需要四个贝塞尔坐标,分别在1/4、1/2.25,3/4,1处设置,会根据高低弧线相连
	
	    var firstPoint=Offset(size.width/4,size.height);
	    var secondPoint=Offset(size.width/2.25,size.height-30);
	    path.quadraticBezierTo(firstPoint.dx, firstPoint.dy, secondPoint.dx, secondPoint.dy);
	
	    var thirdPoint=Offset(size.width/4*3,size.height-90);
	    var fourthPoint=Offset(size.width,size.height-40);
	    path.quadraticBezierTo(thirdPoint.dx, thirdPoint.dy, fourthPoint.dx, fourthPoint.dy);
	    
	    path.lineTo(size.width, 0);


	    return path;
	  }
	
  @override
  bool shouldReclip(CustomClipper oldClipper) {
    // TODO: implement shouldReclip
    return false;
  }
}

效果图:
flutter 按路径切割组件ClipPath、绘制贝塞尔曲线_第1张图片flutter 按路径切割组件ClipPath、绘制贝塞尔曲线_第2张图片

代码示例:

import 'package:flutter/gestures.dart';
import "package:flutter/material.dart";
import 'package:flutter/rendering.dart';
import "drag.dart";
import 'dart:ui';

import 'page/1.dart';
import 'page/2.dart';
import 'page/3.dart';
import 'xuan.dart';

void main()
{
  runApp(App());
}
class App extends StatelessWidget {
  const App({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return App2();
  }
}

class App2 extends StatefulWidget {
  App2({Key key}) : super(key: key);

  @override
  _AppState createState() => _AppState();
}

class _AppState extends State<App2> with SingleTickerProviderStateMixin {

  // List _page=[Home3(),Home2(),Home4()];
  // int index=0;
  TabController con;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    con=new TabController(length: 3, vsync: this);
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    con.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return  MaterialApp(
      home:Scaffold(
        appBar:AppBar(
          title: Text('小案例'),
        ),
        
        body:Home(),
      //去掉右上角的debug贴纸
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue
      ),
      );
  }
}


class Home extends StatefulWidget {

  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  

  @override
  Widget build(BuildContext context) {

    return Container(
      // width: double.infinity,
       child:Center(
         child:Column(
           children: <Widget>[
             ClipPath(
               clipper:BottomClipper() ,  //裁切路径
               child: Container(
                 height: 200,
                 width: double.infinity,
                 color:Colors.indigoAccent
               ),
             )
           ],
         ),
       )
       
    );
  }
}

class BottomClipper extends CustomClipper<Path>{
  
  Path getClip(Size size){
    var path=Path();

    // path.lineTo(0, 0);
    // path.lineTo(0,size.height-30);
    
    // var firstPoint=Offset(size.width/2,size.height);

    // var endPoint=Offset(size.width,size.height-30);

    // path.quadraticBezierTo(firstPoint.dx, firstPoint.dy, endPoint.dx, endPoint.dy);

    // path.lineTo(size.width, 0);

    path.lineTo(0,0);
    path.lineTo(0,size.height-40);

    var firstPoint=Offset(size.width/4,size.height);
    var secondPoint=Offset(size.width/2.25,size.height-30);
    path.quadraticBezierTo(firstPoint.dx, firstPoint.dy, secondPoint.dx, secondPoint.dy);

    var thirdPoint=Offset(size.width/4*3,size.height-90);
    var fourthPoint=Offset(size.width,size.height-40);
    path.quadraticBezierTo(thirdPoint.dx, thirdPoint.dy, fourthPoint.dx, fourthPoint.dy);

    path.lineTo(size.width, 0);
    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) {
    // TODO: implement shouldReclip
    return false;
  }
}

你可能感兴趣的:(flutter)