Creating a seamless rotation effect on an SVG shape at its center across all browsers, even Internet Explorer

Is there a way to make an SVG figure rotate around its center? I have been trying to calculate the rotation center and scale it based on the viewBox. It seems to work perfectly fine in Chrome, Firefox, and Safari, but I just can't seem to get it to work in Internet Explorer. I've played around with the preserveAspectRatio attribute, double-checked my values, but nothing seems to fix it ... Any suggestions?

<!doctype HTML>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">  
</head>
<body>
<svg version="1.1" id="sketch" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
 viewBox="0 0 1332 1080" style="enable-background:new 0 0 1332 1080;" preserveAspectRatio="xMinYMin slice">
<g id="wheel1">
<g>
<path class="st8" d="M258.4,149c-123.7,0-224,100.3-224,224s100.3,224,224,224s224-100.3,224-224S382.1,149,258.4,149z M258.9,533
c-88.4,0-160-71.6-160-160s71.6-160,160-160s160,71.6,160,160S347.2,533,258.9,533z"/>
<g>
<polyline class="st9" points="258.5,149 282,181 258.5,213 "/>
</g>
</g>
</svg>

<script type="text/javascript">
var svg = document.getElementById('sketch')
  var wheel = document.getElementById('wheel1')

  var svgBBox = svg.getBoundingClientRect()
  var wheelBBox = wheel.getBoundingClientRect()

  // Calculate rotation center of the wheel
  var cx = (wheelBBox.left - svgBBox.left) + wheelBBox.width / 2
  var cy = (wheelBBox.top - svgBBox.top) + wheelBBox.height / 2

  // Calculate scaling ratio based on viewBox / viewport
  var viewBox = svg.getAttribute('viewBox').split(' ').map(function(v) { return parseInt(v, 10) })
  var ratioX = viewBox[2] / svgBBox.width
  var ratioY = viewBox[3] / svgBBox.height

var t0 = Date.now()

// Rotation loop
  setInterval(function() {
var delta = (Date.now() - t0)
wheel.setAttribute('transform', 'rotate(' + delta * 0.05 + ', ' + (cx * ratioX) + ', ' + (cy * ratioY) + ')')
  }, 10)
</script>

<style type="text/css">
.st9 { fill: yellow; }
</style>

</body>
</html>

Answer №1

Opt for utilizing getBBox() over getBoundingClientRect(). The coordinates provided by getBBox() are already relative to the viewBox, making it easier to use these values independently of any viewBox.

Uncertain if this will resolve issues in IE...

var svg = document.getElementById('sketch')
var wheel = document.getElementById('wheel1')
var wheelBBox = wheel.getBBox()

  // determine the center of rotation for the wheel
  var cx = wheelBBox.x + wheelBBox.width / 2
  var cy = wheelBBox.y + + wheelBBox.height / 2

var t0 = Date.now()

// Rotation loop
setInterval(function() {
var delta = (Date.now() - t0)
wheel.setAttribute('transform', 'rotate(' + delta * 0.05 + ', ' + cx + ', ' + cy + ')')
  }, 10)
.st9 { fill: yellow; }
<svg version="1.1" id="sketch" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
 viewBox="0 0 1332 1080" style="enable-background:new 0 0 1332 1080;" preserveAspectRatio="xMinYMin slice">
<g id="wheel1">
<g>
<path class="st8" d="M258.4,149c-123.7,0-224,100.3-224,224s100.3,224,224,224s224-100.3,224-224S382.1,149,258.4,149z M258.9,533
c-88.4,0-160-71.6-160-160s71.6-160,160-160s160,71.6,160,160S347.2,533,258.9,533z"/>
<g>
<polyline class="st9" points="258.5,149 282,181 258.5,213 "/>
</g>
</g>
</svg>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Please refresh the page in order to utilize the newly updated cookies

I have a specific process that involves: A button triggers the function fcn1 and redirects to a page called p1 Function fcn1 retrieves 6 strings from a backend SQL database The 6 strings are then stored in cookies Page p1 reads the 6 cookies and displays ...

Using Vue.js, learn how to target a specific clicked component and update its state accordingly

One of the challenges I'm facing is with a dropdown component that is used multiple times on a single page. Each dropdown contains various options, allowing users to select more than one option at a time. The issue arises when the page refreshes afte ...

Associate the callback function with a directive that does not have an isolated scope

