实现“斑马纹”背景(需要变换颜色)(组图)

Flutter 实现“斑马纹”背景

由于工作中的项目需求,需要将H5转换为Flutter代码。

斑马纹背景需要根据界面返回的颜色进行渲染,不能只是图片的形式,也不能通过decoration属性配置图片背景板。

楼主在这里想到的方法是通过实现一个canvas来绘制斑马纹。使用Stack布局,下面的斑马纹作为背景板,上面要显示的内容。

实现“斑马”背景(需要改变颜色)

文章主要分为效果图、实现思路、代码、计算过程讲解。希望对你有帮助

最终渲染

思维斑马纹的实现(45°角,向左倾斜)

使用CustomPaint(size: Size(width, height),painter:brush)

CustomPaint(
   size: Size(widget.width, widget.height),
   painter: 画笔,
)

继承CustomPainter类,实现paint(Canvas canvas, Size size)方法,根据宽度、高度、画笔宽度、间距计算每个点。使用canvas.drawLine方法绘制斑马纹。

@override
void paint(Canvas canvas, Size size) {
  …
  canvas. drawLine();
}

斑马纹坐标位置的计算

2.82 = 2 次根 2

1.41 = 根二

填充数 = 最大高度/(画笔宽度1.41+间距)向上取整。 (从0开始,0开始,左边会有空位,所以需要补上)

条纹数 = 宽度/(画笔宽度1.41+间距)向上取整。

(x-axis y-axis) offset =画笔宽度/2.82(画笔的起点和终点都会露出一段,需要计算x,y偏移量。减去上边left corner x, y 去掉偏移,在右下角x,y加上偏移,补充这部分)

起点坐标=((画笔宽度1.41+间距)*条纹索引-偏移量,-偏移量)

终点坐标=((画笔宽度1.41+间距)*条纹索引-偏移+高度,高度+偏移)

裁剪角(如果需要)

因为画笔画的是直角,会超出背景板,需要剪掉四个角。使用

ClipRRect(
   borderRadius: BorderRadius.all(Radius.circular(10)),
   child: xxx
)

作为背景

使用Stack布局实现下面斑马纹作为背景板,上面要显示的内容

Stack(
  children: [
  	buildZebraBack(…), 
  	需要展示的内容
  ]
)

代码用在哪里 main_page.dart

Stack(
  children: [
    Positioned(
      child: ZebraStripesBack(
          width: 335,
          height: 44,
          lineWidth: 10,
          spacing: 10,
          borderRaduis: 10,
          lineColor: Colors.blue),
      top: 0,
      left: 0,
    ),
    Container(
      width: 335,
      height: 44,
      alignment: Alignment.center,
      padding: EdgeInsets.only(
          top: 10,
          left: 12,
          bottom: 10,
          right: 12),
      child: Text(
              "英语",
              style: TextStyle(
                color: Color(0xFFFFFFFF),
                fontSize: 14.sp,
                fontWeight: FontWeight.w500),
            )
      )
  ]
)

斑马条纹的具体实现类zebra_stripes_back.dart

import 'dart:math';
import 'package:flutter/material.dart';
// 斑马纹具体实现类
class ZebraStripesBack extends StatefulWidget {
  ZebraStripesBack({
    this.width: 0,
    this.height: 0,
    this.spacing: 4,
    this.lineWidth: 4,
    this.lineColor: Colors.transparent,
    this.borderRaduis: 0,
  });
  final double width; // 容器宽度
  final double height; // 容器高度 
  final double lineWidth; // 斑马纹宽度
  final double spacing; // 间距
  final double borderRaduis; // 容器圆角
  final Color lineColor; // 斑马纹颜色
  @override
  State createState() => _ZebraStripesBackState();
}
class _ZebraStripesBackState extends State {
  @override
  void initState() {
    super.initState();
  }
  @override
  void dispose() {
    super.dispose();
  }
  @override
  Widget build(BuildContext context) {
    return ClipRRect(
        borderRadius: BorderRadius.all(Radius.circular(widget.borderRaduis)),
        child: CustomPaint(
          size: Size(widget.width, widget.height),
          painter: _ZebraStripesBackPainter(
            maxWidth: widget.width,
            maxHeight: widget.height,
            spacing: widget.spacing,
            lineWidth: widget.lineWidth,
            lineColor: widget.lineColor,
            borderRaduis: widget.borderRaduis,
          ),
        ));
  }
}
class _ZebraStripesBackPainter extends CustomPainter {
  _ZebraStripesBackPainter({
    this.maxWidth: 0,
    this.maxHeight: 0,
    this.spacing: 4,
    this.lineWidth: 4,
    this.lineColor: Colors.black12,
    this.borderRaduis: 0,
  });
  final double maxWidth;
  final double maxHeight;
  final double spacing;
  final double lineWidth;
  final Color lineColor;
  final double borderRaduis;
  @override
  void paint(Canvas canvas, Size size) {
    var paint = Paint()
      ..isAntiAlias = true
      ..style = PaintingStyle.fill
      ..color = lineColor
      ..strokeWidth = lineWidth;
    int number = 0; // 个数
    int fillNumber = 0; // 填充个数
    double lineAndSpace = lineWidth *1.41 + spacing; // 单个条纹宽 + 间距宽
    if (lineWidth > 0) {
      number = (maxWidth / lineAndSpace).ceil();
      fillNumber = (maxHeight / lineAndSpace).ceil(); // 填充个数
    }
    double deviation = lineWidth / 2.82; // x y轴偏移量 = width / 2倍根号2
    for (int i = -fillNumber; i  true;
}

计算过程解释偏移量计算过程

填数计算过程

为什么画笔宽度需要乘以二?

缺失填充

缺失偏移

© 版权声明
THE END
喜欢就支持一下吧
点赞120 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片