skip to Main Content

I want to create an transition from the current state to a new state for an arbitrary attribute. I have this code:

const animate: SVGAnimateElement; 

function transition(attribute: keyof SVGGElement, to: string) {
    const initialState = animate.parentElement[attribute].animVal;
    animate.setAttribute('from', initialState);
    animate.setAttribute('to', to);
    animate.beginElement();
}

This works fine for string or numeric attributes, but sometimes the attribute will be an SVGRect or an SVGTransformList or any other non-string type. setAttribute only accepts strings.

Is there a good way to either:

  • Convert an arbitrary attribute value from animState to a string suitable for use in setAttribute.
  • Directly set the value in animate to a more complex object like SVGRect or SVGTransformList
  • Start the animation from the current state in some other way.

I can’t use CSS transititions since it doesn’t support some attributes (like viewBox)

2

Answers


  1. You need the value property on the animVal object to get the current value. An then you also need to change the attributeName attribute.

    const animate = document.querySelector('animate');
    
    transition('cy', 80);
    
    function transition(attribute, to) {
      const initialState = animate.parentElement[attribute].animVal.value;
      animate.setAttribute('attributeName', attribute);
      animate.setAttribute('from', initialState);
      animate.setAttribute('to', to);
      animate.beginElement();
    }
    <svg viewBox="0 0 100 100" height="100">
      <circle cx="20" cy="10" r="15" fill="blue" stroke="black" stroke-width="1">
        <animate
          attributeName="cx"
          from="0"
          to="100"
          dur="1s"
          repeatCount="1" fill="freeze" />
      </circle>
    </svg>
    Login or Signup to reply.
  2. Is there a good way to either:

    • Convert an arbitrary attribute value from animState to a string suitable for use in setAttribute.

    You will have to write case distinctions yourself, and even a serialization method at least in some cases like SVGRect. SVGTransformList can be serialized via SVGTransformList.consolidate().matrix.toString().

    • Directly set the value in animate to a more complex object like SVGRect or SVGTransformList

    No. The spec states:

    Unlike other SVG DOM interfaces, the SVG DOM does not specify convenience DOM properties corresponding to the various language attributes on SVG’s animation elements…The current method for accessing and modifying the attributes on the animation elements is to use the standard getAttribute, setAttribute,…

    • Start the animation from the current state in some other way.

    Manipulating the animation timeline would be the domain of WAAPI, as it was initially intended. But in fact it is only implemented for CSS animations and transitions. Nobody works on implementing it for SMIL, or even on writing an appropriate spec.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search