【问题标题】:Can not translate screen x,y coordinates to svg coordinates无法将屏幕 x,y 坐标转换为 svg 坐标
【发布时间】:2021-07-09 12:41:36
【问题描述】:

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

如果我不够清楚我期待什么结果,只需从 <svg> 元素中删除 viewBox 属性

【问题讨论】:

    标签: javascript html svg


    【解决方案1】:

    您使用 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>

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-28
    • 2012-01-17
    • 1970-01-01
    • 1970-01-01
    • 2017-05-23
    • 2011-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多