将 svg 路径 d 拆分为对象数组 [英] Split a svg path d to array of objects

查看:33
本文介绍了将 svg 路径 d 拆分为对象数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法将 d 路径字符串拆分为一个对象数组?

Is there a way to split the d path string to an array of objects?

例如:

const d = `M 0 0 L 0 10 C 0 10 20 30 20 20 Z`
const result = fromPathToArray(d)

// const result = [
//   { type: 'M', x: 0, y: 0 },
//   { type: 'L', x: 0, y: 10 },
//   { type: 'C', x1: 0, y1: 10, x2: 20, y2: 30, x3: 20, y3: 20 },
//   { type: 'Z' },
// ]

这是我的起始代码:

const PATH_COMMANDS = {
  M: ["x", "y"],
  m: ["dx", "dy"],
  H: ["x"],
  h: ["dx"],
  V: ["y"],
  v: ["dy"],
  L: ["x", "y"],
  l: ["dx", "dy"],
  Z: [],
  C: ["x1", "y1", "x2", "y2", "x", "y"],
  c: ["dx1", "dy1", "dx2", "dy2", "dx", "dy"],
  S: ["x2", "y2", "x", "y"],
  s: ["dx2", "dy2", "dx", "dy"],
  Q: ["x1", "y1", "x", "y"],
  q: ["dx1", "dy1", "dx", "dy"],
  T: ["x", "y"],
  t: ["dx", "dy"],
  A: ["rx", "ry", "rotation", "large-arc", "sweep", "x", "y"],
  a: ["rx", "ry", "rotation", "large-arc", "sweep", "dx", "dy"]
};

export function splitPath(path) {
  const items = path.trim().split(/\s*,|\s+/);
  const segments = [];
  
  items.forEach((item, i) => {
    const type = isString(item) ? item : null
    // ...
  })

  return segments
}

老实说我不知道​​该怎么做..

Honeslty I don't know how to do..

推荐答案

对于您所描述的案例,这里有一个简单的例程.请注意,这种简单的解决方案只有在您知道输入遵循特定模式时才有用.如评论所示,一般情况更复杂.此外,您应该添加健全性检查以处理错误输入.

Here is a simple routine for a case like the one you describe. Please, be aware that such a simple solution is only useful if you know the input follows a certain pattern. As shown in the comments, the general case is more complex. Also, you should add sanity checks to handle faulty input.

const PATH_COMMANDS = {
  M: ["x", "y"],
  m: ["dx", "dy"],
  H: ["x"],
  h: ["dx"],
  V: ["y"],
  v: ["dy"],
  L: ["x", "y"],
  l: ["dx", "dy"],
  Z: [],
  C: ["x1", "y1", "x2", "y2", "x", "y"],
  c: ["dx1", "dy1", "dx2", "dy2", "dx", "dy"],
  S: ["x2", "y2", "x", "y"],
  s: ["dx2", "dy2", "dx", "dy"],
  Q: ["x1", "y1", "x", "y"],
  q: ["dx1", "dy1", "dx", "dy"],
  T: ["x", "y"],
  t: ["dx", "dy"],
  A: ["rx", "ry", "rotation", "large-arc", "sweep", "x", "y"],
  a: ["rx", "ry", "rotation", "large-arc", "sweep", "dx", "dy"]
};

function fromPathToArray(path) {
  const items = path.replace(/[\n\r]/g, '').
                replace(/-/g, ' -').
                replace(/(\d*\.)(\d+)(?=\.)/g, '$1$2 ').
                trim().
                split(/\s*,|\s+/);
  const segments = [];
  let currentCommand = '';
  let currentElement = {};
  while (items.length > 0){
    let it = items.shift();
    if (PATH_COMMANDS.hasOwnProperty(it)){
      currentCommand = it;
    }
    else{
      items.unshift(it);
    }
    currentElement = {type: currentCommand};
    PATH_COMMANDS[currentCommand].forEach((prop) => {
      it = items.shift();  // TODO sanity check
      currentElement[prop] = it;
    });
    if (currentCommand === 'M'){
      currentCommand = 'L';
    }
    else if (currentCommand === 'm'){
      currentCommand = 'l';
    }
    segments.push(currentElement);
  }
  return segments
}

const d = `M 0 0 10 10 L 0 10 C 0 10 
20 30 20 20 a 4.12.12 1 0 1 4.13-1 Z`;
const result = fromPathToArray(d);

console.log(result);

这篇关于将 svg 路径 d 拆分为对象数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