无法将屏幕x、y坐标转换为svg坐标

ryoqjall  于 2021-09-23  发布在  Java
关注(0)|答案(1)|浏览(351)

我正在尝试将单击事件中的位置转换为应该附加到要附加到我的 <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> 要素

xj3cbfub

xj3cbfub1#

无论是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>

相关问题