Flutter处理canvas.saveLayer来制作图层

问题描述 投票:0回答:1

我正在尝试在flutter中使图层功能像Photoshop一样。 为了简单实现,一个图层中的所有图片都是相同的颜色。例如,第 1 层上的所有绘图都是红色。 但每一层都有不同的颜色。例如,第 1 层为红色,第 2 层为蓝色。

下面是各层的结构。

import 'package:flutter/material.dart';
import 'package:label_up_study/models/sketch.dart';
import 'dart:math';

Color randomColor() {
  return Color((Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(1.0);
}

class LayerInfo {
  List<Sketch> drawLayer; // This stores every sketch in Listener onPointerDown()/Move()/Up()
  String label;
  bool selected;
  bool visible;
  Color color;

  LayerInfo({
    required this.drawLayer,
    required this.label,
    required this.selected,
    this.visible = true,
    required this.color,
  });
}

class Layers {
  final Map<int, LayerInfo> layers = {};

  int get selected =>
      layers.keys.where((key) => layers[key]!.selected).toList().first;

  void addLayer() {
    final nextKey = layers.keys.toList().last + 1;
    layers.updateAll((key, value) {
      value.selected = false;
      return value;
    });
    layers[nextKey] = LayerInfo(
        drawLayer: [],
        label: 'Layer $nextKey',
        selected: true,
        color: randomColor());
  }

  Layers() {
    layers[1] = LayerInfo(
        drawLayer: [], label: 'Layer 1', selected: true, color: randomColor());
  }
}

我像这样测试了canvas.saveLayer,这就是我希望它的行为方式:

与同一图层没有重叠,但与其他图层有明显区别。

所以我希望它在下面的代码中工作相同

class WholeSketchPainter extends CustomPainter {
  final Layers imageLayer;

  WholeSketchPainter({required this.imageLayer});

  @override
  void paint(Canvas canvas, Size size) {
    for (var value in imageLayer.layers.values) {
      print(value.color);
      if (value.visible) {
        canvas.saveLayer(null, Paint()..color = value.color.withOpacity(0.5));
        drawSketch(canvas, value.drawLayer, value.color);
        canvas.restore();
      } else {
        // nothing
      }
    }
  }

  void drawSketch(Canvas canvas, List<Sketch> sketches, Color layerColor) {
    Paint strokePaint = Paint()
      ..style = PaintingStyle.stroke
      ..color = layerColor.withOpacity(1);
    Paint fillPaint = Paint()
      ..style = PaintingStyle.fill
      ..color = layerColor.withOpacity(1);

    for (int i = 0; i < sketches.length; i++) {
      final offsets = sketches[i].points;
      if (offsets.isEmpty) {
        return;
      }
      final path = Path();
      final firstOffset = offsets.first;
      final lastOffset = offsets.last;

      path.moveTo(firstOffset.dx, firstOffset.dy);

      if (sketches[i].sketchType == SketchType.pencil) {
        for (int i = 1; i < offsets.length - 1; i++) {
          final p0 = offsets[i];
          final p1 = offsets[i + 1];
          path.quadraticBezierTo(
              p0.dx, p0.dy, (p0.dx + p1.dx) / 2, (p0.dy + p1.dy) / 2);
        }
        canvas.drawPath(path, fillPaint);
      } else if (sketches[i].sketchType == SketchType.square) {
        final rect = Rect.fromPoints(firstOffset, lastOffset);
        canvas.drawRect(rect, fillPaint);
      }
    }
  }

  @override
  bool shouldRepaint(WholeSketchPainter delegate) {
    return false;
  }
}

但事实并非如此。它不断弹出下面的层并覆盖它。

这就是一层的样子

这就是两层的样子。颜色重叠,层与层之间没有剪辑。

我希望 WholeSketcher 代码像第一个一样,但我不知道该怎么做。有什么解决办法吗?或者有什么办法可以做到吗??

+)整体绘画代码有参考:https://github.com/JideGuru/flutter_drawing_board/tree/master

flutter dart canvas flutter-canvas
1个回答
0
投票

这不是画布的问题。这是List如何保存的问题。当我修复保存列表的方法时 - 它在添加新图层时保存整个草图,它按我的预期工作。无需修复 Paint 方法中的某些内容。

© www.soinside.com 2019 - 2024. All rights reserved.