问题描述
我尝试使用 SVG 和 JS 制作类似 Windows 的油漆。它运行良好,但它有一个错误。我无法描述那是怎么回事。你应该看到它。但似乎当你画一条线时,它会跳到另一个位置!有人可以帮我吗?
代码如下:
HTML:
<div id="Test" >
<svg height="300" width="300"></svg>
</div>
JavaScript:
var i=0;
var Sx;
var Sy;
var Show = false;
document.addEventListener('DOMContentLoaded',function(event) {
document.getElementById('Test').onmousedown = function clickEvent(e) {
var rect = e.target.getBoundingClientRect();
Sx = e.clientX - rect.left; //x position within the element.
Sy = e.clientY - rect.top; //y position within the element.
Show = true;
}
document.getElementById('Test').onmouseup = function clickEvent2(e) {
rect = e.target.getBoundingClientRect();
var Ex = e.clientX - rect.left; //x position within the element.
var Ey = e.clientY - rect.top; //y position within the element.
var TheLine = document.createElementNS("http://www.w3.org/2000/svg","line");
TheLine.innerHTML = "";
document.getElementsByTagName("svg")[0].appendChild(TheLine);
i++;
var LineZ = document.getElementsByTagName("line")[i];
Show = false;
}
document.getElementById('Test').onmouseleave = function clickEvent4(e) {
Show = false;
console.log(":(");
i++;
}
document.getElementById('Test').onmousemove = function clickEvent3(e) {
if (Show == true)
{
rect = e.target.getBoundingClientRect();
Ex = e.clientX - rect.left; //x position within the element.
Ey = e.clientY - rect.top;
var TheLine = document.createElementNS("http://www.w3.org/2000/svg","line");
document.getElementsByTagName("svg")[0].appendChild(TheLine);
///i++;
///console.log(Sx," ",Sy,Ex,Ey);
var LineZ = document.getElementsByTagName("line")[i];
if (LineZ != undefined && Ex != 0 && Ey != 0 && Ex != 1 && Ey != 1){
document.getElementsByTagName("line")[i].setAttributeNS(null,"x1",Sx);
document.getElementsByTagName("line")[i].setAttributeNS(null,"y1",Sy);
document.getElementsByTagName("line")[i].setAttributeNS(null,"x2",Ex);
document.getElementsByTagName("line")[i].setAttributeNS(null,"y2",Ey);
document.getElementsByTagName("line")[i].setAttribute("style","stroke:rgb(255,0);stroke-width:2;visibility:visible");
}
}
}
})
编辑:
我认为问题是“e.target.getBoundingClientRect”;因为我已经将 SVG 的宽度设置为 300。但是当这条线跳跃时,我寻找“rect.width”并看到它是 20!虽然它必须是 300!
这是一个小提琴:
https://jsfiddle.net/qrL2mvea/1
var i=0;
var Sx;
var Sy;
var Show = false;
document.addEventListener('DOMContentLoaded',0);stroke-width:2;visibility:visible");
}
}
}
})
body
{
margin: 0px;
}
#Test
{
border:2px dotted blue;
width:300px;
height:300px;
background-color:lightblue;
position: fixed;
top: 10%;
}
<div id="Test" >
<svg height="300" width="300"></svg>
</div>
编辑 2: 我尝试使用 JQuery 的:
"event.pageX - $(this).offset().left;"
和“event.pageY - $(this).offset().top;”,
但完全一样的发生:(
有趣的是,当我使用 e.clientX 和 e.clientX 代替时,效果会更好,但还是不行 :(
解决方法
嗨,我又解决了!我使用了 D3(jsfiddle 中的 5.9.2 版,以及来自其原始网站的 5 版)。
这是新代码:
HTML:
<div id="Test" >
CSS:
body
{
margin: 0px;
}
#Test
{
border:2px dotted blue;
width:300px;
height:300px;
background-color:lightblue;
position: fixed;
top: 100px;
left: 100px;
}
svg {
border: 1px solid grey;
}
line {
stroke: steelblue;
stroke-width: 2px;
stroke-linecap: round;
}
JavaScript:
var line;
var vis = d3.select("div").append("svg")
.attr("width",300)
.attr("height",300)
.on("mousedown",mousedown)
.on("mouseleave",mouseleave)
.on("mouseup",mouseup);
function mousedown() {
var m = d3.mouse(this);
line = vis.append("line")
.attr("x1",m[0])
.attr("y1",m[1])
.attr("x2",m[0])
.attr("y2",m[1]);
vis.on("mousemove",mousemove);
}
function mousemove() {
var m = d3.mouse(this);
line.attr("x2",m[1]);
}
function mouseup() {
vis.on("mousemove",null);
}
function mouseleave() {
vis.on("mousemove",null);
}
这是一个小提琴:
提示:
"d3.mouse" 不再适用于新版本的 D3。使用 V5.9.2 或更低版本。如果你使用它,它会报错:
d3.mouse 不是函数
我读到 Here 我们可以使用 "d3.pointer(event)" 代替。
您可以通过将此代码添加到您的 html 代码中来添加第 5 版:
<script src="https://d3js.org/d3.v5.min.js"></script>
您可以随心所欲地添加它。但是记得在 div 之后添加 JS 部分 。否则,它会给你一个错误:
未捕获的引用错误:d3 未定义
最后,在
var vis = d3.select("div").append("svg")
您应该记住将 div 更改为元素的名称。例如,如果它是一个 span,请像这样更改它:
var vis = d3.select("span").append("svg")
谢谢,希望你能使用它,再见。
注意:
我没有编写完整的代码,我使用了 this fiddle。