arbor.js пользовательские формы каждого узла - PullRequest
1 голос
/ 23 февраля 2012

следующий код рисует изображение яйца на холсте html5

function init() {

  var canvas = document.getElementById("canvas");
  var ctx = canvas.getContext("2d");

  draw(ctx);
}

function draw(ctx) {

  // layer1/Path
  ctx.save();
  ctx.beginPath();
  ctx.moveTo(100.0, 90.0);
  ctx.bezierCurveTo(100.0, 95.5, 95.5, 100.0, 90.0, 100.0);
  ctx.lineTo(10.0, 100.0);
  ctx.bezierCurveTo(4.5, 100.0, 0.0, 95.5, 0.0, 90.0);
  ctx.lineTo(0.0, 10.0);
  ctx.bezierCurveTo(0.0, 4.5, 4.5, 0.0, 10.0, 0.0);
  ctx.lineTo(90.0, 0.0);
  ctx.bezierCurveTo(95.5, 0.0, 100.0, 4.5, 100.0, 10.0);
  ctx.lineTo(100.0, 90.0);
  ctx.closePath();
  ctx.fillStyle = "rgb(229, 229, 229)";
  ctx.fill();

  // layer1/Path
  ctx.beginPath();
  ctx.moveTo(10.0, 28.0);
  ctx.bezierCurveTo(10.0, 37.9, 18.1, 46.0, 28.0, 46.0);
  ctx.bezierCurveTo(37.9, 46.0, 46.0, 37.9, 46.0, 28.0);
  ctx.bezierCurveTo(46.0, 18.1, 37.9, 10.0, 28.0, 10.0);
  ctx.bezierCurveTo(18.1, 10.0, 10.0, 18.1, 10.0, 28.0);
  ctx.closePath();
  ctx.fillStyle = "rgb(255, 191, 30)";
  ctx.fill();
  ctx.restore();
}
<body onload="init()">
  <canvas id="canvas" width="100" height="100"></canvas>
</body>

Я пытаюсь получить arbor.js, чтобы показать яйцо как узел. Я также буду показывать другие иллюстрации, такие как бекон, хлеб для интерактивного меню ресторана. Предполагается, что в каждом узле, я верю? Но не совсем уверен, как.

