# Flutter Xfermode 实现

```dart
//设置矩阵变换区域
canvas.saveLayer(Offset.zero& size, Paint());

/// 绘制背景
Rect rect = Rect.fromPoints(start, valueEnd);
canvas.drawLine(start, valueEnd, mPaint);
mPaint.blendMode = BlendMode.srcIn;

/// 绘制进度
mPaint.strokeCap = StrokeCap.square;
/// 增加渐变色
mPaint.shader = LinearGradient(colors: colors).createShader(rect);
 //计算进度的长度
valueEnd = valueEnd = Offset(
value *(size.width - 2 * _offset)+ _offset, _offset);
//合成图层
canvas.drawLine(start, valueEnd, mPaint);
canvas.restore();
```

文字反色实现

```dart
/// 绘制反色文字
double fontSize = 10;
double marginTop =(strokeWidth - fontSize)/ 2.0;
start = Offset(_offset, 0); //画笔起点坐标
valueEnd = Offset(value *(size.width - 2 * _offset)+ _offset * 2,
    _offset * 2); //计算进度的长度
var textPainter = TextPainter(
text: TextSpan(
text: soldNumString,
      style: TextStyle(color: Color(0xffFC5E82), fontSize: fontSize)),
  textDirection: TextDirection.ltr,
  maxLines: 1,
)..layout();

textPainter.paint(canvas, Offset(marginStart, marginTop));
if(value > 0) {
canvas.saveLayer(Rect.fromPoints(start, valueEnd), Paint());
  var textPainter2 = TextPainter(
text: TextSpan(
text: soldNumString,
        style: TextStyle(color: ColorCons.white, fontSize: fontSize)),
    textDirection: TextDirection.ltr,
    maxLines: 1,
)..layout();
  // 绘制两次达到Xfermode的效果
  textPainter2.paint(canvas, Offset(marginStart, marginTop));
  textPainter2.paint(canvas, Offset(marginStart, marginTop));
  canvas.restore();
}
```

完整代码

```dart
import 'package:flutter/material.dart';
import 'package:si_basic_flutter/base/cons/color_cons.dart';

class GradientLinearProgressBar extends StatelessWidget{
final double strokeWidth; //画笔的宽度,其实是进度条的高度
  final double value; //进度值
  final List<Color>colors; //渐变的颜色列表
  final Color backgroundColor;
  final String soldNumString;

  const GradientLinearProgressBar(
      {this.strokeWidth = 2.0,
      @required this.colors,
      @required this.value,
      this.backgroundColor,
      this.soldNumString = ""});

  @override
  Widget build(BuildContext context) {
var _colors = colors;
    if(_colors == null) {
Color color = Theme.of(context).accentColor;
      _colors =[color, color];
}else if(_colors.length == 1) {
var color = _colors[0];
      _colors =[color, color];
}
var _backgroundColor = backgroundColor;
    if(_backgroundColor == null) {
_backgroundColor = Colors.white;
}
return CustomPaint(
size: MediaQuery.of(context).size,
      painter: _GradientLinearProgressPainter(
strokeWidth: strokeWidth,
          value: value,
          colors: _colors,
          backgroundColor: _backgroundColor,
          soldNumString: soldNumString),
);
}
}

class _GradientLinearProgressPainter extends CustomPainter{
final double strokeWidth;
  final double value;
  final List<Color>colors;
  final mPaint = Paint();
  final Color backgroundColor;
  final String soldNumString;

  _GradientLinearProgressPainter(
      {this.strokeWidth = 2.0,
      @required this.colors,
      this.value = 0.0,
      this.backgroundColor,
      this.soldNumString}) {
mPaint.strokeCap = StrokeCap.round;
    mPaint.style = PaintingStyle.fill;
    mPaint.isAntiAlias = true;
    mPaint.strokeWidth = strokeWidth;
    mPaint.color = backgroundColor;
}

@override
  void paint(Canvas canvas, Size size) {
double _offset = strokeWidth / 2; //留一定的偏移量
    var start = Offset(_offset, _offset); //画笔起点坐标

    var valueEnd =
        Offset(1 *(size.width - 2 * _offset)+ _offset, _offset); //计算进度的长度
    if(value > 0) {
canvas.saveLayer(Offset.zero& size, Paint());

/// 绘制背景
Rect rect = Rect.fromPoints(start, valueEnd);
      canvas.drawLine(start, valueEnd, mPaint);

      mPaint.blendMode = BlendMode.srcIn;

/// 绘制进度
mPaint.strokeCap = StrokeCap.square;
      mPaint.shader = LinearGradient(colors: colors).createShader(rect);
      valueEnd = valueEnd = Offset(
value *(size.width - 2 * _offset)+ _offset, _offset); //计算进度的长度
      canvas.drawLine(start, valueEnd, mPaint);
      canvas.restore();
}else{
canvas.drawLine(start, valueEnd, mPaint);
}

double marginStart = 0;
    if(value >= 0.85) {
marginStart = 22.5;
}else{
marginStart = 8;
}
/// 绘制反色文字
double fontSize = 10;
    double marginTop =(strokeWidth - fontSize)/ 2.0;
    start = Offset(_offset, 0); //画笔起点坐标
    valueEnd = Offset(value *(size.width - 2 * _offset)+ _offset * 2,
        _offset * 2); //计算进度的长度
    var textPainter = TextPainter(
text: TextSpan(
text: soldNumString,
          style: TextStyle(color: Color(0xffFC5E82), fontSize: fontSize)),
      textDirection: TextDirection.ltr,
      maxLines: 1,
)..layout();

    textPainter.paint(canvas, Offset(marginStart, marginTop));
    if(value > 0) {
canvas.saveLayer(Rect.fromPoints(start, valueEnd), Paint());
      var textPainter2 = TextPainter(
text: TextSpan(
text: soldNumString,
            style: TextStyle(color: ColorCons.white, fontSize: fontSize)),
        textDirection: TextDirection.ltr,
        maxLines: 1,
)..layout();
      textPainter2.paint(canvas, Offset(marginStart, marginTop));
      textPainter2.paint(canvas, Offset(marginStart, marginTop));
      canvas.restore();
}
  }

@override
  bool shouldRepaint(covariant CustomPainter oldDelegate)=> true;
}

```