draw method

  1. @override
void draw(
  1. Canvas canvas
)
override

Implementation

@override
void draw(ui.Canvas canvas) {
  var aabb = artboard.artboardAABB();
  Rect bounds = Rect.fromLTRB(aabb[0], aabb[1], aabb[2], aabb[3]);

  double baseBlurX = 0;
  double baseBlurY = 0;
  Paint layerPaint = Paint()..isAntiAlias = antialias;
  Color layerColor = Colors.white.withOpacity(parent!.renderOpacity);
  layerPaint.color = layerColor;
  if (blur?.isActive ?? false) {
    baseBlurX = blur!.blurX;
    baseBlurY = blur!.blurY;
    layerPaint.imageFilter = _blurFilter(baseBlurX, baseBlurY);
  }

  if (dropShadows.isNotEmpty) {
    for (final dropShadow in dropShadows) {
      if (!dropShadow.isActive) {
        continue;
      }
      // DropShadow: To draw a shadow we just draw the shape (with
      // drawPass) with a custom color and image (blur) filter before
      // drawing the main shape.
      canvas.save();
      var color = dropShadow.color;
      canvas.translate(dropShadow.offsetX, dropShadow.offsetY);

      // Adjust bounds for offset.
      var adjustedBounds = Rect.fromLTRB(
        bounds.left - dropShadow.offsetX.abs(),
        bounds.top - dropShadow.offsetY.abs(),
        bounds.right + dropShadow.offsetX.abs(),
        bounds.bottom + dropShadow.offsetY.abs(),
      );

      var shadowPaint = Paint()
        ..isAntiAlias = antialias
        ..color = layerColor
        ..imageFilter = _blurFilter(
            dropShadow.blurX + baseBlurX, dropShadow.blurY + baseBlurY)
        ..colorFilter = ui.ColorFilter.mode(
            ui.Color.fromRGBO(
                (color[0] * 255.0).round(),
                (color[1] * 255.0).round(),
                (color[2] * 255.0).round(),
                color[3]),
            ui.BlendMode.srcIn)
        ..blendMode = ui.BlendMode.values[dropShadow.blendModeId];

      drawPass(canvas, adjustedBounds, shadowPaint);
      canvas.restore();
      canvas.restore();
    }
  }
  drawPass(canvas, bounds, layerPaint);
  // Draw inner shadows on the main layer.
  if (innerShadows.isNotEmpty) {
    for (final innerShadow in innerShadows) {
      if (!innerShadow.isActive) {
        continue;
      }
      var blendMode = ui.BlendMode.values[innerShadow.blendModeId];
      bool extraBlendPass = blendMode != ui.BlendMode.srcOver;
      if (extraBlendPass) {
        // if we have a custom blend mode, then we can't just srcATop with
        // what's already been drawn. We need to draw the contents as a mask
        // to then draw the shadow on top of with srcIn to only show the
        // shadow and finally composite with the desired blend mode requested
        // here.
        var extraLayerPaint = Paint()
          ..blendMode = blendMode
          ..isAntiAlias = antialias;
        drawPass(canvas, bounds, extraLayerPaint);
      }

      // because there's no way to compose image filters (use two filters in
      // one) we have to use an extra layer to invert the alpha for the inner
      // shadow before blurring.

      var color = innerShadow.color;
      var shadowPaint = Paint()
        ..isAntiAlias = antialias
        ..color = layerColor
        ..blendMode =
            extraBlendPass ? ui.BlendMode.srcIn : ui.BlendMode.srcATop
        ..imageFilter = _blurFilter(
            innerShadow.blurX + baseBlurX, innerShadow.blurY + baseBlurY)
        ..colorFilter = ui.ColorFilter.mode(
            ui.Color.fromRGBO(
                (color[0] * 255.0).round(),
                (color[1] * 255.0).round(),
                (color[2] * 255.0).round(),
                color[3]),
            ui.BlendMode.srcIn);

      canvas.saveLayer(bounds, shadowPaint);
      canvas.translate(innerShadow.offsetX, innerShadow.offsetY);
      // Adjust bounds for offset.
      var adjustedBounds = Rect.fromLTRB(
        bounds.left - innerShadow.offsetX.abs(),
        bounds.top - innerShadow.offsetY.abs(),
        bounds.right + innerShadow.offsetX.abs(),
        bounds.bottom + innerShadow.offsetY.abs(),
      );

      // Invert the alpha to compute inner part.
      var invertPaint = Paint()
        ..isAntiAlias = antialias
        ..colorFilter = const ui.ColorFilter.matrix([
          1,
          0,
          0,
          0,
          0,
          0,
          1,
          0,
          0,
          0,
          0,
          0,
          1,
          0,
          0,
          0,
          0,
          0,
          -1,
          255,
        ]);
      drawPass(canvas, adjustedBounds, invertPaint);
      // restore draw pass (inverted aint)
      canvas.restore();
      // restore save layer used to that blurs and colors the shadow
      canvas.restore();

      if (extraBlendPass) {
        // Restore extra layer used to draw the contents to clip against (we
        // clip by drawing with srcIn)
        canvas.restore();
      }
    }
  }
  canvas.restore();
}