使用 JavaScript 移动 SVG 'g' 标签
moving SVG 'g' tag using JavaScript
我知道SVG <g>
标签没有X和Y属性,传输它的唯一方法是使用transform="translate(x,y)"
和transform="rotate(45 50 50)"
等transform
我正在尝试使用 JavaScript 进行相同的编程,我想移动具有 rect
和 text
组合的 g
标签,下面是我的代码,所以我犯了什么错误,所以g
在我点击它后不会移动/翻译?
var NS="http://www.w3.org/2000/svg";
var SVG=function(h,w){
var svg=document.createElementNS(NS,"svg");
svg.width=w;
svg.height=h;
return svg;
}
var svg=SVG(1200,1500);
document.body.appendChild(svg);
class myRect {
constructor(x,y,h,w,fill,name) {
this.g= document.createElementNS(NS,"g");
this.name=name;
this.SVGObj= 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;
this.text = document.createElementNS(NS, 'text');
this.text.setAttribute('x', x+10);
this.text.setAttribute('y', y+20);
this.text.setAttribute('fill', '#000');
this.text.textContent = '2';
this.g.appendChild(self);
this.g.appendChild(this.text)
this.g.addEventListener("click",this,false);
}
}
Object.defineProperty(myRect.prototype, "node", {
get: function node() {
return this.g; // this.SVGObj;
}
});
myRect.prototype.handleEvent= function(evt){
self = this.g;
switch (evt.type){
case "click":
// alert(this.name); // this.animate();
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);
self.parentNode.removeChild(self);
}
break;
default:
break;
}
}
myRect.prototype.animate = function() {
self = this.g;
self.transform="translate(200,200)";
// self.x.baseVal.value+=1;
// self.y.baseVal.value+=1;
};
var r= new myRect(50,50,30,30,'#'+Math.round(0xffffff * Math.random()).toString(16),'this is my name');
svg.appendChild(r.node);
更新我尝试了self.setAttribute('transform','translate(10,10)')
但没有奏效,我能够使用getItem(0)获取转换属性中的第一个元素的self.setAttribute('transform','translate(10,10)');
进行一次仅移动一步,例如 transform="translate(1, 1) scale(2)"
getItem(0)
获取translate(1, 1)
矩阵和getItem(1)
获取scale(2)
的位置,如此处所述
但这仍然不是我需要的,一旦我单击g
直到循环结束,我需要连续移动。
<html>
<body>
<div class="svg"></div>
</body>
<script>
var NS="http://www.w3.org/2000/svg";
var SVG=function(h,w){
var svg=document.createElementNS(NS,"svg");
svg.width=w;
svg.height=h;
return svg;
}
var svg=SVG(1200,1500);
var div =document.querySelector(".svg");
div.appendChild(svg);
class myRect {
constructor(x,y,h,w,fill,name) {
this.g= document.createElementNS(NS,"g");
this.name=name;
this.SVGObj= 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;
this.text = document.createElementNS(NS, 'text');
this.text.setAttribute('x', x+10);
this.text.setAttribute('y', y+20);
this.text.setAttribute('fill', '#000');
this.text.textContent = '2';
this.g.appendChild(self);
this.g.appendChild(this.text)
this.g.addEventListener("click",this,false);
}
}
Object.defineProperty(myRect.prototype, "node", {
get: function node() {
return this.g; // this.SVGObj;
}
});
myRect.prototype.handleEvent= function(evt){
self = this.g;
switch (evt.type){
case "click":
// alert(this.name); // this.animate();
if (typeof self.moving == 'undefined' || self.moving == false) self.moving = true;
else self.moving = false;
if(self.moving == true)
self.move = setInterval(()=>this.animate(evt),100);
else{
clearInterval(self.move);
self.parentNode.removeChild(self);
}
break;
default:
break;
}
}
myRect.prototype.animate = function(evt) {
self = this.g;
var recElement=self.childNodes[0];
recElement.setAttribute("x",10);
recElement.setAttribute("y",10);
//self.transform="translate(200,200)";
};
var r= new myRect(50,50,30,30,'#'+Math.round(0xffffff * Math.random()).toString(16),'this is my name');
svg.appendChild(r.node);
</script>
感谢 Mike Williamson,我能够通过开发自定义转换函数来解决它:
myRect.prototype.step = function(x,y) {
return svg.createSVGTransformFromMatrix(svg.createSVGMatrix().translate(x,y));
}
并通过以下方式调用:
myRect.prototype.animate = function() {
self = this.g;
self.transform.baseVal.appendItem(this.step(1,1));
};
对于任何感兴趣的人,完整的代码是:
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,name) {
this.g= SVG("g");
this.name=name;
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)";
this.text = SVG('text');
this.text.setAttribute('x', x+10);
this.text.setAttribute('y', y+20);
this.text.setAttribute('fill', '#000');
this.text.textContent = name;
this.g.appendChild(self);
// this.g.appendChild(this.text); // if required to be loaded from start up
this.g.addEventListener("click",this,false);
//(e)=>alert(e.target.parentNode.parentNode); / this is to check what is clicked
}
}
Object.defineProperty(myRect.prototype, "node", {
get: ()=> return this.g;
});
myRect.prototype.handleEvent= function(evt){
self = evt.target.parentNode; // this returns the `g` element
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);
self.appendChild(this.text); // show the text node
}
else{
clearInterval(self.move);
self.removeChild(self.childNodes[1]); // remove the text node
// self.parentNode.removeChild(self); // This removes the `g` element completly
}
break;
default:
break;
}
}
myRect.prototype.step = function(x,y) {
return svg.createSVGTransformFromMatrix(svg.createSVGMatrix().translate(x,y));
}
myRect.prototype.animate = function() {
self = this.g;
self.transform.baseVal.appendItem(this.step(1,1));
};
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),'click to stop');
svg.appendChild(r.node);
}
它也可以在JSFiddle上找到
相关文章:
- 将 OnClick 事件附加到我的标签 - JavaScript.亚德夫.
- innerHTML 在 img 标签 javascript 之后
- Instagram API - 使用自定义标签javascript阅读图片
- 我如何替换像twitter或facebook这样的keydown事件上的hash标签.javascript//jquer
- 当我们点击链接标签javascript中的跨度时,要防止链接的行为
- 自动;点击“;每X秒一个锚标签?Javascript
- 在html中附加文本<脚本></脚本>标签Javascript问题
- 使用Google JSAPI破坏了我的内场标签javascript,为什么以及如何修复它
- 如何更改 标签 javascript 的文本值
- 标签中的标签- JavaScript错误-不能设置属性className为null
- 获取Twitter引导's "标签"Javascript在Rails应用程序上工作
- 完整的HTML标签javascript
- 在 Python 程序中包装画布标签 + javascript 的最简单方法
- 将每个单词的第一个字母包装在span标签- javascript中
- 不能从选择标签JavaScript中检索选项的值
- 将输入文本字段更改为标签,并在标签javascript中添加输入类型值
- 获取特定HTML标签JavaScript的内容
- 解析标签javascript的html属性
- 如何用这一行打开一个新标签(JavaScript?)
- 在span标签javascript中包装数字