paint method

  1. @override
void paint(
  1. TouchRippleContext context,
  2. Canvas canvas,
  3. Size size
)
override

Implementation

@override
void paint(TouchRippleContext context, Canvas canvas, Size size) {
  // Returns how far the given offset is from the centre of the canvas size,
  // defined as a percentage (0~1), relative to the canvas size.
  Offset centerToRatioOf(Offset offset) {
    final sizeOffset = sizeToOffset(size);
    final dx = (offset.dx / sizeOffset.dx) - 0.5;
    final dy = (offset.dy / sizeOffset.dy) - 0.5;

    return Offset(dx.abs(), dy.abs());
  }

  // If a touch event occurs at the exact center,
  // it is the size at which the touch ripple effect fills completely.
  final centerDistance = sizeToOffset(size / 2).distance;

  // However, since touch events don't actually occur at the exact center but at various offsets,
  // it is necessary to compensate for this.
  //
  // If the touch event moves away from the center,
  // the touch ripple effect should expand in size accordingly.
  //
  // This defines the additional scale that needs to be expanded.
  final centerToRatio = centerToRatioOf(baseOffset);

  // The background color of a spread ripple effect.
  final color = context.rippleColor;

  // Return the radius pixels of a blur filter to touch ripple.
  final blurRadius = context.rippleBlur.calculateRadius(this, size);

  // This defines the additional touch ripple size.
  final distance = Offset(
    sizeToOffset(size).dx * centerToRatio.dx,
    sizeToOffset(size).dy * centerToRatio.dy,
  ).distance + (blurRadius * 2);

  final radius = centerDistance + distance + context.ripplePadding * 2;
  final paintSize = radius * spreadPercent;
  final paintColor = color.withAlpha(((color.alpha) * fadePercent).toInt());
  final paint = Paint()
    ..color = paintColor
    ..style = PaintingStyle.fill;

  if (context.useSparkleShader) {
    if (!TouchRippleShader.initCalled) {
      TouchRippleShader.initializeShader();
    }

    if (TouchRippleShader.isInitialized) {
      paint.shader = _sparkleShader ??= TouchRippleShader.program.fragmentShader();

      TouchRippleShader.updateFragmentShader(
        shader: _sparkleShader!,
        color: context.rippleColor,
        alpha: 1.0,
        rippleScale: spreadPercent,
        rippleAlpha: fadePercent,
        center: baseOffset,
        radius: radius,
        blurRatio: context.sparkleRippleBlur,
        size: size
      );

      canvas.drawCircle(baseOffset, radius, paint);
      return;
    }
  }

  if (blurRadius != 0) {
    paint.maskFilter = MaskFilter.blur(BlurStyle.normal, blurRadius);
  }

  canvas.drawCircle(baseOffset, paintSize * context.rippleScale, paint);
}