Deprecated SMIL SVG animation replaced with CSS or Web animations effects (hover, click)

Artem.Borysov picture Artem.Borysov · Jun 21, 2015 · Viewed 31.6k times · Source

In accordance with this topic:

Firefox 38-40 SMIL problems - very slow speed (resolved in FF version 41 from 22.09.15)

and this topic:

Intent to deprecate: SMIL

SVG tag 'animateTransform' does not work well. It would be nice to replace SMIL (animate tag) with CSS or CSS transitions.

CONSOLE WARNING: Please use CSS animations or Web animations instead),
which would work fast on the latest versions of Firefox and Chrome.

The next Google Chrome warning:

CONSOLE WARNING: SVG's SMIL animations ('animate', 'set', etc.) are deprecated 
and will be removed. Please use CSS animations or Web animations instead.

Revision 196823: Add SMIL deprecation warning


For a start, I need to implement three things:

1) Hover effect on mouse over(the easiest)

How it was:

<rect x="-0.5" y="-0.5" width="1" height="1" fill="white">
    <!--it makes half-visible selecting effect -->
    <set attributeName="stroke-opacity" begin="mouseover" end="mouseout" to="0.5"/>
    <!-- explicitly reverse the opacity animation on mouseout -->
    <set attributeName="stroke-opacity" begin="mouseout" end="mouseover" to="1"/>
</rect>

I removed the set tags, added classes to the rect tag and added to this to the CSS hover Pseudo-class:

.element_tpl:hover {
    stroke-opacity: 0.5;
}

2) It scales a few times after change committed to this element (pageload)

How it was:

<!--animation-->
<!--it scales a few times after change committed to this element -->
<animateTransform attributeType="XML" attributeName="transform" type="scale" dur="0.5s" keyTimes="0;0.5;0.5;1" values="1;1.12;1.12;1" repeatCount="6" fill="freeze"/>

How to organize without the animate tag:

???


3) It animates scale up and scale down (onclick)

How it was:

<!--it animates scale up and scale down onclick -->
    <animateTransform attributeName="transform" attributeType="XML" type="scale" from="1" to="1.15" repeatCount="1" begin="mousedown+0.2s" dur = "0.2s" fill="freeze"/>
    <animateTransform attributeName="transform" attributeType="XML" type="scale" from="1.15" to="1" repeatCount="1" begin="mouseup+0.4s" dur = "0.2s" fill="freeze"/>

How to organize without animate tag? Tried to use :active, but there are differences in the behavior:

.element_tpl:active {
    transform: scale(1.1); 
}

This is the entire code of my template element:

<g id="switcher" cursor="pointer" stroke-width="0.15">
    <g transform="scale(1,1.375)">
        <g>
            <rect x="-0.5" y="-0.5" width="1" height="1" stroke="white" pointer-events="none"/>
            <rect x="-0.5" y="-0.5" width="1" height="1" fill="white">
                <!--it makes half-visible selecting effect -->
                <set attributeName="stroke-opacity" begin="mouseover" end="mouseout" to="0.5"/>
                <!-- explicitly reverse the opacity animation on mouseout -->
                <set attributeName="stroke-opacity" begin="mouseout" end="mouseover" to="1"/>
            </rect>
            <line x1="0" y1="-0.25" x2="0" y2="0.25" stroke-width="0.17" stroke-linecap="round" pointer-events="none"/><!-- vertical on -->
            <!--animation-->
            <!--it scales a few times after change committed to this element -->
            <animateTransform attributeType="XML" attributeName="transform" type="scale" dur="0.5s" keyTimes="0;0.5;0.5;1" values="1;1.12;1.12;1" repeatCount="6" fill="freeze"/>
            <!--it animates scale up and scale down onclick -->
            <animateTransform attributeName="transform" attributeType="XML"
            type="scale" from="1" to="1.15" repeatCount="1" begin="mousedown+0.2s" dur = "0.2s"
            fill="freeze"/>
            <animateTransform attributeName="transform" attributeType="XML"
            type="scale" from="1.15" to="1" repeatCount="1" begin="mouseup+0.4s" dur = "0.2s"
            fill="freeze"/>
        </g>
    </g>
</g>

Working version from my current working project looks like:

http://jsfiddle.net/7e2jeet0 (previously only used by a browser FF - because (pay attention) hover works here with 2 figures - cause [Chrome support SMIL and 'use' together, Firefox does not currently support SMIL and 'use' together] / according to Robert Longson)

in my attempt to make the equivalent CSS, it looks like

http://jsfiddle.net/7e2jeet0/1/ (in FF)

http://jsfiddle.net/7e2jeet0/2/ (in Chrome)


or the same for other element. Working version:

http://jsfiddle.net/f7o03rsr/

http://jsfiddle.net/f7o03rsr/1/

http://jsfiddle.net/f7o03rsr/2/

Thanks!


Edit 1

I found that this combination variant will work fine for hover and mousedown in Firefox, but only the hover effect works in Chrome.


I'm also interested in how could I save some of these animations:

http://jsfiddle.net/e4dxx2wg/

http://jsfiddle.net/e4dxx2wg/1/

by transfering them to CSS / Web animations?

Answer

Emanuele Sabetta picture Emanuele Sabetta · Aug 14, 2015

SMIL support was not removed from Chrome but was replaced with a Polyfill. Eric Willigers has created a SMIL polyfill implemented entirely on the Web Animations API. You can find it here: https://github.com/ericwilligers/svg-animation