Ensuring the correct context when binding a callback function to a directive is crucial. When working with an isolated scope, this task is easily accomplished. <bar-foo callback="mycontroller.callback()"></bar-foo> The directive code: ... ...

Issue with React component not displaying in the browser.Here are some

I am currently following a React tutorial on and I'm facing an issue where the Counter component is not displaying on the page. The generated HTML looks like this: <html> <head> <script src="/bundle.js" ></script> </he ...

Guide to creating varying component sizes using ReactJS and Styled Components

Is it possible to add variation to my button based on the prop 'size' being set to either 'small' or 'medium'? interface Props { size?: 'medium' | 'small'; } How can I adjust the size of the component us ...

Enhancing Application Performance Through Next.js Development

I'm currently working on an application using next.js and I am looking to implement code splitting in order to reduce the bundle size and load pages on demand. Unfortunately, I have not been able to find a way to do this without specifying routes. Fo ...

Utilizing Vue.js for Tabs in Laravel 5.8

I am encountering an issue in Laravel while attempting to set up a Vue instance for tabs. Currently, only Tab 1 and Tab 2 are displayed without any content, and the tabs themselves are not clickable links. Could this problem be related to how I am calling ...

When attempting to run JavaScript within PHP, an Uncaught SyntaxError is encountered

When I run this code without PHP, it works perfectly. <?php $activeStatus = "$getuser[active]"; if($activeStatus == 1) { echo '<script type="text/javascript">'; echo ' $(document).ready(function () { v ...

By clicking the button, you can add an item to select2

Utilizing the select2 tag style in my Drupal YAML form allows users to easily locate and add various items. These items come with both images and titles on the same page, accompanied by a button next to each image. My goal is to enable users to click the b ...

Manipulating images separately using the canvas

Currently, I am utilizing an HTML5 canvas to generate a collection of trees alongside their corresponding shadows. My objective is to ensure that each shadow corresponds with the position of a designated light source. While I have successfully drawn each t ...

d3.js attempting to animate data, but each time the data is altered it is always perceived as new

I have a JSON dataset that consists of an array of frames, with each frame containing an array of 10 nodes. Each node is represented as a dictionary with the node id and x,y coordinates. My objective is to devise a d3 animation that smoothly transitions be ...

Leveraging JavaScript for setting an ASP.net Dropdownlist

I have made several attempts to set the dropdownlist without success. Despite observing the selectedIndex changing appropriately in developer tools, and noticing the selected option node change from false to true, the dropdownlist still displays the first ...

What causes the exception in JavaScript to be an empty object?

try { let temporary = null; temporary.split(','); } catch (error) { Logger().info('caught error: ', error, error.constructor); } output: caught error: {} undefined I attempted to use JSON.stringify and encountered the sa ...

Tips for utilizing Material UI's Tooltip feature alongside a TableRow

I'm currently facing an issue where I'm trying to include a MUI TableRow inside a Tooltip component in order to display a long uuid when hovering over the row. However, I noticed that all the columns of the row are being compressed into the first ...

Changing font color of a selected item in Material-UI's textview

I have a select textview in my react app and I am wondering how to change the font color after selecting an item from this textview. <div> <TextField id="standard-select-currency" select fullWidth l ...

Enabling a checkbox grid for exclusive rectangular selections

Apologies for the confusing title, I struggled to come up with something more fitting. Let's say my client needs a square area on their homepage where they can upload images that will be placed within various boxes in a grid. The available box optio ...

What is the maximum number of requests that Node-Express can send simultaneously?

Currently, I am facing a challenge with my script that involves fetching 25,000 records from AWS Athena, a PrestoDB Relational SQL Database. For each of these records, I need to make a request to Athena and then another request to my Redis Cluster once the ...

How to use Javascript to pause an HTML5 video when closed

I am new to coding and currently working on a project in Adobe Edge Animate. I have managed to create a return button that allows users to close out of a video and go back to the main menu. However, I am facing an issue where the video audio continues to p ...

Is it possible to execute functions inline with conditional logic in react?

Is there a way to shorten the long conditions inside an inline if-else statement in React by putting a function inside it? I attempted to do this but encountered an error stating that "discount is not defined." function getDiscount(props) { const d ...

Error: The function expressJwt is not recognized as a valid middleware

As I delve into learning about middlewares, I encountered an issue when trying to import express-jwt. The syntax I used was: const expressJwt = require('express-jwt') To address the problem, I uninstalled the current version of express-jwt and i ...