Skip to content

TextStyle.lerp() does not properly interpolate text shadows #145665

Closed

Description

@leoafarias

Steps to reproduce

  1. Create two TextStyle instances with different shadows lists. For example:

    final style1 = TextStyle(
      fontSize: 24,
      shadows: [
        Shadow(
          blurRadius: 10,
          color: Colors.blue,
          offset: Offset(0, 0),
        ),
      ],
    );
    
    final style2 = TextStyle(
      fontSize: 24,
      shadows: [
        Shadow(
          blurRadius: 20,
          color: Colors.red,
          offset: Offset(5, 5),
        ),
      ],
    );
  2. Use TextStyle.lerp() to interpolate between the two styles with an interpolation factor (t) of your choice. For example:

    final interpolatedStyle = TextStyle.lerp(style1, style2, 0.5);
  3. Observe that the resulting interpolatedStyle does not have smoothly interpolated shadow properties. Instead, it will abruptly switch between the shadows lists of style1 and style2 based on the value of t.

  4. Vary the interpolation factor (t) and notice that the text shadows do not gradually transition between the two styles. They will instantly change from one set of shadows to another at the midpoint of the interpolation.

  5. To see this behavior in action, you can use TextStyle.lerp() within an animation or a widget that animates the interpolation factor over time, such as AnimatedDefaultTextStyle or AnimatedBuilder. Observe that the text shadows do not smoothly animate between the two styles and instead abruptly switch at the midpoint of the animation.

Expected results

When interpolating between two TextStyle instances using TextStyle.lerp(), the shadows property should be smoothly interpolated based on the provided interpolation factor (t). This can be adjusted by using ui.Shadow.listLerp() as part

Each shadow's blurRadius, color, and offset should be linearly combined from the corresponding values in the input styles.

POC example: https://dartpad.dev/?id=799c4bec8b791b74580193174759b93d

Actual results

TextStyle.lerp() does not correctly interpolate the shadows property between two TextStyle instances.

Instead of smoothly transitioning each shadow's blurRadius, color, and offset based on the interpolation factor (t), it abruptly switches between the entire shadows lists at the midpoint of the interpolation.

This results in a visually inconsistent and jarring transition of text shadows, not meeting the expected smooth interpolation behavior.

Code sample

https://dartpad.dev/?id=08ea4c1134faccc09935c84eeac85322

Screenshots or Video

No response

Logs

No response

Flutter Doctor output

N/A

