Flutter:用于边界容器的高级霓虹灯 UI

Flutter: Advanced neon UI for border container

我正在努力

我知道如何给容器添加阴影,但我不知道如何添加不同的颜色或白色反射。

我试过这样做:

Container(
  width: MediaQuery.of(context).size.width * 0.7,
  height: 50,
  decoration: BoxDecoration(
    boxShadow: [
            BoxShadow(
              color: Color(0XFF900ee5),
              offset: Offset(0, 0),
              blurRadius: 20,
              spreadRadius: 10,
            )
          ],
      borderRadius: BorderRadius.circular(100),
      border: Border.all(color: Color(0XFFff00ff), width: 4)),
      child: Center(child: AutoSizeText('BUTTON')),
);

它不起作用,我会尝试使用油漆,但是你有什么 link 可以帮助我用白色反射渲染得更真实吗?

一如既往,这里的一切都取决于您的想象力,元素越多,它看起来就越逼真。这里棘手的部分是阴影,我自己在那里作弊了一点,你可以从线的两侧缩放一个大阴影,然后在中心添加新的黑色阴影看起来更自然。

重现代码

import 'dart:typed_data';

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'CustomPaint spotlight',
      home: Scaffold(
        backgroundColor: Colors.black,
        appBar: AppBar(
          title: Text('CustomPaint spotlight'),
        ),
        body: Center(
          child: 
          CustomPaint(
            foregroundPainter: BorderPainter(),
            child: Container(
              width: 500,
              height: 100,
            ),
          ),
        ),
      ),
    );
  }
}

class BorderPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    double sh = size.height; // for convenient shortage
    double sw = size.width; // for convenient shortage
    double th = sh * 0.1; // total frame thickness
    double side = sw * 0.12; 

    Paint outerPaint = Paint()
      ..color = Color(0xFF9600FC)
      ..strokeWidth = th
      ..style = PaintingStyle.stroke
      ..strokeCap = StrokeCap.round;

    Paint lightTopPaint = Paint()
      ..color = Color(0XFFD197F9)
      ..style = PaintingStyle.fill;

    Paint lightSmallPaint = Paint()
      ..color = Colors.white
      ..strokeWidth = th*0.06
      ..strokeCap = StrokeCap.round
      ..style = PaintingStyle.stroke;

    Paint arcPaint = Paint()
      ..color = Color(0xFF3D0066)
      ..style = PaintingStyle.fill;

    Paint minilinePaint = Paint()
      ..color = Color(0xFF180029)
      ..strokeCap = StrokeCap.round
      ..style = PaintingStyle.stroke
      ..strokeWidth = th*0.06;
      
    Path outerPath = Path()
      ..moveTo(side, 0)
      ..lineTo(sw - side, 0)
      ..quadraticBezierTo(sw, 0, sw, sh/2)
      ..quadraticBezierTo(sw, sh, sw - side, sh)
      ..lineTo(side, sh)
      ..quadraticBezierTo(0, sh, 0, sh/2)
      ..quadraticBezierTo(0, 0, side, 0);
      
      
    Path lightTop = Path()
      ..moveTo(-th, sh/2)
      ..quadraticBezierTo(0, 0, side, -th/3)
      ..lineTo(sw-side, -th/3)
      ..quadraticBezierTo(sw, 0, sw+th, sh/2)
      ..quadraticBezierTo(sw, 0, sw-side, th/20)
      ..lineTo(side, th/20)
      ..quadraticBezierTo(0, 0, -th, sh/2);

        Path lightBottom = Path()
      ..moveTo(-th, sh/2)
      ..quadraticBezierTo(0, sh, side, sh+th/3)
      ..lineTo(sw-side, sh+th/3)
      ..quadraticBezierTo(sw, sh, sw+th, sh/2)
      ..quadraticBezierTo(sw, sh, sw-side, sh - th/20)
      ..lineTo(side, sh - th/20)
      ..quadraticBezierTo(0, sh, -th, sh/2);

    Path lightSmallTop = Path()
      ..moveTo(side*0.8, th*0.3)
      ..lineTo(sw-side*0.8, th*0.3);

    Path miniLineTop = Path()
      ..moveTo(side*0.8, th/3)
      ..lineTo(sw - side*0.8, th/3);

    Path miniLineBottom = Path()
      ..moveTo(side*0.8, sh+th/3)
      ..lineTo(sw - side*0.8, sh+th/3);

    Path lightSmallBottom = Path()
      ..moveTo(side*0.8, sh -th*0.3)
      ..lineTo(sw-side*0.8, sh -th*0.3);



    Path leftArc = Path()
      ..moveTo(side, -th/2)
      ..quadraticBezierTo(0, 0, -th/2, sh/2)
      ..quadraticBezierTo(0, sh, side, sh)
      ..quadraticBezierTo(0, sh, 0, sh/2)
      ..quadraticBezierTo(0, 0, side, -th/2);

    Path rightArc = Path()
      ..moveTo(sw - side, th/2)
      ..quadraticBezierTo(sw, 0, sw + th/2, sh/2)
      ..quadraticBezierTo(sw, sh, sw-side, sh)
      ..quadraticBezierTo(sw, sh, sw, sh/2)
      ..quadraticBezierTo(sw, 0, sw-side, th/2);


    Float64List matrix4 = Float64List.fromList([1,0,0,0,
                              0,0.3,0,0,
                              0,0,1,0,
                              0,0,0,1,]);


    canvas.drawShadow(outerPath.transform(matrix4).shift(Offset(0,-sh)), Color(0xFF9600FC), sh, true);
    canvas.drawShadow(outerPath.transform(matrix4).shift(Offset(0,0)), Color(0xFF9600FC), sh, true);

    canvas.drawPath(outerPath, outerPaint);
    canvas.drawPath(lightTop, lightTopPaint);
    canvas.drawPath(miniLineTop, minilinePaint);
    canvas.drawPath(miniLineBottom, minilinePaint);
    canvas.drawPath(lightBottom, lightTopPaint);
    canvas.drawPath(lightSmallTop, lightSmallPaint);
    canvas.drawPath(lightSmallBottom, lightSmallPaint);
    canvas.drawPath(leftArc, arcPaint);
    canvas.drawPath(rightArc, arcPaint);

  }

  @override
  bool shouldRepaint(BorderPainter oldDelegate) => false;

  @override
  bool shouldRebuildSemantics(BorderPainter oldDelegate) => false;
}