加载stickman从json不持有线坐标旋转逻辑 [英] loading stickman from json does not persist line coordinate rotation logic

查看:137
本文介绍了加载stickman从json不持有线坐标旋转逻辑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

加载完stickman.tojson后,圆和线旋转逻辑就消失了。

After loading stickman.tojson, the circles and line rotation logic is gone.

我能够复制stickman逻辑来添加线到对象,旋转和跟随对象,因为我移动它。我使用canvas.toJSON保存Json和所有这些工作正常。我可以加载json与canvas.loadFromJSON(json),它加载正常。

I was able to duplicate the stickman logic to add lines to objects and the line will rotate and follow the object as I move it. I used canvas.toJSON to save the Json and all of this works fine. I can load the Json with canvas.loadFromJSON(json) and it loads fine.

问题是我加载它后,当我移动圆,线不跟随并旋转。我尝试搜索属性以包含在toJSON()中,但我找不到任何东西。

The issue is after I load it, when I move the circles, the line does not follow and rotate. I tried searching for properties to include in the toJSON() but I was not able to find anything.

http://fabricjs.com/stickman/

这里是一个jsfiddle示例。

Here is a jsfiddle sample.

    var canvas = this.__canvas = new fabric.Canvas('c', { selection: false });
  fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';

saveNow = (function(){
    var jsonSave = JSON.stringify(canvas.toJSON())
   // alert(jsonSave);
    sessionStorage.canvase = jsonSave;     
});

loadNow = (function(){
    var jsonLoad = sessionStorage.canvase;
   // alert(jsonLoad);
    canvas.loadFromJSON(jsonLoad, canvas.renderAll.bind(canvas));
});

(function() {


  function makeCircle(left, top, line1, line2, line3, line4) {
    var c = new fabric.Circle({
      left: left,
      top: top,
      strokeWidth: 5,
      radius: 12,
      fill: '#fff',
      stroke: '#666'
    });
    c.hasControls = c.hasBorders = false;

    c.line1 = line1;
    c.line2 = line2;
    c.line3 = line3;
    c.line4 = line4;

    return c;
     }

    function makeLine(coords) {
    return new fabric.Line(coords, {
      fill: 'red',
      stroke: 'red',
      strokeWidth: 5,
      selectable: false
    });
  }

  var line = makeLine([ 250, 125, 250, 175 ]),
      line2 = makeLine([ 250, 175, 250, 250 ]),
      line3 = makeLine([ 250, 250, 300, 350]),
      line4 = makeLine([ 250, 250, 200, 350]),
      line5 = makeLine([ 250, 175, 175, 225 ]),
      line6 = makeLine([ 250, 175, 325, 225 ]);

  canvas.add(line, line2, line3, line4, line5, line6);

  canvas.add(
    makeCircle(line.get('x1'), line.get('y1'), null, line),
    makeCircle(line.get('x2'), line.get('y2'), line, line2, line5, line6),
    makeCircle(line2.get('x2'), line2.get('y2'), line2, line3, line4),
    makeCircle(line3.get('x2'), line3.get('y2'), line3),
    makeCircle(line4.get('x2'), line4.get('y2'), line4),
    makeCircle(line5.get('x2'), line5.get('y2'), line5),
    makeCircle(line6.get('x2'), line6.get('y2'), line6)
  );

  canvas.on('object:moving', function(e) {
    var p = e.target;
    p.line1 && p.line1.set({ 'x2': p.left, 'y2': p.top });
    p.line2 && p.line2.set({ 'x1': p.left, 'y1': p.top });
    p.line3 && p.line3.set({ 'x1': p.left, 'y1': p.top });
    p.line4 && p.line4.set({ 'x1': p.left, 'y1': p.top });
    canvas.renderAll();
  });
})();

http://jsfiddle.net/pec86/28/

重现步骤:
1.移动圆形对象。
2.单击保存按钮。
3.移动圆形对象。
4.单击加载按钮。
5.移动圆形对象。

Steps to reproduce: 1. Move the circles objects around. 2. Click on the Save button. 3. Move the circles objects around. 4. Click on the Load button. 5. Move the circles objects around. This will now reveal what I am trying to fix/persists.

提前感谢。

推荐答案

你所面对的问题是 canvas.toJSON()将保存所有布料的对象,如在画布中绘制,但不会保存

The problem you're facing is that canvas.toJSON() will save all the fabric's objects, as drawn in the canvas but won't save your own objects, and so it will loose the references such as the links between circles and lines.