Activity

  1. danagbemava-nc commented on Mar 25, 2024

    @danagbemava-nc
    Member

    Reproducible using the code sample provided above.

    Screen.Recording.2024-03-25.at.11.20.31.mov
    sample (from dartpad above)
    import 'dart:ui' as ui show Shadow, lerpDouble;
    
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            body: Center(
              child: ShadowLerpExample(),
            ),
          ),
        );
      }
    }
    
    class ShadowLerpExample extends StatefulWidget {
      @override
      _ShadowLerpExampleState createState() => _ShadowLerpExampleState();
    }
    
    class _ShadowLerpExampleState extends State<ShadowLerpExample>
        with SingleTickerProviderStateMixin {
      late AnimationController _controller;
      late Animation<double> _animation;
    
      @override
      void initState() {
        super.initState();
        _controller = AnimationController(
          duration: const Duration(seconds: 4),
          vsync: this,
        )..repeat(reverse: true);
        _animation = Tween<double>(begin: 0, end: 1).animate(_controller);
      }
    
      @override
      void dispose() {
        _controller.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return AnimatedBuilder(
          animation: _animation,
          builder: (context, child) {
            return Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text(
                  'TextStyle.lerp()',
                  style: TextStyle.lerp(
                    const TextStyle(
                      fontSize: 24,
                      shadows: [
                        Shadow(
                          blurRadius: 10,
                          color: Colors.blue,
                          offset: Offset(0, 0),
                        ),
                        Shadow(
                          blurRadius: 5,
                          color: Colors.green,
                          offset: Offset(10, 10),
                        ),
                      ],
                    ),
                    const TextStyle(
                      fontSize: 48,
                      shadows: [
                        Shadow(
                          blurRadius: 20,
                          color: Colors.red,
                          offset: Offset(5, 5),
                        ),
                        Shadow(
                          blurRadius: 10,
                          color: Colors.purple,
                          offset: Offset(-10, -10),
                        ),
                      ],
                    ),
                    _animation.value,
                  ),
                ),
                const SizedBox(height: 20),
                Text(
                  'Shadow.lerpList()',
                  style: TextStyle(
                    fontSize: ui.lerpDouble(24, 48, _animation.value)!,
                    shadows: ui.Shadow.lerpList(
                      [
                        const Shadow(
                          blurRadius: 10,
                          color: Colors.blue,
                          offset: Offset(0, 0),
                        ),
                        const Shadow(
                          blurRadius: 5,
                          color: Colors.green,
                          offset: Offset(10, 10),
                        ),
                      ],
                      [
                        const Shadow(
                          blurRadius: 20,
                          color: Colors.red,
                          offset: Offset(5, 5),
                        ),
                        const Shadow(
                          blurRadius: 10,
                          color: Colors.purple,
                          offset: Offset(-10, -10),
                        ),
                      ],
                      _animation.value,
                    ),
                  ),
                ),
              ],
            );
          },
        );
      }
    }
    flutter doctor -v
    [!] Flutter (Channel stable, 3.19.4, on macOS 14.3.1 23D60 darwin-arm64, locale en-GB)
        • Flutter version 3.19.4 on channel stable at /Users/nexus/dev/sdks/flutter
        ! Warning: `flutter` on your path resolves to /Users/nexus/dev/sdks/flutters/bin/flutter, which is not inside your current Flutter SDK checkout at /Users/nexus/dev/sdks/flutter. Consider adding /Users/nexus/dev/sdks/flutter/bin to the front of your path.
        ! Warning: `dart` on your path resolves to /Users/nexus/dev/sdks/flutters/bin/dart, which is not inside your current Flutter SDK checkout at /Users/nexus/dev/sdks/flutter. Consider adding /Users/nexus/dev/sdks/flutter/bin to the front of your path.
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision 68bfaea224 (5 days ago), 2024-03-20 15:36:31 -0700
        • Engine revision a5c24f538d
        • Dart version 3.3.2
        • DevTools version 2.31.1
        • If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades.
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
        • Android SDK at /Users/nexus/Library/Android/sdk
        • Platform android-34, build-tools 34.0.0
        • Java binary at: /Users/nexus/Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
        • Java version OpenJDK Runtime Environment (build 17.0.7+0-17.0.7b1000.6-10550314)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS (Xcode 15.3)
        • Xcode at /Applications/Xcode-15.3.0.app/Contents/Developer
        • Build 15E204a
        • CocoaPods version 1.14.3
    
    [✓] Chrome - develop for the web
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [✓] Android Studio (version 2023.1)
        • Android Studio at /Users/nexus/Applications/Android Studio.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        • Java version OpenJDK Runtime Environment (build 17.0.7+0-17.0.7b1000.6-10550314)
    
    [✓] IntelliJ IDEA Ultimate Edition (version 2023.2.5)
        • IntelliJ at /Users/nexus/Applications/IntelliJ IDEA Ultimate.app
        • Flutter plugin version 77.2.2
        • Dart plugin version 232.10286
    
    [✓] VS Code (version 1.87.2)
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.84.0
    
    [✓] Connected device (3 available)
        • Dean’s iPad (mobile) • 00008103-000825C811E3401E • ios            • iOS 17.4.1 21E236
        • macOS (desktop)      • macos                     • darwin-arm64   • macOS 14.3.1 23D60 darwin-arm64
        • Chrome (web)         • chrome                    • web-javascript • Google Chrome 123.0.6312.58
    
    [✓] Network resources
        • All expected network resources are available.
    
    ! Doctor found issues in 1 category.
    
    [✓] Flutter (Channel master, 3.21.0-14.0.pre.9, on macOS 14.3.1 23D60 darwin-arm64, locale en-GB)
        • Flutter version 3.21.0-14.0.pre.9 on channel master at /Users/nexus/dev/sdks/flutters
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision 7f06c263a4 (7 hours ago), 2024-03-25 00:33:34 -0400
        • Engine revision ae758d5463
        • Dart version 3.4.0 (build 3.4.0-268.0.dev)
        • DevTools version 2.34.0-dev.12
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
        • Android SDK at /Users/nexus/Library/Android/sdk
        • Platform android-34, build-tools 34.0.0
        • Java binary at: /Users/nexus/Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
        • Java version OpenJDK Runtime Environment (build 17.0.7+0-17.0.7b1000.6-10550314)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS (Xcode 15.3)
        • Xcode at /Applications/Xcode-15.3.0.app/Contents/Developer
        • Build 15E204a
        • CocoaPods version 1.14.3
    
    [✓] Chrome - develop for the web
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [✓] Android Studio (version 2023.1)
        • Android Studio at /Users/nexus/Applications/Android Studio.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        • Java version OpenJDK Runtime Environment (build 17.0.7+0-17.0.7b1000.6-10550314)
    
    [✓] IntelliJ IDEA Ultimate Edition (version 2023.2.5)
        • IntelliJ at /Users/nexus/Applications/IntelliJ IDEA Ultimate.app
        • Flutter plugin version 77.2.2
        • Dart plugin version 232.10286
    
    [✓] VS Code (version 1.87.2)
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.84.0
    
    [✓] Connected device (3 available)
        • macOS (desktop)                 • macos                 • darwin-arm64   • macOS 14.3.1 23D60 darwin-arm64
        • Mac Designed for iPad (desktop) • mac-designed-for-ipad • darwin         • macOS 14.3.1 23D60 darwin-arm64
        • Chrome (web)                    • chrome                • web-javascript • Google Chrome 123.0.6312.58
        ! Error: Browsing on the local area network for Dean’s iPad. Ensure the device is unlocked and attached with a cable or associated with the same local area network as this Mac.
          The device must be opted into Developer Mode to connect wirelessly. (code -27)
    
    [✓] Network resources
        • All expected network resources are available.
    
    • No issues found!
    
  2. added
    frameworkflutter/packages/flutter repository. See also f: labels.
    a: typographyText rendering, possibly libtxt
    has reproducible stepsThe issue has been confirmed reproducible and is ready to work on
    and removed
    in triagePresently being triaged by the triage team
    a: typographyText rendering, possibly libtxt
    on Mar 25, 2024
  3. added
    P2Important issues not at the top of the work list
    on Mar 26, 2024
  4. added a commit that references this issue on Apr 3, 2024
    2759ec2
  5. added
    r: fixedIssue is closed as already fixed in a newer version
    on Apr 4, 2024
  6. github-actions commented on Apr 18, 2024

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  7. locked as resolved and limited conversation to collaborators on Apr 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work lista: animationAnimation APIsfound in release: 3.19Found to occur in 3.19found in release: 3.21Found to occur in 3.21frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onr: fixedIssue is closed as already fixed in a newer versionteam-frameworkOwned by Framework teamtriaged-frameworkTriaged by Framework team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions