javascript - 无法将屏幕 x,y 坐标转换为 svg 坐标
问题描述
我正在尝试将从 click 事件中获取的位置转换为应该附加到我想要附加到我的<svg>
. 每次单击时,我都想在单击的位置添加一个元素,例如圆形。我已经读过point.matrixTransform(svgRoot.getScreenCTM().inverse());
应该做的伎俩并将屏幕坐标转换为SVG坐标,但在我的情况下它似乎不起作用(坐标根本不翻译)。仅当我将viewBox
属性添加到我的<svg>
. 我不知道我在这里做错了什么。也许这不适用于我的情况,我需要手动进行转换?
例子:
const drawingArea = document.querySelector('#drawing-area');
drawingArea.addEventListener('click', (e) => {
const { left, top } = drawingArea.getBoundingClientRect();
drawCircle({
x: e.clientX - left,
y: e.clientY - top});
});
const drawCircle = ({ x, y }, r = 10) => {
const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
circle.setAttribute('cx', x.toString());
circle.setAttribute('cy', y.toString());
circle.setAttribute('r', r.toString());
drawingArea.appendChild(circle);
}
const translateToSVGCoordinates = (x, y) => {
const point = drawingArea.createSVGPoint();
point.x = x;
point.y = y;
point.matrixTransform(drawingArea.getScreenCTM().inverse());
return { x: point.x, y: point.y };
}
body, html {
width: 100%;
height: 100%;
margin: 0;
}
<svg id="drawing-area" width="100%" height="100%" viewBox="0 0 1920 1080" preserveAspectRatio="xMinYMin meet"></svg>
如果我不够清楚我期待什么结果,只需从元素中删除
viewBox
属性<svg>
解决方案
您使用 SVG 代码和 Web 组件代码使其过于复杂......
尝试这个:
<svg-draw-board></svg-draw-board>
<style>
svg-draw-board {
width : 100vw;
height : 180px;
display : inline-block;
background : pink;
cursor : pointer;
}
</style>
<script>
customElements.define('svg-draw-board', class extends HTMLElement {
constructor() {
super()
.attachShadow({mode:'open'})
.innerHTML = `<svg width="100%" height="100%" viewBox="0 0 800 800"></svg>`;
this.svg = this.shadowRoot.querySelector('svg');
this.svg.onclick = (evt) => { // convert clientXY to SVG XY
let CTM = this.svg.getScreenCTM();
let x = (evt.clientX - CTM.e) / CTM.a;
let y = (evt.clientY - CTM.f) / CTM.d;
this.drawCircle( x, y , evt.ctrlKey ? 50 : 30 );
};
}
drawCircle(cx, cy, r, fill = 'red') {
this.svg.append( this.createSVGElement('circle', { cx, cy, r, fill }) );
}
createSVGElement( tag, attrs={} ) {
const el = document.createElementNS('http://www.w3.org/2000/svg',tag);
Object.entries(attrs).map(([name, val]) => el.setAttribute(name, val));
return el;
}
});
</script>
推荐阅读
- r - 如何将pdf上传到R中的FTP服务器?
- c# - 在 Exchange 上使用 EAGetMail 查找和创建文件夹
- terraform - Terraform v0.12.1 错误属性“cidr_blocks”的值不合适:元素 0:需要字符串
- python - 如何使用 Python 脚本检测 SQL 注入漏洞
- compiler-optimization - 如何使用 rpmbuild 创建未优化的构建?
- vb.net - VB.NET 解决方案属性缺少“XML 文档文件”路径选项
- openxml - 使用 OpenXML SDK 将 WordML 2003 格式转换为 OpenXML 格式
- python - Python selenium 自动化 Linkedin 帖子
- r - 在 rma.mv 中指定“random=”参数用于具有多个效应大小和嵌套研究的多级荟萃分析
- python - 使用 pandas 数据框数据填充 dict 和 json