我没有fabric.js专家,所以可能有一个更简单的解决方案,但是我重写了你的代码,以便它可以完成你试图做的。

我使用一个数组来存储所有的行,现在 saveNow()函数只保存那些线的坐标。
我还必须重写绘图函数,现在放置到 init()函数中。

I am no fabric.js specialist so there might be a simpler solution, however I rewrote your code so that it can accomplish what you tried to do.
I used an array to store all our lines and now the saveNow()function only saves the coordinates of those lines. I also had to rewrite the drawing function, now placed into an init() function.

另外,注意它很脏:

Also, note that it's kind of dirty :

var canvas = this.__canvas = new fabric.Canvas('c', {
    selection: false
});
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';

(function () {
    //Some other objects
    canvas.add(
        new fabric.Rect({ top: 100, left: 100, width: 50, height: 50, fill: '#f55' }),
        new fabric.Circle({ top: 140, left: 230, radius: 75, fill: 'green' }),
        new fabric.Triangle({ top: 300, left: 210, width: 100, height: 100, fill: 'blue' })
      );
    var lines,
    links = [[0,1,4,5], [1,2,3], [2], [3], [4], [5]];

    var saveNow = function () {
        //save our stickMan
        var coords = [],l;
        for (var i = 0; l = lines[i]; i++) {
            coords.push([l.x1, l.y1, l.x2, l.y2]);
        }
        sessionStorage.stickman = JSON.stringify(coords);
        //Hide our stickman
        lines.forEach(function(l){canvas.remove(l)});
        circles.forEach(function(c){canvas.remove(c)});
        //save the rest of the canvas
        sessionStorage.canvase = JSON.stringify(canvas.toJSON());
        //unhide stickman
        lines.forEach(function(l){canvas.add(l)});
        circles.forEach(function(c){canvas.add(c)});
        canvas.renderAll();
    };

    var loadNow = function () {
        var coords = JSON.parse(sessionStorage.stickman);
        canvas.clear();
        var jsonLoad = sessionStorage.canvase;
        canvas.loadFromJSON(jsonLoad, function(){canvas.renderAll.bind(canvas); init(coords);});
    };
    var btns = document.querySelectorAll('button');
    btns[0].addEventListener('click', saveNow, false);
    btns[1].addEventListener('click', loadNow, false);
    var circles;
    function makeCircle(left, top, l) {
        var c = new fabric.Circle({
            left: left,
            top: top,
            strokeWidth: 5,
            radius: 12,
            fill: '#fff',
            stroke: '#666'
        });
        c.hasControls = c.hasBorders = false;
        for (var i = 0; i < links.length; i++) {
            c["line" + i] = lines[l[i]];
        }
        circles.push(c);
        return c;
    }

    function makeLine(coords) {
        return new fabric.Line(coords, {
            fill: 'red',
            stroke: 'red',
            strokeWidth: 5,
            selectable: false
        });
    }

    function init(coords) {
        coords = coords || [
            [250, 125, 250, 175],
            [250, 175, 250, 250],
            [250, 250, 300, 350],
            [250, 250, 200, 350],
            [250, 175, 175, 225],
            [250, 175, 325, 225]
        ];
        lines = circles = [];
        var i;
        for (i = 0; i < coords.length; i++) {
            lines.push(makeLine(coords[i]));
        }
        for (i = 0; i < lines.length; i++) {
            canvas.add(lines[i]);
        }
        for (i = 0; i < lines.length; i++) {
            if (i === 0) {
                canvas.add(makeCircle(lines[i].get('x1'), lines[i].get('y1'), [null, 0]));
                canvas.add(makeCircle(lines[i].get('x2'), lines[i].get('y2'), links[i]));
            } else canvas.add(makeCircle(lines[i].get('x2'), lines[i].get('y2'), links[i]));
        }
    }
    canvas.on('object:moving', function (e) {
        var p = e.target;
        p.line0 && p.line0.set({'x2': p.left,'y2': p.top});
        p.line1 && p.line1.set({'x1': p.left,'y1': p.top});
        p.line2 && p.line2.set({'x1': p.left,'y1': p.top});
        p.line3 && p.line3.set({'x1': p.left,'y1': p.top});
        canvas.renderAll();
    });

    init();
})();



//stackoverflow.com/a/11276133/3702797\">此答案

这篇关于加载stickman从json不持有线坐标旋转逻辑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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