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;
}
我正在努力
我知道如何给容器添加阴影,但我不知道如何添加不同的颜色或白色反射。
我试过这样做:
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;
}