Open MCDFsteve opened 1 month ago
可以使用整数的描边宽度。但无法完全消除尖刺。
这和 flutter 引擎的底层抗锯齿机制相关。
如果你想要获得尽可能好的视觉效果, 大概只能选择一些较为圆润的字体。尖刺会不那么明显。
如果找到了解决方法,欢迎在这里留言。
这个 Issue 保持开启,因为这是一个实际存在的问题。且其他流行的弹幕库似乎也没有解决。
我将描边绘制方法更改为使用shadow绘制以后,尖刺现象就完全消失了。并且整体视觉效果也很不错。
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'danmaku_content_item.dart';
import 'dart:io'; // 用于检测平台
// 返回根据平台的描边偏移值
double getStrokeOffset() {
if (Platform.isIOS || Platform.isAndroid) {
return 1.0; // iOS 和 Android 使用较小的偏移
} else {
return 1.5; // 其他平台使用较大的偏移
}
}
class Utils {
// 根据文字颜色判断使用的描边颜色
static Color getShadowColor(Color textColor) {
// 如果文字是黑色,使用白色描边
if (textColor == Colors.black || textColor.value == const Color.fromARGB(255, 0, 0, 0).value) {
return Colors.white;
}
// 否则使用黑色描边
return Colors.black;
}
static generateParagraph(DanmakuContentItem content, double danmakuWidth, double fontSize) {
// 获取描边颜色
final shadowColor = getShadowColor(content.color);
final strokeOffset = getStrokeOffset(); // 动态获取偏移量
final ui.ParagraphBuilder builder = ui.ParagraphBuilder(ui.ParagraphStyle(
textAlign: TextAlign.left,
fontSize: fontSize,
textDirection: TextDirection.ltr,
))
..pushStyle(ui.TextStyle(
color: content.color,
shadows: [
ui.Shadow(offset: Offset(-strokeOffset, -strokeOffset), color: shadowColor), // 左上
ui.Shadow(offset: Offset(strokeOffset, -strokeOffset), color: shadowColor), // 右上
ui.Shadow(offset: Offset(-strokeOffset, strokeOffset), color: shadowColor), // 左下
ui.Shadow(offset: Offset(strokeOffset, strokeOffset), color: shadowColor), // 右下
ui.Shadow(offset: Offset(0, -strokeOffset), color: shadowColor), // 上
ui.Shadow(offset: Offset(0, strokeOffset), color: shadowColor), // 下
ui.Shadow(offset: Offset(-strokeOffset, 0), color: shadowColor), // 左
ui.Shadow(offset: Offset(strokeOffset, 0), color: shadowColor), // 右
],
))
..addText(content.text);
return builder.build()
..layout(ui.ParagraphConstraints(width: danmakuWidth));
}
static generateStrokeParagraph(DanmakuContentItem content, double danmakuWidth, double fontSize) {
final Paint strokePaint = Paint()
..style = PaintingStyle.stroke
..strokeWidth = getStrokeOffset() // 使用偏移值来控制描边宽度
..color = (content.color == Colors.black || content.color.value == const Color.fromARGB(255, 0, 0, 0).value)
? Colors.white
: Colors.black;
final ui.ParagraphBuilder strokeBuilder =
ui.ParagraphBuilder(ui.ParagraphStyle(
textAlign: TextAlign.left,
fontSize: fontSize,
textDirection: TextDirection.ltr,
))
..pushStyle(ui.TextStyle(
foreground: strokePaint,
))
..addText(content.text);
return strokeBuilder.build()
..layout(ui.ParagraphConstraints(width: danmakuWidth));
}
}
这样字体在低分辨率设备上会发虚。
不过是很棒的思路。我想想有没有什么更好的解法。
以及这段代码是 GPT 生成的吗,看上去有微妙的不协调。
没在低分辨率测试过。代码确实是gpt写的
我还没有做进一步测试。
不过这种渲染方式应该可以作为一个可选项,在 iOS/macOS/Android 上启用,在 windows/linux 上禁用。
很奇怪。同一份代码,其中macOS的描边宽度是3,IOS和Android设为的1.5. 但是手机上显示出来就有奇怪的尖刺,不知道是因为什么导致的。 尖刺容易出现在字的尖锐处(例如大写的M,2的左下角)