Kasper Gyselinck
Kasper Gyselinck

Reputation: 175

svg transform rotation precision

I'm trying to create a simple test with an svg, allowing me to change a quality setting (FPS), and a speed of rotation on an svg.

I noticed that the transform, rotate functionality works with degrees. To my knowledge it is not possible to increase precision by using decimals as degrees.

So are we stuck using the rotation degrees, which gives us a maximum of 360 pieces to divide a circle into, or is there a way to increase the precision somehow ?

The reason I ask is because I created a pen https://codepen.io/KaGys/pen/yKVjrr?editors=1111 in which I added several quality settings. A higher quality setting results in a higher number of frames per second. This means that if 1 degree is the smallest unit I can rotate at, I would need to start delaying the animation to go slower than 1 degree per frame, which at my highest quality setting (fastest frames per second) is still a pretty fast rotation. I hope the question is clear, if not, please let me know and I'll try to clarify.

    var ultra = 1000 / 120;
    var high = 1000 / 60;
    var medium = 1000 / 30;
    var low = 1000 / 10;

    var quality = ultra;

    var speed = 1; // degrees per frame on ultra quality (converts to lower quality settings to maintain consistency)
    // I tried doing this on per second basis, which works but the problem is that degrees can not be decimals which causes inconsistent behavior
    speed = (speed * quality) / ultra; // Recalculate the speed for consistency across quality settings

  var rotateSettings = {
    path: document.getElementById("pathGroup"),
    active: false,
    speed: speed,
    quality: quality
  };

  function rotate() {
    if (this.active) {
      setTimeout(rotate.bind(this), this.quality);
      var currentRotation = Number(
        /\d+/.exec(this.path.getAttributeNS(null, "transform"))
      );
  currentRotation = currentRotation%360;
      console.log(this.speed);
      this.path.setAttributeNS(
        null,
        "transform",
        `rotate(${currentRotation + this.speed}, 60, 60)`
      );
    }
  }

  document.getElementById("btnRotate").addEventListener("click", e => {
    if (!rotateSettings.active) {
      rotateSettings.active = true;
      document.getElementById("btnRotate").style.background = "green";
      document.getElementById("btnRotate").style.color = "white";
      rotate.bind(rotateSettings)();
    } else {
      rotateSettings.active = false;
      document.getElementById("btnRotate").style.background = "white";
      document.getElementById("btnRotate").style.color = "green";
    }
  });

Upvotes: 1

Views: 334

Answers (1)

Robert Longson
Robert Longson

Reputation: 124299

You can read the transform angle via the SVG DOM

var currentRotation = this.path.transform.animVal[0].angle;

Upvotes: 2

Related Questions