-
Notifications
You must be signed in to change notification settings - Fork 814
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CSS Transition rubber bands when %'s are used #2940
Comments
I didn't even know there was a I've modified the example hoping it would make it clearer what is happening. This has a custom widget with a slower linear transition, which displays its current width size. However at the moment I'm still struggling to debug this! from rich.console import RenderableType
from textual.app import App, ComposeResult
from textual.containers import Container
from textual.widget import Widget
from textual.widgets import Button
class TestWidget(Widget, can_focus=True):
DEFAULT_CSS = """
TestWidget {
background: red;
height: 3;
width: 20%;
transition: width 10000ms linear;
content-align: center middle;
text-style: bold;
}
TestWidget:focus {
width: 80%;
text-style: bold reverse;
}
TestWidget:blur {
width: 20%;
}
"""
def render(self) -> RenderableType:
return str(self.size.width)
class Issue2940(App[None]):
CSS = """
Container {
width: 100;
height: auto;
background: $panel;
}
"""
def compose(self) -> ComposeResult:
with Container():
yield Button("Reset Focus")
yield TestWidget()
if __name__ == "__main__":
Issue2940().run() [EDIT: Forgot I also changed Container width to 100 columns to more easily check percentages] |
Ah-ha... If you set the initial width to 20 columns rather than 20%, I think my example shows what is happening. On focus, the width will shrink until 16 (80% of the widget width of 20), before suddenly jumping to 80 (80% of the container width). On blur, the width suddenly reduces to 64 (80% of the widget width of 80), then shrinks until 20 (20% of the container width). |
@TomJGooding It currently has the status of "undocumented feature". |
@TomJGooding that's some fine detective work! @davep the same behavior can be seen when using from textual.app import App, ComposeResult
from textual.widgets import Header, Input, Footer, Button
from textual.containers import Container
from textual.widgets import Input
from textual.events import Focus, Blur
class AnimatedInput(Input):
"""A custom input widget that animates its width when focused or blurred"""
DEFAULT_CSS = """
AnimatedInput {
height: 3;
width: 20%;
background: $surface;
border: round $panel-lighten-2;
}
AnimatedInput:focus {
border: round $accent;
}
"""
def on_focus(self, _event: Focus) -> None:
"""Animates the input width when it is focused.
This method is called when the input receives focus.
"""
self.styles.animate(
"width",
value="85%",
duration=0.5,
)
def on_blur(self, _event: Blur) -> None:
"""Animates the input width when it loses focus.
This method is called when the input loses focus.
"""
self.styles.animate("width", value="20%", duration=0.5)
class Issue2940(App[None]):
TITLE = "Test Issue 2940"
def compose(self) -> ComposeResult:
yield Header()
with Container():
yield AnimatedInput()
yield Button('focusable')
yield Footer()
if __name__ == "__main__":
Issue2940().run()``` |
@epi052 To be clear: I was simply letting Tom know why he'd failed to find the stylesheet-based version in the docs, not suggesting this wasn't a general issue. |
@davep I didn't think you were being dismissive. Y'all are insanely helpful. It was more to confirm that it exists in both entry points to that functionality. Should have included it in the original, just wasn't thinking about animate at the time |
I might be barking up the wrong tree, but would a maintainer mind explaining what the I'm probably out of my depth but I'm now invested in trying to solve this! |
|
Thanks Will for clarifying. I think the problem is how the start and destination are 'resolved' here, but after that I'm afraid I'm getting a bit lost textual/src/textual/css/scalar_animation.py Lines 38 to 42 in 2f055f6
|
Sorry could I also double-check: should the If I've understood this correctly, shouldn't |
Have you checked closed issues? https://github.com/Textualize/textual/issues?q=is%3Aissue+is%3Aclosed
yes
Please give a brief but clear explanation of the issue. If you can, include a complete working example that demonstrates the bug. Check it can run without modifications.
current: when using the
transition
css property onwidth
with a percentage-based start/stop, the animation is jerky/rubber-bands. When moving from larger to smaller, it seems to move past the desired value (maybe to the default widget size?) then snap back to the specified value. When moving from smaller to larger, it appears to start moving from at or near a width of zero, hitting the current width, and then snapping out to the desired width.expected: transition should look like the
textual easing
examples when applied to %-based widths.of note: when using concrete values instead of percents, all seems well.
vokoscreenNG-2023-07-14_06-17-21.mp4
Textual Diagnostics
Versions
Python
Operating System
Terminal
Rich Console options
Feel free to add screenshots and / or videos. These can be very helpful!
The text was updated successfully, but these errors were encountered: