nbedos/termtosvg

Disable animation looping

masaeedu opened this issue · 6 comments

Hi there. Thanks for a very useful utility. I'm trying to add some recordings to a presentation, but can't figure out how to get the animation to simply stop once it reaches the end of the recording (instead of immediately looping back around). I tried poking around in the generated SVG but couldn't figure out how to get this to work (not very skilled at SMIL or SVG).

Deleting the anim_last.end+... hooks from all the begin attributes seemed to be what I'd need, but this simply makes everything disappear at the end of the animation rather than stopping at the final state of the screen.

Unfortunately I don't think it can easily be done by tweaking the SVG file.

termtosvg uses animate elements to show lines of the terminal by changing display="none" to display="inline" at a specific time (animate.begin) and for a specific duration (animate.dur). Once the duration set for an animate element has elapsed, the corresponding lines are hidden.

So in order to keep the last frame of the animation on the screen we would need to identify which lines are displayed last and then add a fill="freeze" attribute to the corresponding animate tag. Unless you've got a very simple animation it's probably a pain to do by hand.

@nbedos Do you think there's a way to change the SVG output that's getting interpolated into the templates in such a way that it's possible to recognize which elements are part of a single "frame"?

@masaeedu No, sorry, I'd rather not add more information in the SVG output. As of today the ouput of termtosvg is kind of messy and it needs to be reworked. I'll keep in mind that you're interested in getting an animation that does not loop.

I needed this non-looping behaviour for similar reasons, namely incorporating SVG animations in presentation.

It turns out that this is possible with an SVG template, by including Javascript which pauses (i.e. stops forever) the animation at the "end". This solution is definitely hacky, but it works without needing to modify termtosvg.

The script to include in the template is as follows:

    <script type="text/javascript">
        <![CDATA[
            var terminal = document.getElementById('terminal');
            var screen = terminal.getElementById('screen');
            var style = getComputedStyle(terminal);
            var animationDuration = parseInt(style.getPropertyValue('--animation-duration')) / 1000;

            function stop() {
                terminal.pauseAnimations();
                screen.pauseAnimations();
            }

            let now = screen.getCurrentTime();
            let remainingTime = animationDuration - now;

            setTimeout(stop, remainingTime * 1000);
        ]]>
    </script>

With c9a3ecb I've changed the way animations are created by termtosvg. This makes it possible to disable looping without using javascript.

See https://github.com/nbedos/termtosvg/blob/develop/man/termtosvg-templates.md#restricting-the-animation-to-a-single-loop

Feature included in version 0.9.0