javascript - 使用 SVG 和 JS 制作类似绘画的东西
问题描述
我尝试使用 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,0);stroke-width:2;visibility:visible");
}
}
}
})
编辑:
我认为问题是“e.target.getBoundingClientRect”;因为我已经将 SVG 的宽度设置为 300。但是当线路跳跃时,我寻找“rect.width”并看到它是 20!虽然它必须是300!
这是一个小提琴:
https://jsfiddle.net/qrL2mvea/1
这是snippest的完整代码:
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,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>
Edit2: 我尝试使用 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[0])
.attr("y2", m[1]);
}
function mouseup() {
vis.on("mousemove", null);
}
function mouseleave() {
vis.on("mousemove", null);
}
这是一个小提琴:
提示:
“d3.mouse”不再适用于新版本的 D3。使用 V5.9.2 或更低版本。如果你使用它,它会给出一个错误:
d3.mouse 不是函数
我在这里读到我们可以使用“d3.pointer(event)”来代替。
您可以通过将此代码添加到您的 html 代码来添加版本 5:
<script src="https://d3js.org/d3.v5.min.js"></script>
你可以在任何你想要的地方添加它。但是记得在div 后面加上 JS 部分。否则,它会给你一个错误:
未捕获的 ReferenceError:未定义 d3
最后,在
var vis = d3.select("div").append("svg")
您应该记住将div更改为元素的名称。例如,如果它是一个span,请像这样更改它:
var vis = d3.select("span").append("svg")
谢谢,希望你可以使用它,再见。
笔记:
我没有写完整的代码,我用了这个小提琴。
推荐阅读
- angular - 角度 cli 找不到外部脚本文件
- react-native - 图像选择器自定义按钮 React-native
- python - 将递归函数或可变长度循环应用于 numpy 数组的元素
- python - 正确显示嵌入时出现问题
- javascript - 根据条件更新字段的许多 mongoDB 记录
- c++ - 内存分配导致内存泄漏
- javascript - SpeechSynthesis 和 chrome.tts 有什么区别
- asp.net - 使用 Unity 连接到 SQL Server
- python - 在任务队列中实现消息优先级
- reactjs - 调试 React Native + Redux 应用程序的选项有哪些?