这不是另一个问题的重复.我发现这个问题是关于使用XML的中心轮换,尝试使用类似于vanilla的JavaScript实现相同rotate(45, 60, 60)但不适用于我.
与我合作的方法是下面的片段中的一个,但发现矩形不是围绕其中心旋转,并且它移动了一点点,矩形应该在第一次点击时开始旋转,并且应该在第二次点击时停止,我很好.
任何想法,为什么项目在移动,以及如何解决它.
var NS="http://www.w3.org/2000/svg";
var SVG=function(el){
return document.createElementNS(NS,el);
}
var svg = SVG("svg");
svg.width='100%';
svg.height='100%';
document.body.appendChild(svg);
class myRect {
constructor(x,y,h,w,fill) {
this.SVGObj= SVG('rect'); // document.createElementNS(NS,"rect");
self = this.SVGObj;
self.x.baseVal.value=x;
self.y.baseVal.value=y;
self.width.baseVal.value=w;
self.height.baseVal.value=h;
self.style.fill=fill;
self.onclick="click(evt)";
self.addEventListener("click",this,false);
}
}
Object.defineProperty(myRect.prototype, "node", {
get: function(){ return this.SVGObj;}
});
Object.defineProperty(myRect.prototype, "CenterPoint", {
get: function(){
var self = this.SVGObj;
self.bbox = self.getBoundingClientRect(); // returned only after the item is drawn
self.Pc = {
x: self.bbox.left + self.bbox.width/2,
y: self.bbox.top + self.bbox.height/2
};
return self.Pc;
}
});
myRect.prototype.handleEvent= function(evt){
self = evt.target; // this returns the `rect` element
this.cntr = this.CenterPoint; // backup the origional center point Pc
this.r =5;
switch (evt.type){
case "click":
if (typeof self.moving == 'undefined' || self.moving == false) self.moving = true;
else self.moving = false;
if(self.moving == true){
self.move = setInterval(()=>this.animate(),100);
}
else{
clearInterval(self.move);
}
break;
default:
break;
}
}
myRect.prototype.step = function(x,y) {
return svg.createSVGTransformFromMatrix(svg.createSVGMatrix().translate(x,y));
}
myRect.prototype.rotate = function(r) {
return svg.createSVGTransformFromMatrix(svg.createSVGMatrix().rotate(r));
}
myRect.prototype.animate = function() {
self = this.SVGObj;
self.transform.baseVal.appendItem(this.step(this.cntr.x,this.cntr.y));
self.transform.baseVal.appendItem(this.rotate(this.r));
self.transform.baseVal.appendItem(this.step(-this.cntr.x,-this.cntr.y));
};
for (var i = 0; i < 10; i++) {
var x = Math.random() * 100,
y = Math.random() * 300;
var r= new myRect(x,y,10,10,'#'+Math.round(0xffffff * Math.random()).toString(16));
svg.appendChild(r.node);
}Run Code Online (Sandbox Code Playgroud)
UPDATE
我发现这个问题将被计算的中心点的rect使用self.getBoundingClientRect()总是存在4px extra in each side的,这意味着8像素额外的宽度和8像素额外的高度,以及x和y由4像素移位,我发现这个谈论相同,但既不设置self.setAttribute("display", "block");或self.style.display = "block";与我合作.
所以,现在我有两种选择之一:
或使用以下方法计算中点:
self.Pc = {
x: self.x.baseVal.value + self.width.baseVal.value/2,
y: self.y.baseVal.value + self.height.baseVal.value/2
};
第二个选项(计算中点的另一种方式与我一起工作正常,因为它是矩形但如果使用其他形状,它是不一样的,我会寻找通用的方法来找到中点无论如何对象是,即寻找解决self.getBoundingClientRect()问题的第一个选项.
谢谢@Philipp,
可以通过以下任一方式来解决捕获 SVG 中心的问题:
使用.getBoundingClientRect()和调整尺寸时考虑到 4px 每边都是额外的,因此结果数字调整为:
BoxC = self.getBoundingClientRect();
Pc = {
x: (BoxC.left - 4) + (BoxC.width - 8)/2,
y: (BoxC.top - 4) + (BoxC.height - 8)/2
};
Run Code Online (Sandbox Code Playgroud)
或通过:
捕获.(x/y).baseVal.value为:
Pc = {
x: self.x.baseVal.value + self.width.baseVal.value/2,
y: self.y.baseVal.value + self.height.baseVal.value/2
};
Run Code Online (Sandbox Code Playgroud)下面是完整的运行代码:
BoxC = self.getBoundingClientRect();
Pc = {
x: (BoxC.left - 4) + (BoxC.width - 8)/2,
y: (BoxC.top - 4) + (BoxC.height - 8)/2
};
Run Code Online (Sandbox Code Playgroud)