Javascript-仅需要从SVG路径的笔触获取x和y坐标?

时间:2019-03-10 17:39:13

标签: javascript html svg coordinates mouse

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

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

import random
import telebot
from telebot.types import Message

TOKEN = ''

bot = telebot.TeleBot(TOKEN)

@bot.message_handler(commands=['start'])
def command_handler(message: Message):
    bot.reply_to(message, 'example_text1\n'
                          random_number_here\n
                          'example_text2\n')

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

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笔触路径的每个x和y坐标。

示例:Example of what I mean

1 个答案:

答案 0 :(得分:1)

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

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

ctx.isPointInStroke(the_path, x, y)

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

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

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>