graphicswithahat
graphicswithahat

Reputation: 1

Rotating an embedded svg object in html/js

I'm trying to create a one-handed clock to be used as an HTML-based desktop wallpaper.

I've embedded the SVG for the hand into the HTML, and am trying to get the hand to rotate with reference to the time, which is where I'm stuck...

This is where I'm currently at:

<!DOCTYPE html>
<html>
<body>

<svg width="100%" height="100%" viewBox="0 0 2560 1440" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
  <!-- <rect x="0" y="0" width="2560" height="1440"/> -->
      <path id="Hand" d="M1284.85,707.293C1289.96,709.248 1293.6,714.203 1293.6,720C1293.6,725.722 1290.06,730.623 1285.05,732.63L1285.05,865.05L1281.8,1215.35L1278.2,1215.35L1274.95,865.05L1274.95,732.63C1269.94,730.623 1266.4,725.722 1266.4,720C1266.4,714.203 1270.04,709.248 1275.15,707.293L1276.4,626.7L1283.6,626.7L1284.85,707.293Z" style="fill:#ffd000;"/>
</svg>

<script>
    var now = new Date();
    var hour = now.getHours();
    var minute = now.getMinutes();
    var second = now.getSeconds();

    hour = hour%24;
    hour = (hour*Math.PI/12)+(minute*Math.PI/(12*60))+(second*Math.PI/(12*60*60));

    setInterval(drawClock, 1000);

    function drawClock() {
    var vector = document.getElementById("Hand")
    vector.setAttribute("transform", "rotate("hour", 1280, 720)");
  }
  </script>


</html>
</body>

Any help or pointers would be greatly appreciated!

Upvotes: 0

Views: 104

Answers (1)

Akxe
Akxe

Reputation: 11495

You should use css transform, the key ingredient to make it work will then be transform-origin this css property allows you to say, that the element should rotate around the base of the hand rather than its middle.

function moveHand() {
  // Create time-related variables.
  const now = new Date();
  
  /** Divide current hour by hours in day, 
   * then multiply by 360 to get it to circle and 
   * offset by 180 to have 0 on top
   */
  document.querySelector("#hours").style.transform =   `rotate(${now.getHours()   / 24 * 360 - 180}deg)`;
  // Same for minutes and seconds
  document.querySelector("#minutes").style.transform = `rotate(${now.getMinutes() / 60 * 360 - 180}deg)`;
  document.querySelector("#seconds").style.transform = `rotate(${now.getSeconds() / 60 * 360 - 180}deg)`;
;

	requestAnimationFrame(moveHand)
}

// Use `requestAnimationFrame` instead of interval, it is the way to schedule render tasks
requestAnimationFrame(moveHand);
.hand {
  transform-origin: 50% 50%;
}
<svg id="clock" width="100%" height="100%" viewBox="0 0 2560 1440" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
  <!-- <rect x="0" y="0" width="2560" height="1440"/> -->
  <path class="hand" id="seconds" d="M1284.85,707.293C1289.96,709.248 1293.6,714.203 1293.6,720C1293.6,725.722 1290.06,730.623 1285.05,732.63L1285.05,865.05L1281.8,1215.35L1278.2,1215.35L1274.95,865.05L1274.95,732.63C1269.94,730.623 1266.4,725.722 1266.4,720C1266.4,714.203 1270.04,709.248 1275.15,707.293L1276.4,626.7L1283.6,626.7L1284.85,707.293Z" style="fill:#ffd000;" />
  <path class="hand" id="minutes" d="M1284.85,707.293C1289.96,709.248 1293.6,714.203 1293.6,720C1293.6,725.722 1290.06,730.623 1285.05,732.63L1285.05,865.05L1281.8,1215.35L1278.2,1215.35L1274.95,865.05L1274.95,732.63C1269.94,730.623 1266.4,725.722 1266.4,720C1266.4,714.203 1270.04,709.248 1275.15,707.293L1276.4,626.7L1283.6,626.7L1284.85,707.293Z" style="fill:#d000ff;" />
  <path class="hand" id="hours" d="M1284.85,707.293C1289.96,709.248 1293.6,714.203 1293.6,720C1293.6,725.722 1290.06,730.623 1285.05,732.63L1285.05,865.05L1281.8,1215.35L1278.2,1215.35L1274.95,865.05L1274.95,732.63C1269.94,730.623 1266.4,725.722 1266.4,720C1266.4,714.203 1270.04,709.248 1275.15,707.293L1276.4,626.7L1283.6,626.7L1284.85,707.293Z" style="fill:#d0ff00;" />
</svg>

Upvotes: 1

Related Questions