particleSystem.eachNode(function(node, pt){
          // node: {mass:#, p:{x,y}, name:"", data:{}}
          // pt:   {x:#, y:#}  node position in screen coords


          // determine the box size and round off the coords if we'll be 
          // drawing a text label (awful alignment jitter otherwise...)
          var w = ctx.measureText(node.data.label||"").width + 6
          var label = node.data.label
          if (!(label||"").match(/^[ \t]*$/)){
            pt.x = Math.floor(pt.x)
            pt.y = Math.floor(pt.y)
          }else{
            label = null
          }

          // clear any edges below the text label
          // ctx.fillStyle = 'rgba(255,255,255,.6)'
          // ctx.fillRect(pt.x-w/2, pt.y-7, w,14)


          ctx.clearRect(pt.x-w/2, pt.y-7, w,14)



          // draw the text
          if (label){
            ctx.font = "bold 11px Arial"
            ctx.textAlign = "center"

            // if (node.data.region) ctx.fillStyle = palette[node.data.region]
            // else ctx.fillStyle = "#888888"
            ctx.fillStyle = "#888888"

            // ctx.fillText(label||"", pt.x, pt.y+4)
            ctx.fillText(label||"", pt.x, pt.y+4)
          }
        })          
      },

      resize:function(){
        var w = $(window).width(),
            h = $(window).height();
        canvas.width = w; canvas.height = h // resize the canvas element to fill the screen
        particleSystem.screenSize(w,h) // inform the system so it can map coords for us
        that.redraw()
      },

        initMouseHandling:function(){
        // no-nonsense drag and drop (thanks springy.js)
        selected = null;
        nearest = null;
        var dragged = null;
        var oldmass = 1

        $(canvas).mousedown(function(e){
            var pos = $(this).offset();
            var p = {x:e.pageX-pos.left, y:e.pageY-pos.top}
            selected = nearest = dragged = particleSystem.nearest(p);

            if (selected.node !== null){
            // dragged.node.tempMass = 10000
            dragged.node.fixed = true
            }
            return false
        });

Большое спасибо заранее.

1 Ответ

4 голосов
/ 24 февраля 2012

Итак, откройте пример проекта, включенного в комплектацию 0,92. В main.js найдите анонимную функцию, прикрепленную к eachNode:

particleSystem.eachNode(function(node, pt){
  // node: {mass:#, p:{x,y}, name:"", data:{}}
  // pt:   {x:#, y:#}  node position in screen coords

  // draw a rectangle centered at pt
  var w = 20
  ctx.fillStyle = (node.data.alone) ? "orange" : "black"
  ctx.fillRect(pt.x-w/2, pt.y-w/2, w/2,w)
})

Это раздел, который нам нужно заменить на код вашего яйца. Проблема в том, что вы не можете просто оставить свою функцию рисования такой, какая она есть, потому что она использует абсолютные координаты, тогда как нам нужно использовать координаты относительно того, где визуализируется узел. По сути, вам нужно изменить каждый из вызовов в вашей функции draw(ctx), чтобы использовать pt.x и pt.y, как описано в примере.

Редактировать

Хорошо, готово. Замените весь блок следующим:

    particleSystem.eachNode(function(node, pt){
      // node: {mass:#, p:{x,y}, name:"", data:{}}
      // pt:   {x:#, y:#}  node position in screen coords

      // draw a rectangle centered at pt

            ctx.beginPath();
  ctx.moveTo(100.0 + pt.x, 90.0 + pt.y);
  ctx.bezierCurveTo(100.0 + pt.x, 95.5 + pt.y, 95.5 + pt.x, 100.0 + pt.y, 90.0 + pt.x, 100.0 + pt.y);
  ctx.lineTo(10.0 + pt.x, 100.0 + pt.y);
  ctx.bezierCurveTo(4.5 + pt.x, 100.0 + pt.y, 0.0 + pt.x, 95.5 + pt.y, 0.0 + pt.x, 90.0 + pt.y);
  ctx.lineTo(0.0 + pt.x, 10.0 + pt.y);
  ctx.bezierCurveTo(0.0 + pt.x, 4.5 + pt.y, 4.5 + pt.x, 0.0 + pt.y, 10.0 + pt.x, 0.0 + pt.y);
  ctx.lineTo(90.0 + pt.x, 0.0 + pt.y);
  ctx.bezierCurveTo(95.5 + pt.x, 0.0 + pt.y, 100.0 + pt.x, 4.5 + pt.y, 100.0 + pt.x, 10.0 + pt.y);
  ctx.lineTo(100.0 + pt.x, 90.0 + pt.y);
  ctx.closePath();
  ctx.fillStyle = "rgb(229, 229, 229)";
  ctx.fill();

  // layer1/Path
  ctx.beginPath();
  ctx.moveTo(10.0 + pt.x, 28.0 + pt.y);
  ctx.bezierCurveTo(10.0 + pt.x, 37.9 + pt.y, 18.1 + pt.x, 46.0 + pt.y, 28.0 + pt.x, 46.0 + pt.y);
  ctx.bezierCurveTo(37.9 + pt.x, 46.0 + pt.y, 46.0 + pt.x, 37.9 + pt.y, 46.0 + pt.x, 28.0 + pt.y);
  ctx.bezierCurveTo(46.0 + pt.x, 18.1 + pt.y, 37.9 + pt.x, 10.0 + pt.y, 28.0 + pt.x, 10.0 + pt.y);
  ctx.bezierCurveTo(18.1 + pt.x, 10.0 + pt.y, 10.0 + pt.x, 18.1 + pt.y, 10.0 + pt.x, 28.0 + pt.y);
  ctx.closePath();
  ctx.fillStyle = "rgb(255, 191, 30)";
  ctx.fill();
    })

enter image description here

Они не центрированы, как вы можете видеть, но, надеюсь, это дает достаточно идеала о том, как продолжать. :)

...