Hasan A Yousef
Hasan A Yousef

Reputation: 24948

JavaScript rotate a SVG object around specific point `transform: rotate()`

I've the below code that is functioning properly, create the path, and rotate it upon the click.

I want to rotate the path about specific point, when i use the rotate(45 50 50) below instead of the rotate(x) i get this error: VM267:85 Uncaught SyntaxError: missing ) after argument list what shall I do?

Note NOt interested to use any ready library to handle the task, need to so it using the standard API only. thanks

var NS="http://www.w3.org/2000/svg";  
var SVG=function(el){
    return document.createElementNS(NS,el);
}
 
 svg = SVG('svg');
  svg.setAttribute("width", "100%");
  svg.setAttribute("height", "100%");
 //   svg.width='50em';  // Not working
document.body.appendChild(svg);
var bbox = svg.getBoundingClientRect();
     var center = {
          x: bbox.left + bbox.width/2,
          y: bbox.top  + bbox.height/2
     };

class myPath {
     constructor(cx,cy) {
     this.path=SVG('path');
   //  https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d
   //  https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths
     var d="M" + cx + " " + cy; 

     d = d + "L175 120 L125 120 Z";
     this.path.setAttribute("d", d);
     this.path.setAttribute("fill", "#F7931E");
     this.path.addEventListener("click",this,false);
   }
   get draw(){
       return this.path;
   }
 }
 
 myPath.prototype.rotate = function(x) {
 /*
   var path = this.path.getBoundingClientRect();
     var Pc = {
          x: bbox.left + bbox.width/2,
          y: bbox.top  + bbox.height/2
     };  */
   return svg.createSVGTransformFromMatrix(svg.createSVGMatrix().rotate(x));
   // https://developer.mozilla.org/en/docs/Web/SVG/Attribute/transform
}

myPath.prototype.animate = function() {
       self = this.path;
       self.transform.baseVal.appendItem(this.rotate(5));
};

 myPath.prototype.handleEvent= function(evt){
  self = evt.target;  
  console.log(self.getAttribute('d'));
     
 self.move = setInterval(()=>this.animate(),100);
       
}

svg.appendChild(new myPath(center.x,center.y).draw);

Upvotes: 0

Views: 5204

Answers (2)

Paul LeBeau
Paul LeBeau

Reputation: 101820

rotate(45 50 50) is the format for the transform XML attribute. For example:

<path d="..." transform="rotate(45 50 50)" .../>

But you are using the Javascript rotate() function on the SVGTransform object. JS functions require commas between parameters. Try:

rotate(45, 50, 50)

https://developer.mozilla.org/en/docs/Web/API/SVGTransform

Upvotes: 2

Hasan A Yousef
Hasan A Yousef

Reputation: 24948

I was able to solve it using translate(<x>, <y>) rotate(<a>) translate(-<x>, -<y>) as per this link

var NS="http://www.w3.org/2000/svg";  
var SVG=function(el){
    return document.createElementNS(NS,el);
}
 
 svg = SVG('svg');
  svg.setAttribute("width", "100%");
  svg.setAttribute("height", "100%");
  svg.setAttribute("fill", "green");
document.body.appendChild(svg);
bbox = svg.getBoundingClientRect();
center = {
          x: this.bbox.left + this.bbox.width/2,
          y: this.bbox.top  + this.bbox.height/2
     };

class myPath {
     constructor(cx,cy) {
     this.path=SVG('path');
   //  https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d
   //  https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths
     var d="M" + cx + " " + cy; 

     d = d + "h75 v75 h-75 z";
     this.path.setAttribute("d", d);
     this.path.setAttribute("fill", "#F7931E");
     this.path.addEventListener("click",this,false);

     this.Pbox = svg.getBoundingClientRect();
     this.Pc = {
          x: this.Pbox.left + this.Pbox.width/2,
          y: this.Pbox.top  + this.Pbox.height/2
     };
   }
   get draw(){
       return this.path;
   }
 }
 
 myPath.prototype.rotate = function(x) {
   return svg.createSVGTransformFromMatrix(svg.createSVGMatrix().rotate(x));
   // https://developer.mozilla.org/en/docs/Web/SVG/Attribute/transform
}

 myPath.prototype.move = function(x,y) {
   return svg.createSVGTransformFromMatrix(svg.createSVGMatrix().translate(x,y));
   // https://developer.mozilla.org/en/docs/Web/SVG/Attribute/transform
}

myPath.prototype.animate = function() {
       self = this.path;
            self.transform.baseVal.appendItem(this.move(this.Pc.x,this.Pc.y));
            self.transform.baseVal.appendItem(this.rotate(5));
            self.transform.baseVal.appendItem(this.move(-this.Pc.x,-this.Pc.y));
};

 myPath.prototype.handleEvent= function(evt){
  self = evt.target;  
  console.log(self.getAttribute('d'));
     
 self.move = setInterval(()=>this.animate(),100);
       
}

svg.appendChild(new myPath(center.x,center.y).draw);

Upvotes: 0

Related Questions