【问题标题】:Drawing guitar chords dynamically动态绘制吉他和弦
【发布时间】:2019-03-01 20:57:18
【问题描述】:

所以我的目标是使用 json 文件绘制这样的吉他和弦,我应该创建的和弦数量是 924,所以我无法手动完成。

我拥有的是一个逗号分隔的数字数组(查看位置)我绝对没有使用指法(那是你应该使用的手指,基本上它是圆圈顶部的数字)

[
  {
    "id": "404",
    "name": "Cb",
    "intervals": "",
    "positions": [
      {
        "id": "1226",
        "position": "x,2,4,4,4,2",
        "fingerings": "13331;12341",
        "picture": "",
        "chord_id": "404",
        "instrument_id": "1"
      },
      {
        "id": "1231",
        "position": "7,9,9,8,7,7",
        "fingerings": "134211",
        "picture": "",
        "chord_id": "404",
        "instrument_id": "1"
      },
      {
        "id": "1251",
        "position": "7,6,4,4,4,7",
        "fingerings": "321114",
        "picture": "",
        "chord_id": "404",
        "instrument_id": "1"
      },

      ...

这很有挑战性,因为每个和弦都有几个位置,其中一些在 5 品或更多品上,所以我应该指出我们正在画哪个品格,而不是每次都画整把吉他。

第二个问题是我不知道我应该从哪里开始以及如何正确处理它,我很想在 React 或 Python 中实现所有内容,然后生成一堆 imgs 并在我的应用程序中使用它们,这就是我很舒服。我也在考虑 js 和 css,但我真的要如何编写代码,根据数字在特定位置放置一个圆圈。

我不是在寻找代码,只是一些可以开始研究的链接,现在我有点卡住了,如果您需要更多信息,请告诉我。

【问题讨论】:

标签: javascript python reactjs svg drawing


【解决方案1】:

这可能不是您期望的答案,因为我对吉他和吉他和弦一无所知。请看一下。

const SVG_NS = 'http://www.w3.org/2000/svg';
let json = [
  {
    "id": "404",
    "name": "Cb",
    "intervals": "",
    "positions": [
      {
        "id": "1226",
        "position": "x,2,4,4,4,2",
        "fingerings": "13331;12341",
        "picture": "",
        "chord_id": "404",
        "instrument_id": "1"
      },
      {
        "id": "1231",
        "position": "7,9,9,8,7,7",
        "fingerings": "134211",
        "picture": "",
        "chord_id": "404",
        "instrument_id": "1"
      },
      {
        "id": "1251",
        "position": "7,6,4,4,4,7",
        "fingerings": "321114",
        "picture": "",
        "chord_id": "404",
        "instrument_id": "1"
      }
      ]
   }
]

for(let j = 0; j < json[0].positions.length; j++){
let position = json[0].positions[j].position.replace("x","").split(",");
let min = Math.min.apply(null, position);
let displacement = min < 1 ? 1 : min;
let svg = drawSVGElement("svg", {viewBox:"0 0 70 60"}, wrap);
drawGrid();

for(let i = 0; i < position.length; i++ ){
if(parseInt(position[i]) > 0){

let cp = {// circle position
  x : 10 + parseInt(i) * 10,
  y : 15 + (position[i] - displacement)*10
}
drawSVGElement("circle",{cx:cp.x,cy:cp.y,r:4}, svg)
}
}




function drawGrid(){
  let d = "";
  for(let i = 1; i < 6; i++){
    d+=`M10,${i*10}H60`
  } 
  for(let i = 1; i < 7; i++){
    d+=`M${i*10},10V50`
  }
  let path = drawSVGElement("path",{"d": d}, svg);
}

function drawSVGElement(tag, o, parent) {
  var svgElement = document.createElementNS(SVG_NS, tag);
  for (let name in o) {
    if (o.hasOwnProperty(name)) {
      svgElement.setAttributeNS(null, name, o[name]);
    }
  }
  parent.appendChild(svgElement);
  return svgElement;
}

}
svg{border:1px solid; max-height:100vh;}
path{fill:none;stroke:red;stroke-linecap: round}
&lt;div id="wrap"&gt;&lt;/div&gt;

【讨论】:

  • 见鬼!非常感谢,我需要时间来完成这一切
【解决方案2】:

我会使用 Python 以及 Pyx 和/或 Pillow。

您可以从基本的网格图像开始,知道网格中每个正方形的大小可以很容易地迭代并在特定点放置圆圈/其他标记,然后将图像的更新版本保存到新的位置。

为了放置标记,请分别设置宽度和高度的常量,然后乘以每条线的位置变量(或类似的东西)。

JavaScript 画布也可以使用 .toDataUrl() 保存到图像,但我发现 Python 的性能更好。

【讨论】:

    猜你喜欢
    • 2011-07-24
    • 2011-06-22
    • 2010-11-05
    • 2012-08-28
    • 2016-05-07
    • 2018-10-10
    • 1970-01-01
    • 2017-08-07
    相关资源
    最近更新 更多