【问题标题】:Javascript - Need to get x and y coordinates only from the stroke of a SVG path?Javascript - 只需要从 SVG 路径的笔划中获取 x 和 y 坐标吗?
【发布时间】:2019-08-01 02:18:57
【问题描述】:

我有一个画布,在其中绘制了一个元素 svg(例如一个圆圈),用户负责用鼠标通过这个图进行绘制,我将用户绘制的点 x 和 y 保存在一个数组中,但是我不知道如何仅从 svg stroke 获取点。

我的问题是: 使用 isPointInStroke() 我可以查看该点是否在笔画中,但如果我没有笔画的总点数数组,则无法知道用户是否已绘制 100% 的 SVG 图。在之前的方式中,如果用户画了一半但正确,它会给我100%的成功。

function init() {
    canvas = document.getElementById('can');
    ctx = canvas.getContext("2d");
    w = canvas.width;
    h = canvas.height;

    var svgPathCirculo=" M125,200a75,75 0 1,0 150,0a75,75 0 1,0 -150,0";
    var circulo = new Path2D(svgPathCirculo);
    ctx.lineWidth = 5;
    ctx.setLineDash([5, 15]);
    ctx.stroke(circulo);

    // Just example to check if it works
    if(ctx.isPointInStroke(circulo, 125, 200)){
      ctx.arc(200,200,3,0,2*Math.PI);
      ctx.fill();
    };

    canvas.addEventListener("mousemove", function (e) {
        findxy('move', e)
    }, false);
    canvas.addEventListener("mousedown", function (e) {
        findxy('down', e)
    }, false);
    canvas.addEventListener("mouseup", function (e) {
        findxy('up', e)
    }, false);
    canvas.addEventListener("mouseout", function (e) {
        findxy('out', e)
    }, false);
}

我使用画布在其上绘图,并使用 svg 显示预定义的形状,供用户在绘图时作为模板遵循(例如为幼儿绘制小册子)。

 function draw() {
    ctx.beginPath();
    ctx.moveTo(prevX, prevY);
    ctx.lineTo(currX, currY);
    ctx.strokeStyle = x;
    ctx.lineWidth = y;
    ctx.stroke();
    ctx.closePath();
}
function findxy(res, e) {
    if (res == 'down') {
        prevX = currX;
        prevY = currY;
        currX = e.clientX - canvas.offsetLeft;
        currY = e.clientY - canvas.offsetTop;

        if(!arrayCoordenadas.includes({x:currX,y:currY})){
          arrayCoordenadas.push({x:currX,y:currY});
        }


        flag = true;
        dot_flag = true;
        if (dot_flag) {
            ctx.beginPath();
            ctx.fillStyle = x;
            ctx.fillRect(currX, currY, 2, 2);
            ctx.closePath();
            dot_flag = false;
        }
    }
    if (res == 'up' || res == "out") {
        flag = false;
    }
    if (res == 'move') {
        if (flag) {
            prevX = currX;
            prevY = currY;
            currX = e.clientX - canvas.offsetLeft;
            currY = e.clientY - canvas.offsetTop;
            if(!arrayCoordenadas.includes({x:currX,y:currY})){
              arrayCoordenadas.push({x:currX,y:currY});
            }
            draw();
        }
    }
}

我需要知道 svg 笔画路径的 x 和 y 坐标。

示例:Example of what I mean

【问题讨论】:

  • 我很困惑:你标记你的问题 SVG 然后你谈论画布和isPointInPath() - 画布上下文的方法。你能添加一些代码。一个可行的例子会很棒。
  • 现在问题已经形成,非常感谢您

标签: javascript html svg coordinates mouse


【解决方案1】:

我添加了一个函数来检测画布中的鼠标位置,现在 currX 变成了 curr.x ...等

如果您使用Path2D这是您检测点 {x,y} 是否在笔划中的方法:

ctx.isPointInStroke(the_path, x, y)

接下来是我的代码。用户只能在笔划内绘制。

现在代码正在运行,但我认为您可能不知道用户是否已绘制 100% 的 SVG 图。您可以将点推入点数组中并计算路径的长度,并将其与圆的长度进行比较,但我认为这不会。

let prev = {},
  curr = {};
let flag = false;
let circulo;

function init() {
  canvas = document.getElementById("can");
  ctx = canvas.getContext("2d");
  w = canvas.width = 400;
  h = canvas.height = 400;

  var svgPathCirculo = "M125,200a75,75 0 1,0 150,0a75,75 0 1,0 -150,0";
  circulo = new Path2D(svgPathCirculo);

  ctx.lineWidth =10;
  ctx.setLineDash([5, 15]);
  ctx.stroke(circulo);

  canvas.addEventListener("mousemove", move, false);
  canvas.addEventListener("mousedown", down, false);
  canvas.addEventListener("mouseup", up, false);
  canvas.addEventListener("mouseout", up, false);
}

function draw(prev, curr, trazado) {
  
  ctx.setLineDash([]); //unset linedash
  ctx.lineCap = "round";
  ctx.strokeStyle = "gold"
  ctx.lineWidth =5;
  if (
    ctx.isPointInStroke(trazado, curr.x, curr.y) &&
    ctx.isPointInStroke(trazado, prev.x, prev.y)
  ) {
    ctx.beginPath();
    ctx.moveTo(prev.x, prev.y);
    ctx.lineTo(curr.x, curr.y);
    ctx.stroke();
  }
}

function down(e) {
  prev = oMousePos(canvas, e);
  curr = oMousePos(canvas, e);

  flag = true;
  
}

function up(e) {
  flag = false;
}

function move(e) {
  if (flag) {
    curr = oMousePos(canvas, e);
    draw(prev, curr, circulo);
    prev = { x: curr.x, y: curr.y };
  }
}

function oMousePos(canvas, evt) {
  var ClientRect = canvas.getBoundingClientRect();
  return {
    //objeto
    x: Math.round(evt.clientX - ClientRect.left),
    y: Math.round(evt.clientY - ClientRect.top)
  };
}

init();
canvas{border:1px solid}
<canvas id="can"></canvas>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-22
    • 1970-01-01
    • 1970-01-01
    • 2014-05-03
    • 1970-01-01
    • 2011-02-14
    • 2023-01-25
    • 1970-01-01
    相关资源
    最近更新 更多