一统天下 flutter - 图形: 剪裁

源码 https://github.com/webabcd/flutter_demo
作者 webabcd

一统天下 flutter - 图形: 剪裁

示例如下:

lib\shape\clip.dart

/*
 * 剪裁
 *
 * ClipRect - 矩形剪裁
 * ClipRRect - 圆角矩形剪裁
 * ClipOval - 椭圆形剪裁
 * ClipPath - 自定义路径剪裁
 * ClipPath.shape() - 根据指定的 ShapeBorder 对象剪裁
 *
 * 另外,部分 Widget 会有一个 clipBehavior 属性,其用于指定超出范围的子元素的剪裁方式
 * 1、Clip.none - 不剪裁
 * 2、Clip.hardEdge - 裁剪但不抗锯齿,速度比 none 慢
 * 3、Clip.antiAlias - 裁剪而且抗锯齿,速度比 hardEdge 慢
 * 4、Clip.antiAliasWithSaveLayer - 裁剪而且抗锯齿,并分配一个缓冲区,速度比 antiAlias 慢
 */

import 'package:flutter/material.dart';

var image = Image.asset(
  'assets/son.jpg',
  fit: BoxFit.cover,
  width: 50,
  height: 50,
);

class ClipDemo extends StatelessWidget {
  const ClipDemo({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: [
        /// 原始图片
        image,
        /// ClipRect - 矩形剪裁
        /// 本例剪裁后的结果为:只显示图片的上半部分
        ClipRect(
          child: Align(
            alignment: Alignment.topCenter,
            heightFactor: 0.5,
            child: SizedBox(
              height: 50,
              width: 50,
              child: image,
            ),
          ),
        ),
        /// ClipRRect - 圆角矩形剪裁
        /// 本例剪裁后的结果为:显示圆角图片
        ClipRRect(
          borderRadius: BorderRadius.circular(10),
          child: SizedBox(
            height: 50,
            width: 50,
            child: image,
          ),
        ),
        /// ClipOval - 椭圆形剪裁
        /// 本例剪裁后的结果为:显示圆形图片
        ClipOval(
          child: SizedBox(
            height: 50,
            width: 50,
            child: image,
          ),
        ),
        /// ClipPath.shape() - 根据指定的 ShapeBorder 对象剪裁
        ///   shape - 指定用于剪裁的 ShapeBorder 对象(关于 ShapeBorder 的说明请参见 /lib/shape/border.dart)
        /// 本例剪裁后的结果为:显示圆形图片
        ClipPath.shape(
          shape: const CircleBorder(),
          child: SizedBox(
            height: 50,
            width: 50,
            child: image,
          ),
        ),
        /// ClipPath - 自定义路径剪裁
        ///   clipper - 自定义剪裁路径,需要自定义 CustomClipper<Path> 对象
        /// 本例剪裁后的结果为:显示三角图片
        ClipPath(
          clipper: _MyClipper(),
          child: SizedBox(
            height: 50,
            width: 50,
            child: image,
          ),
        ),
      ],
    );
  }
}

/// 自定义的 CustomClipper<Path> 对象,用于实现三角形剪裁
class _MyClipper extends CustomClipper<Path>{
  @override
  Path getClip(Size size) {
    var path = Path();
    path.moveTo(size.width / 2, 0);
    path.lineTo(0, size.height);
    path.lineTo(size.width, size.height);
    return path;
  }

  /// 如果之后 widget 重新 build 了,就会执行到这里
  /// 一般通过判断 _MyClipper 新旧实例的与 UI 相关的参数是否发生变化来决定是否需要重新剪裁
  @override
  bool shouldReclip(_MyClipper oldClipper) {
    return true;
  }
}

源码 https://github.com/webabcd/flutter_demo
作者 webabcd

posted @ 2023-03-22 11:17  webabcd  阅读(37)  评论(0编辑  收藏  举报