Это не дубликат другого вопроса. Я нашел this, говоря о вращении вокруг центра с помощью XML, попытался реализовать то же самое с использованием ванильного JavaScript вроде rotate(45, 60, 60)
, но не работал со мной.Вращающийся SVG прямоугольник вокруг его центра с использованием ванили JavaScript
Подход, который работал со мной, является тем, что находится в фрагменте ниже, но обнаружил, что прямоугольник не вращается точно вокруг его центра, и он немного движется, прямоугольник должен начинать вращаться при первом щелчке и должен остановиться на второй щелчок, который идет хорошо со мной.
Любая идея, почему элемент движется, и как его исправить.
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);
}
ОБНОВЛЕНИЕ
Я нашел вопрос, который должен расчета центральную точку rect
с помощью self.getBoundingClientRect()
всегда 4px extra in each side
, что означает 8px дополнительный в ширину и 8px дополнительно в высоте, а также как x, так и y сдвинуты на 4 пикселя, я нашел this, говоря о том же, но ни один параметр self.setAttribute("display", "block");
или self.style.display = "block";
wo со мной.
Итак, теперь я один из 2-х вариантов, либо:
- Найти решение дополнительного 4px с каждой стороны (т.е. 4px смещение обоих х и у, а общая 8px дополнительная как по ширине и высота),
или вычисления средней точки с помощью:
self.Pc = { x: self.x.baseVal.value + self.width.baseVal.value/2, y: self.y.baseVal.value + self.height.baseVal.value/2 };
Второй вариант (другой способ вычисления средней точки работал отлично со мной, поскольку он является прямым, но если используется другая форма, это не то же самое, я буду искать универсальный способ найти середину, независимо от того, какой объект , то есть ищет первый вариант, который решает проблему self.getBoundingClientRect()
.
, который является часто отвечал, что ... Уловка: Перевести объект так, что центр вращения/Scale находится в начале координат, вращать, переводить обратно. Все эти три шага могут быть объединены в одну матрицу преобразования. – philipp
Возможный дубликат [Поворот прямоугольника вокруг собственного центра в SVG] (http://stackoverflow.com/questions/15138801/rotate-rectangle-around-its-own-center-in-svg) – philipp
Кстати ... При написании es6, вам не нужно использовать этот 'Object.defineProperty (myRect.prototype ...', так как вы можете напрямую создавать методы-члены класса, что переводится в эту вещь прототипа ... – philipp