How to decorate text stroke in Flutter?

前端 未结 5 935
孤独总比滥情好
孤独总比滥情好 2020-12-17 09:14

How to decorate text stroke in Flutter? It\'s like -webkit-text-stroke - CSS

相关标签:
5条回答
  • 2020-12-17 09:23

    Inspired by @Gary Qian's answer

    Widget textWithStroke({String text, String fontFamily, double fontSize: 12, double strokeWidth: 1, Color textColor: Colors.white, Color strokeColor: Colors.black}) {
            return Stack(
              children: <Widget>[
                Text(
                  text,
                  style: TextStyle(
                    fontSize: fontSize,
                    fontFamily: fontFamily,
                    foreground: Paint()
                      ..style = PaintingStyle.stroke
                      ..strokeWidth = strokeWidth
                      ..color = strokeColor,
                  ),
                ),
                Text(text, style: TextStyle(fontFamily: fontFamily, fontSize: fontSize, color: textColor)),
              ],
            );
          }
    
    0 讨论(0)
  • 2020-12-17 09:35

    If you prefer the shadows method, you can configure the stroke width using :

    /// Outlines a text using shadows.
    static List<Shadow> outlinedText({double strokeWidth = 2, Color strokeColor = Colors.black, int precision = 5}) {
      Set<Shadow> result = HashSet();
      for (int x = 1; x < strokeWidth + precision; x++) {
        for(int y = 1; y < strokeWidth + precision; y++) {
          double offsetX = x.toDouble();
          double offsetY = y.toDouble();
          result.add(Shadow(offset: Offset(-strokeWidth / offsetX, -strokeWidth / offsetY), color: strokeColor));
          result.add(Shadow(offset: Offset(-strokeWidth / offsetX, strokeWidth / offsetY), color: strokeColor));
          result.add(Shadow(offset: Offset(strokeWidth / offsetX, -strokeWidth / offsetY), color: strokeColor));
          result.add(Shadow(offset: Offset(strokeWidth / offsetX, strokeWidth / offsetY), color: strokeColor));
        }
      }
      return result.toList();
    }
    

    Use it like this :

    Text(
      'My text',
      style: TextStyle(shadows: outlinedText(strokeColor: Colors.blue)),
    );
    
    0 讨论(0)
  • 2020-12-17 09:40

    I was also looking for this, wasn't able to find it. But I did find a workaround using 4 shadows in the TextStyle:

    Text("Border test",
        style: TextStyle(
          inherit: true,
          fontSize: 48.0,
          color: Colors.pink,
          shadows: [
            Shadow( // bottomLeft
              offset: Offset(-1.5, -1.5),
              color: Colors.white
            ),
            Shadow( // bottomRight
              offset: Offset(1.5, -1.5),
              color: Colors.white
            ),
            Shadow( // topRight
              offset: Offset(1.5, 1.5),
              color: Colors.white
            ),
            Shadow( // topLeft
              offset: Offset(-1.5, 1.5),
              color: Colors.white
            ),
          ]
        ),
    );
    

    I also opened an Issue on GitHub: https://github.com/flutter/flutter/issues/24108

    0 讨论(0)
  • 2020-12-17 09:45

    Stroke has been possible without workarounds since the addition of foreground paints in TextStyle. An explicit example of stroke under fill bordered text has been added in the TextStyle documentation: https://master-api.flutter.dev/flutter/painting/TextStyle-class.html#painting.TextStyle.6

    This example is reproduced here:

    Stack(
      children: <Widget>[
        // Stroked text as border.
        Text(
          'Greetings, planet!',
          style: TextStyle(
            fontSize: 40,
            foreground: Paint()
              ..style = PaintingStyle.stroke
              ..strokeWidth = 6
              ..color = Colors.blue[700],
          ),
        ),
        // Solid text as fill.
        Text(
          'Greetings, planet!',
          style: TextStyle(
            fontSize: 40,
            color: Colors.grey[300],
          ),
        ),
      ],
    )
    

    Stroke by itself is possible by removing the Stack and just using the first stroke Text widget by itself. The stroke/fill order can also be adjusted by swapping the first and second Text widget.

    0 讨论(0)
  • 2020-12-17 09:48

    Inspired by this article, to achieve the effect, I prefer to use a technique that mixes two Text widgets and TextStype.foreground property with custom Paint():

    class StrokeText extends StatelessWidget {
      final String text;
      final double fontSize;
      final FontWeight fontWeight;
      final Color color;
      final Color strokeColor;
      final double strokeWidth;
    
      const StrokeText(
        this.text, {
        Key key,
        this.fontSize,
        this.fontWeight,
        this.color,
        this.strokeColor,
        this.strokeWidth,
      }) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Stack(
          children: [
            Text(
              text,
              style: TextStyle(
                fontSize: fontSize,
                fontWeight: fontWeight,
                foreground: Paint()..color = color,
              ),
            ),
            Text(
              text,
              style: TextStyle(
                fontSize: fontSize,
                fontWeight: fontWeight,
                foreground: Paint()
                  ..strokeWidth = strokeWidth
                  ..color = strokeColor
                  ..style = PaintingStyle.stroke,
              ),
            ),
          ],
        );
      }
    }
    
    0 讨论(0)
提交回复
热议问题