Home > Enterprise >  animateTransform a group/object on hover (and return to initial state afterwards)
animateTransform a group/object on hover (and return to initial state afterwards)

Time:02-06

Is it possible to perform an animateTransform on a hover inside SVG?

I want the element to transform while the mouse is over it, and then return to its original position when the mouse has left.

I figure this is probably isn't possible. I have a mouseover to start the element, a mouseout to stop it, and set fill to remove to set its state back to the start.

But if the transform moves the object out from user the mouse cursor, the animation resets and starts moving again then moves out and resets and starts moving again ... flickering.

Here my simple example

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100">
    <g transform="translate(0 0)">
        <rect x="10" y="10" width="20" height="40" fill="black" />
        <animateTransform attributeName="transform" begin="mouseover" end="mouseout" dur="2s" type="translate" from="0 0" to="50 50" repeatCount="1" fill="remove" />
    </g>
</svg>

Note: The svg is not being used on a HTML page - most solutions I have seen use "css" and "javascript", neither of which are available. I need to use SVG/SMIL only. If I were targetting html, I'd use css :hover.

CodePudding user response:

You can use fill freeze on combination with restart whenNotActive. And then have an animation for both mouseover and mouseout.

I also removed the from attribute. The animation needs to start from the "freezed" point.

<svg xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100">
  <g transform="translate(0 0)">
    <rect x="10" y="10" width="20" height="40" fill="black" />
    <animateTransform attributeName="transform" begin="mouseover"
      dur="2s" type="translate" to="50 50" repeatCount="none"
      fill="freeze" restart="whenNotActive" />
    <animateTransform attributeName="transform" begin="mouseout"
      dur="2s" type="translate" to="0 0" repeatCount="none"
      fill="freeze" restart="whenNotActive" />
  </g>
</svg>

CodePudding user response:

One variant is to link the animation to an invisible, unmoving element on top of the moving one. For that, the begin and end event values are prefixed with the id of that cover element. Like this:

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100">
    <g transform="translate(0 0)">
        <rect x="10" y="10" width="20" height="40" fill="black" />
        <animateTransform attributeName="transform"
                begin="cover.mouseover" end="cover.mouseout" dur="2s"
                type="translate" from="0 0" to="50 50" repeatCount="1" fill="remove" />
    </g>
    <rect id="cover" x="10" y="10" width="20" height="40" opacity="0" />
</svg>

  • Related